@geenius/adapters 0.1.0 → 0.3.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.
Files changed (185) hide show
  1. package/README.md +79 -42
  2. package/package.json +23 -4
  3. package/packages/convex/README.md +1 -1
  4. package/packages/convex/dist/index.cjs +300 -0
  5. package/packages/convex/dist/index.cjs.map +1 -0
  6. package/packages/convex/dist/index.d.cts +231 -0
  7. package/packages/convex/dist/index.d.ts +231 -0
  8. package/packages/convex/dist/index.js +263 -0
  9. package/packages/convex/dist/index.js.map +1 -0
  10. package/packages/react/README.md +1 -1
  11. package/packages/react/dist/index.d.mts +106 -0
  12. package/packages/react/dist/index.d.ts +106 -0
  13. package/packages/react/dist/index.js +611 -0
  14. package/packages/react/dist/index.js.map +1 -0
  15. package/packages/react/dist/index.mjs +570 -0
  16. package/packages/react/dist/index.mjs.map +1 -0
  17. package/packages/react-css/README.md +1 -1
  18. package/packages/react-css/dist/index.cjs +515 -0
  19. package/packages/react-css/dist/index.cjs.map +1 -0
  20. package/packages/react-css/dist/index.d.cts +105 -0
  21. package/packages/react-css/dist/index.d.ts +105 -0
  22. package/packages/react-css/dist/index.js +467 -0
  23. package/packages/react-css/dist/index.js.map +1 -0
  24. package/packages/shared/README.md +1 -1
  25. package/packages/shared/dist/index.d.mts +625 -0
  26. package/packages/shared/dist/index.d.ts +625 -0
  27. package/packages/shared/dist/index.js +1567 -0
  28. package/packages/shared/dist/index.js.map +1 -0
  29. package/packages/shared/dist/index.mjs +1489 -0
  30. package/packages/shared/dist/index.mjs.map +1 -0
  31. package/packages/solidjs/README.md +1 -1
  32. package/packages/solidjs/dist/index.d.mts +97 -0
  33. package/packages/solidjs/dist/index.d.ts +97 -0
  34. package/packages/solidjs/dist/index.js +250 -0
  35. package/packages/solidjs/dist/index.js.map +1 -0
  36. package/packages/solidjs/dist/index.mjs +202 -0
  37. package/packages/solidjs/dist/index.mjs.map +1 -0
  38. package/packages/solidjs-css/README.md +1 -1
  39. package/packages/solidjs-css/dist/index.cjs +343 -0
  40. package/packages/solidjs-css/dist/index.cjs.map +1 -0
  41. package/packages/solidjs-css/dist/index.d.cts +67 -0
  42. package/packages/solidjs-css/dist/index.d.ts +67 -0
  43. package/packages/solidjs-css/dist/index.js +326 -0
  44. package/packages/solidjs-css/dist/index.js.map +1 -0
  45. package/.changeset/config.json +0 -11
  46. package/.github/CODEOWNERS +0 -1
  47. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -16
  48. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -11
  49. package/.github/PULL_REQUEST_TEMPLATE.md +0 -10
  50. package/.github/dependabot.yml +0 -11
  51. package/.github/workflows/ci.yml +0 -23
  52. package/.github/workflows/release.yml +0 -29
  53. package/.nvmrc +0 -1
  54. package/.project/ACCOUNT.yaml +0 -4
  55. package/.project/IDEAS.yaml +0 -7
  56. package/.project/PROJECT.yaml +0 -11
  57. package/.project/ROADMAP.yaml +0 -15
  58. package/CODE_OF_CONDUCT.md +0 -16
  59. package/CONTRIBUTING.md +0 -26
  60. package/SECURITY.md +0 -15
  61. package/SUPPORT.md +0 -8
  62. package/packages/convex/package.json +0 -42
  63. package/packages/convex/src/adapter.ts +0 -39
  64. package/packages/convex/src/index.ts +0 -19
  65. package/packages/convex/src/mutations.ts +0 -142
  66. package/packages/convex/src/queries.ts +0 -106
  67. package/packages/convex/src/schema.ts +0 -54
  68. package/packages/convex/src/types.ts +0 -20
  69. package/packages/convex/tsconfig.json +0 -11
  70. package/packages/convex/tsup.config.ts +0 -10
  71. package/packages/react/package.json +0 -45
  72. package/packages/react/src/components/AdapterCard.tsx +0 -49
  73. package/packages/react/src/components/AdapterConfigForm.tsx +0 -118
  74. package/packages/react/src/components/AdapterList.tsx +0 -84
  75. package/packages/react/src/components/AdapterStatusBadge.tsx +0 -30
  76. package/packages/react/src/components/index.ts +0 -4
  77. package/packages/react/src/hooks/index.ts +0 -75
  78. package/packages/react/src/index.tsx +0 -44
  79. package/packages/react/src/pages/AdapterDetailPage.tsx +0 -133
  80. package/packages/react/src/pages/AdaptersPage.tsx +0 -111
  81. package/packages/react/src/pages/index.ts +0 -2
  82. package/packages/react/src/provider/AdapterProvider.tsx +0 -115
  83. package/packages/react/src/provider/index.ts +0 -2
  84. package/packages/react/tsconfig.json +0 -18
  85. package/packages/react/tsup.config.ts +0 -10
  86. package/packages/react-css/package.json +0 -44
  87. package/packages/react-css/src/adapters.css +0 -1576
  88. package/packages/react-css/src/components/AdapterCard.tsx +0 -34
  89. package/packages/react-css/src/components/AdapterConfigForm.tsx +0 -63
  90. package/packages/react-css/src/components/AdapterList.tsx +0 -40
  91. package/packages/react-css/src/components/AdapterStatusBadge.tsx +0 -21
  92. package/packages/react-css/src/components/index.ts +0 -4
  93. package/packages/react-css/src/hooks/index.ts +0 -75
  94. package/packages/react-css/src/index.tsx +0 -25
  95. package/packages/react-css/src/pages/AdapterDetailPage.tsx +0 -133
  96. package/packages/react-css/src/pages/AdaptersPage.tsx +0 -111
  97. package/packages/react-css/src/pages/index.ts +0 -2
  98. package/packages/react-css/src/provider/AdapterProvider.tsx +0 -115
  99. package/packages/react-css/src/provider/index.ts +0 -2
  100. package/packages/react-css/src/styles.css +0 -494
  101. package/packages/react-css/tsconfig.json +0 -19
  102. package/packages/react-css/tsup.config.ts +0 -2
  103. package/packages/shared/package.json +0 -39
  104. package/packages/shared/src/__tests__/adapters.test.ts +0 -545
  105. package/packages/shared/src/admin/index.ts +0 -2
  106. package/packages/shared/src/admin/interface.ts +0 -34
  107. package/packages/shared/src/admin/localStorage.ts +0 -109
  108. package/packages/shared/src/ai/anthropic.ts +0 -123
  109. package/packages/shared/src/ai/cloudflare-gateway.ts +0 -130
  110. package/packages/shared/src/ai/gemini.ts +0 -181
  111. package/packages/shared/src/ai/index.ts +0 -14
  112. package/packages/shared/src/ai/interface.ts +0 -11
  113. package/packages/shared/src/ai/localStorage.ts +0 -78
  114. package/packages/shared/src/ai/ollama.ts +0 -143
  115. package/packages/shared/src/ai/openai.ts +0 -120
  116. package/packages/shared/src/ai/vercel-ai.ts +0 -101
  117. package/packages/shared/src/auth/better-auth.ts +0 -118
  118. package/packages/shared/src/auth/clerk.ts +0 -151
  119. package/packages/shared/src/auth/convex-auth.ts +0 -125
  120. package/packages/shared/src/auth/index.ts +0 -10
  121. package/packages/shared/src/auth/interface.ts +0 -17
  122. package/packages/shared/src/auth/localStorage.ts +0 -125
  123. package/packages/shared/src/auth/supabase-auth.ts +0 -136
  124. package/packages/shared/src/config.ts +0 -57
  125. package/packages/shared/src/constants.ts +0 -122
  126. package/packages/shared/src/db/convex.ts +0 -146
  127. package/packages/shared/src/db/index.ts +0 -10
  128. package/packages/shared/src/db/interface.ts +0 -13
  129. package/packages/shared/src/db/localStorage.ts +0 -91
  130. package/packages/shared/src/db/mongodb.ts +0 -125
  131. package/packages/shared/src/db/neon.ts +0 -171
  132. package/packages/shared/src/db/supabase.ts +0 -158
  133. package/packages/shared/src/index.ts +0 -117
  134. package/packages/shared/src/payments/index.ts +0 -4
  135. package/packages/shared/src/payments/interface.ts +0 -11
  136. package/packages/shared/src/payments/localStorage.ts +0 -81
  137. package/packages/shared/src/payments/stripe.ts +0 -177
  138. package/packages/shared/src/storage/convex.ts +0 -113
  139. package/packages/shared/src/storage/index.ts +0 -14
  140. package/packages/shared/src/storage/interface.ts +0 -11
  141. package/packages/shared/src/storage/localStorage.ts +0 -95
  142. package/packages/shared/src/storage/minio.ts +0 -47
  143. package/packages/shared/src/storage/r2.ts +0 -123
  144. package/packages/shared/src/storage/s3.ts +0 -128
  145. package/packages/shared/src/storage/supabase-storage.ts +0 -116
  146. package/packages/shared/src/storage/uploadthing.ts +0 -126
  147. package/packages/shared/src/styles/adapters.css +0 -494
  148. package/packages/shared/src/tier-gate.ts +0 -119
  149. package/packages/shared/src/types.ts +0 -162
  150. package/packages/shared/tsconfig.json +0 -18
  151. package/packages/shared/tsup.config.ts +0 -9
  152. package/packages/shared/vitest.config.ts +0 -14
  153. package/packages/solidjs/package.json +0 -44
  154. package/packages/solidjs/src/components/AdapterCard.tsx +0 -24
  155. package/packages/solidjs/src/components/AdapterConfigForm.tsx +0 -54
  156. package/packages/solidjs/src/components/AdapterList.tsx +0 -28
  157. package/packages/solidjs/src/components/AdapterStatusBadge.tsx +0 -20
  158. package/packages/solidjs/src/components/index.ts +0 -4
  159. package/packages/solidjs/src/index.tsx +0 -17
  160. package/packages/solidjs/src/pages/AdapterDetailPage.tsx +0 -38
  161. package/packages/solidjs/src/pages/AdaptersPage.tsx +0 -39
  162. package/packages/solidjs/src/pages/index.ts +0 -2
  163. package/packages/solidjs/src/primitives/index.ts +0 -78
  164. package/packages/solidjs/src/provider/AdapterProvider.tsx +0 -62
  165. package/packages/solidjs/src/provider/index.ts +0 -2
  166. package/packages/solidjs/tsconfig.json +0 -20
  167. package/packages/solidjs/tsup.config.ts +0 -10
  168. package/packages/solidjs-css/package.json +0 -43
  169. package/packages/solidjs-css/src/adapters.css +0 -1576
  170. package/packages/solidjs-css/src/components/AdapterCard.tsx +0 -43
  171. package/packages/solidjs-css/src/components/AdapterConfigForm.tsx +0 -119
  172. package/packages/solidjs-css/src/components/AdapterList.tsx +0 -68
  173. package/packages/solidjs-css/src/components/AdapterStatusBadge.tsx +0 -24
  174. package/packages/solidjs-css/src/components/index.ts +0 -8
  175. package/packages/solidjs-css/src/index.tsx +0 -30
  176. package/packages/solidjs-css/src/pages/AdapterDetailPage.tsx +0 -107
  177. package/packages/solidjs-css/src/pages/AdaptersPage.tsx +0 -94
  178. package/packages/solidjs-css/src/pages/index.ts +0 -4
  179. package/packages/solidjs-css/src/primitives/index.ts +0 -1
  180. package/packages/solidjs-css/src/provider/AdapterProvider.tsx +0 -61
  181. package/packages/solidjs-css/src/provider/index.ts +0 -2
  182. package/packages/solidjs-css/tsconfig.json +0 -20
  183. package/packages/solidjs-css/tsup.config.ts +0 -2
  184. package/pnpm-workspace.yaml +0 -2
  185. package/tsconfig.json +0 -17
@@ -0,0 +1,250 @@
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/index.tsx
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ ADAPTER_DOMAINS: () => import_adapters_shared7.ADAPTER_DOMAINS,
24
+ AdapterCard: () => AdapterCard,
25
+ AdapterConfigForm: () => AdapterConfigForm,
26
+ AdapterDetailPage: () => AdapterDetailPage,
27
+ AdapterList: () => AdapterList,
28
+ AdapterProvider: () => AdapterProvider,
29
+ AdapterStatusBadge: () => AdapterStatusBadge,
30
+ AdaptersPage: () => AdaptersPage,
31
+ DOMAIN_DESCRIPTIONS: () => import_adapters_shared7.DOMAIN_DESCRIPTIONS,
32
+ DOMAIN_ICONS: () => import_adapters_shared7.DOMAIN_ICONS,
33
+ DOMAIN_LABELS: () => import_adapters_shared7.DOMAIN_LABELS,
34
+ configureAdapters: () => import_adapters_shared7.configureAdapters,
35
+ createAdapterStatus: () => createAdapterStatus,
36
+ createAdapterStatuses: () => createAdapterStatuses,
37
+ createAdapters: () => createAdapters,
38
+ createAdmin: () => createAdmin,
39
+ createAi: () => createAi,
40
+ createAuth: () => createAuth,
41
+ createDb: () => createDb,
42
+ createIsAdapterReady: () => createIsAdapterReady,
43
+ createPayments: () => createPayments,
44
+ createStorage: () => createStorage,
45
+ getAdapterConfig: () => import_adapters_shared7.getAdapterConfig,
46
+ useAdapterContext: () => useAdapterContext
47
+ });
48
+ module.exports = __toCommonJS(index_exports);
49
+ var import_adapters_shared7 = require("@geenius/adapters-shared");
50
+
51
+ // src/provider/AdapterProvider.tsx
52
+ var import_solid_js = require("solid-js");
53
+ var import_store = require("solid-js/store");
54
+ var import_adapters_shared = require("@geenius/adapters-shared");
55
+ var AdapterContext = (0, import_solid_js.createContext)();
56
+ function AdapterProvider(props) {
57
+ const initStatuses = {};
58
+ for (const d of import_adapters_shared.ADAPTER_DOMAINS) {
59
+ const adapter = props.adapters[d];
60
+ initStatuses[d] = { domain: d, provider: adapter ? "configured" : "none", status: adapter ? "connected" : "disconnected", lastCheckedAt: Date.now() };
61
+ }
62
+ const [statuses] = (0, import_store.createStore)(initStatuses);
63
+ const getAdapter = (domain) => {
64
+ const adapter = props.adapters[domain];
65
+ if (!adapter) throw new Error(`${import_adapters_shared.DOMAIN_LABELS[domain] ?? domain} adapter not configured`);
66
+ return adapter;
67
+ };
68
+ const isReady = (domain) => !!props.adapters[domain] && statuses[domain]?.status === "connected";
69
+ const value = { adapters: props.adapters, statuses, getAdapter, isReady, isLoading: false };
70
+ return /* @__PURE__ */ React.createElement(AdapterContext.Provider, { value }, props.children);
71
+ }
72
+ function useAdapterContext() {
73
+ const ctx = (0, import_solid_js.useContext)(AdapterContext);
74
+ if (!ctx) throw new Error("useAdapterContext must be used within <AdapterProvider>");
75
+ return ctx;
76
+ }
77
+
78
+ // src/primitives/index.ts
79
+ var import_solid_js2 = require("solid-js");
80
+ function createDb() {
81
+ const ctx = useAdapterContext();
82
+ return ctx.getAdapter("db");
83
+ }
84
+ function createAuth() {
85
+ const ctx = useAdapterContext();
86
+ return ctx.getAdapter("auth");
87
+ }
88
+ function createPayments() {
89
+ const ctx = useAdapterContext();
90
+ return ctx.getAdapter("payments");
91
+ }
92
+ function createAi() {
93
+ const ctx = useAdapterContext();
94
+ return ctx.getAdapter("ai");
95
+ }
96
+ function createStorage() {
97
+ const ctx = useAdapterContext();
98
+ return ctx.getAdapter("storage");
99
+ }
100
+ function createAdmin() {
101
+ const ctx = useAdapterContext();
102
+ return ctx.getAdapter("admin");
103
+ }
104
+ function createAdapterStatuses() {
105
+ const ctx = useAdapterContext();
106
+ return ctx.statuses;
107
+ }
108
+ function createAdapterStatus(domain) {
109
+ const ctx = useAdapterContext();
110
+ return (0, import_solid_js2.createMemo)(() => ctx.statuses[domain]);
111
+ }
112
+ function createIsAdapterReady(domain) {
113
+ const ctx = useAdapterContext();
114
+ return (0, import_solid_js2.createMemo)(() => ctx.isReady(domain));
115
+ }
116
+ function createAdapters() {
117
+ const ctx = useAdapterContext();
118
+ return {
119
+ db: ctx.adapters.db,
120
+ auth: ctx.adapters.auth,
121
+ payments: ctx.adapters.payments,
122
+ ai: ctx.adapters.ai,
123
+ storage: ctx.adapters.storage,
124
+ admin: ctx.adapters.admin,
125
+ statuses: ctx.statuses,
126
+ isLoading: ctx.isLoading,
127
+ isReady: ctx.isReady
128
+ };
129
+ }
130
+
131
+ // src/components/AdapterStatusBadge.tsx
132
+ var LABELS = { connected: "Connected", disconnected: "Disconnected", error: "Error", initializing: "Initializing" };
133
+ var STYLES = {
134
+ connected: { bg: "bg-emerald-500/10", text: "text-emerald-400", dot: "bg-emerald-400" },
135
+ disconnected: { bg: "bg-white/5", text: "text-white/40", dot: "bg-white/30" },
136
+ error: { bg: "bg-red-500/10", text: "text-red-400", dot: "bg-red-400" },
137
+ initializing: { bg: "bg-amber-500/10", text: "text-amber-400", dot: "bg-amber-400" }
138
+ };
139
+ function AdapterStatusBadge(props) {
140
+ const s = () => STYLES[props.status];
141
+ return /* @__PURE__ */ React.createElement("span", { class: `inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 ${s().bg} ${props.class ?? ""}` }, /* @__PURE__ */ React.createElement("span", { class: `h-1.5 w-1.5 rounded-full ${s().dot} ${props.status === "initializing" ? "animate-pulse" : ""}` }), props.showLabel !== false && /* @__PURE__ */ React.createElement("span", { class: `text-[0.625rem] font-semibold uppercase tracking-wider ${s().text}` }, LABELS[props.status]));
142
+ }
143
+
144
+ // src/components/AdapterCard.tsx
145
+ var import_solid_js3 = require("solid-js");
146
+ var import_adapters_shared2 = require("@geenius/adapters-shared");
147
+ function AdapterCard(props) {
148
+ return /* @__PURE__ */ React.createElement("button", { type: "button", onClick: props.onClick, class: `group flex w-full items-start gap-4 rounded-2xl border border-white/10 bg-white/[0.03] p-5 text-left backdrop-blur-sm transition-all hover:border-white/15 hover:bg-white/[0.05] ${props.class ?? ""}` }, /* @__PURE__ */ React.createElement("div", { class: "flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-xl bg-white/5 text-2xl transition-transform group-hover:scale-105" }, import_adapters_shared2.DOMAIN_ICONS[props.domain]), /* @__PURE__ */ React.createElement("div", { class: "min-w-0 flex-1" }, /* @__PURE__ */ React.createElement("div", { class: "flex items-center justify-between gap-2" }, /* @__PURE__ */ React.createElement("h3", { class: "truncate text-sm font-bold text-white/90" }, import_adapters_shared2.DOMAIN_LABELS[props.domain]), /* @__PURE__ */ React.createElement(AdapterStatusBadge, { status: props.status.status })), /* @__PURE__ */ React.createElement("p", { class: "mt-0.5 text-xs text-white/40 line-clamp-2" }, import_adapters_shared2.DOMAIN_DESCRIPTIONS[props.domain]), /* @__PURE__ */ React.createElement(import_solid_js3.Show, { when: props.status.provider && props.status.provider !== "none" }, /* @__PURE__ */ React.createElement("div", { class: "mt-2 flex items-center gap-2" }, /* @__PURE__ */ React.createElement("span", { class: "rounded-md bg-white/5 px-2 py-0.5 text-[0.625rem] font-semibold text-white/50" }, props.status.provider), /* @__PURE__ */ React.createElement(import_solid_js3.Show, { when: props.status.latency }, /* @__PURE__ */ React.createElement("span", { class: "text-[0.625rem] text-white/30" }, props.status.latency, "ms")))), /* @__PURE__ */ React.createElement(import_solid_js3.Show, { when: props.status.error }, /* @__PURE__ */ React.createElement("p", { class: "mt-1.5 truncate text-[0.625rem] text-red-400/80" }, props.status.error))));
149
+ }
150
+
151
+ // src/components/AdapterList.tsx
152
+ var import_solid_js4 = require("solid-js");
153
+ var import_adapters_shared3 = require("@geenius/adapters-shared");
154
+ function AdapterList(props) {
155
+ const ctx = createAdapters();
156
+ const [search, setSearch] = (0, import_solid_js4.createSignal)("");
157
+ const filtered = (0, import_solid_js4.createMemo)(() => {
158
+ let domains = [...import_adapters_shared3.ADAPTER_DOMAINS];
159
+ const q = search().toLowerCase();
160
+ if (q) domains = domains.filter((d) => import_adapters_shared3.DOMAIN_LABELS[d].toLowerCase().includes(q) || d.includes(q));
161
+ if (props.filterStatus) domains = domains.filter((d) => ctx.statuses[d]?.status === props.filterStatus);
162
+ return domains;
163
+ });
164
+ return /* @__PURE__ */ React.createElement("div", { class: props.class ?? "" }, /* @__PURE__ */ React.createElement("input", { type: "text", value: search(), onInput: (e) => setSearch(e.currentTarget.value), placeholder: "Search adapters...", class: "w-full rounded-xl border border-white/10 bg-white/[0.02] px-4 py-2.5 text-sm text-white/90 placeholder:text-white/20 focus:border-indigo-500/50 focus:outline-none mb-4" }), /* @__PURE__ */ React.createElement(import_solid_js4.Show, { when: filtered().length > 0, fallback: /* @__PURE__ */ React.createElement("div", { class: "rounded-xl border border-white/5 bg-white/[0.01] p-8 text-center" }, /* @__PURE__ */ React.createElement("p", { class: "text-sm text-white/40" }, "No adapters match")) }, /* @__PURE__ */ React.createElement("div", { class: "grid gap-3 sm:grid-cols-2" }, /* @__PURE__ */ React.createElement(import_solid_js4.For, { each: filtered() }, (d) => /* @__PURE__ */ React.createElement(AdapterCard, { domain: d, status: ctx.statuses[d], onClick: () => props.onSelect?.(d) })))));
165
+ }
166
+
167
+ // src/components/AdapterConfigForm.tsx
168
+ var import_solid_js5 = require("solid-js");
169
+ var import_adapters_shared4 = require("@geenius/adapters-shared");
170
+ function AdapterConfigForm(props) {
171
+ const providers = (0, import_adapters_shared4.getProvidersForDomain)(props.domain);
172
+ const [provider, setProvider] = (0, import_solid_js5.createSignal)(props.initialConfig?.provider ?? providers[0]?.id ?? "");
173
+ const [apiKey, setApiKey] = (0, import_solid_js5.createSignal)(props.initialConfig?.apiKey ?? "");
174
+ const [baseUrl, setBaseUrl] = (0, import_solid_js5.createSignal)(props.initialConfig?.baseUrl ?? "");
175
+ const [isSaving, setIsSaving] = (0, import_solid_js5.createSignal)(false);
176
+ const [error, setError] = (0, import_solid_js5.createSignal)(null);
177
+ const needsApiKey = () => !["localStorage", "noop"].includes(provider());
178
+ const needsBaseUrl = () => ["ollama", "minio", "neon", "supabase"].includes(provider());
179
+ const handleSubmit = async (e) => {
180
+ e.preventDefault();
181
+ setError(null);
182
+ if (!provider()) {
183
+ setError("Select a provider");
184
+ return;
185
+ }
186
+ setIsSaving(true);
187
+ try {
188
+ await props.onSave({ provider: provider(), apiKey: apiKey() || void 0, baseUrl: baseUrl() || void 0 });
189
+ } catch (e2) {
190
+ setError(e2 instanceof Error ? e2.message : "Failed");
191
+ } finally {
192
+ setIsSaving(false);
193
+ }
194
+ };
195
+ return /* @__PURE__ */ React.createElement("form", { onSubmit: handleSubmit, class: `space-y-5 rounded-2xl border border-white/10 bg-white/[0.03] p-6 backdrop-blur-sm ${props.class ?? ""}` }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h3", { class: "text-lg font-bold text-white/90" }, "Configure ", import_adapters_shared4.DOMAIN_LABELS[props.domain])), /* @__PURE__ */ React.createElement(import_solid_js5.Show, { when: error() }, /* @__PURE__ */ React.createElement("div", { class: "rounded-lg border border-red-500/20 bg-red-500/10 px-4 py-3 text-sm text-red-400" }, error())), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("span", { class: "mb-1.5 block text-xs font-semibold uppercase tracking-wider text-white/40" }, "Provider"), /* @__PURE__ */ React.createElement("div", { class: "grid gap-2 sm:grid-cols-2" }, /* @__PURE__ */ React.createElement(import_solid_js5.For, { each: providers }, (p) => /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => setProvider(p.id), class: `flex flex-col rounded-xl border p-3 text-left transition-all ${provider() === p.id ? "border-indigo-500/30 bg-indigo-500/10" : "border-white/10 bg-white/[0.02] hover:bg-white/[0.04]"}` }, /* @__PURE__ */ React.createElement("span", { class: "text-xs font-semibold text-white/80" }, p.name), /* @__PURE__ */ React.createElement("span", { class: "mt-0.5 text-[0.625rem] text-white/40" }, p.description), /* @__PURE__ */ React.createElement("span", { class: `mt-1 self-start rounded px-1.5 py-0.5 text-[0.5625rem] font-bold uppercase ${p.tier === "pronto" ? "bg-emerald-500/10 text-emerald-400" : "bg-purple-500/10 text-purple-400"}` }, p.tier))))), /* @__PURE__ */ React.createElement(import_solid_js5.Show, { when: needsApiKey() }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("label", { class: "mb-1.5 block text-xs font-semibold uppercase tracking-wider text-white/40" }, "API Key"), /* @__PURE__ */ React.createElement("input", { type: "password", value: apiKey(), onInput: (e) => setApiKey(e.currentTarget.value), class: "w-full rounded-xl border border-white/10 bg-white/[0.02] px-4 py-3 text-sm text-white/90 placeholder:text-white/20 focus:border-indigo-500/50 focus:outline-none", placeholder: "API key" }))), /* @__PURE__ */ React.createElement(import_solid_js5.Show, { when: needsBaseUrl() }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("label", { class: "mb-1.5 block text-xs font-semibold uppercase tracking-wider text-white/40" }, "Base URL"), /* @__PURE__ */ React.createElement("input", { type: "url", value: baseUrl(), onInput: (e) => setBaseUrl(e.currentTarget.value), class: "w-full rounded-xl border border-white/10 bg-white/[0.02] px-4 py-3 text-sm text-white/90 placeholder:text-white/20 focus:border-indigo-500/50 focus:outline-none", placeholder: "https://..." }))), /* @__PURE__ */ React.createElement("div", { class: "flex justify-end gap-3 pt-2" }, /* @__PURE__ */ React.createElement(import_solid_js5.Show, { when: props.onCancel }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: props.onCancel, class: "rounded-xl px-5 py-2.5 text-sm font-semibold text-white/50 hover:text-white/70" }, "Cancel")), /* @__PURE__ */ React.createElement("button", { type: "submit", disabled: isSaving() || !provider(), class: "rounded-xl bg-indigo-500 px-6 py-2.5 text-sm font-semibold text-white hover:bg-indigo-400 disabled:opacity-50" }, isSaving() ? "Saving\u2026" : "Save")));
196
+ }
197
+
198
+ // src/pages/AdaptersPage.tsx
199
+ var import_solid_js6 = require("solid-js");
200
+ var import_adapters_shared5 = require("@geenius/adapters-shared");
201
+ function AdaptersPage(props) {
202
+ const ctx = createAdapters();
203
+ const [selectedDomain, setSelectedDomain] = (0, import_solid_js6.createSignal)(null);
204
+ const [filterStatus, setFilterStatus] = (0, import_solid_js6.createSignal)();
205
+ const connected = () => import_adapters_shared5.ADAPTER_DOMAINS.filter((d) => ctx.statuses[d]?.status === "connected").length;
206
+ const errors = () => import_adapters_shared5.ADAPTER_DOMAINS.filter((d) => ctx.statuses[d]?.status === "error").length;
207
+ return /* @__PURE__ */ React.createElement("div", { class: `max-w-4xl mx-auto space-y-8 ${props.class ?? ""}` }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h1", { class: "text-2xl font-extrabold text-white/95 tracking-tight" }, "Adapters"), /* @__PURE__ */ React.createElement("p", { class: "mt-1 text-sm text-white/40" }, "Manage infrastructure adapters.")), /* @__PURE__ */ React.createElement("div", { class: "grid gap-3 sm:grid-cols-3" }, /* @__PURE__ */ React.createElement("div", { class: "rounded-2xl border border-white/10 bg-white/[0.03] p-4" }, /* @__PURE__ */ React.createElement("p", { class: "text-xs font-semibold uppercase text-white/30" }, "Total"), /* @__PURE__ */ React.createElement("p", { class: "mt-1 text-2xl font-extrabold text-white/90" }, import_adapters_shared5.ADAPTER_DOMAINS.length)), /* @__PURE__ */ React.createElement("div", { class: "rounded-2xl border border-emerald-500/10 bg-emerald-500/[0.03] p-4" }, /* @__PURE__ */ React.createElement("p", { class: "text-xs font-semibold uppercase text-emerald-400/60" }, "Connected"), /* @__PURE__ */ React.createElement("p", { class: "mt-1 text-2xl font-extrabold text-emerald-400" }, connected())), errors() > 0 && /* @__PURE__ */ React.createElement("div", { class: "rounded-2xl border border-red-500/10 bg-red-500/[0.03] p-4" }, /* @__PURE__ */ React.createElement("p", { class: "text-xs font-semibold uppercase text-red-400/60" }, "Errors"), /* @__PURE__ */ React.createElement("p", { class: "mt-1 text-2xl font-extrabold text-red-400" }, errors()))), /* @__PURE__ */ React.createElement("div", { class: "flex items-center gap-2" }, /* @__PURE__ */ React.createElement("button", { onClick: () => setFilterStatus(void 0), class: `rounded-lg px-3 py-1.5 text-xs font-semibold ${!filterStatus() ? "bg-white/10 text-white/80" : "text-white/30"}` }, "All"), /* @__PURE__ */ React.createElement(import_solid_js6.For, { each: [...import_adapters_shared5.ADAPTER_STATUSES] }, (s) => /* @__PURE__ */ React.createElement("button", { onClick: () => setFilterStatus(s), class: `flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-semibold ${filterStatus() === s ? "bg-white/10 text-white/80" : "text-white/30"}` }, /* @__PURE__ */ React.createElement(AdapterStatusBadge, { status: s, showLabel: false }), s))), /* @__PURE__ */ React.createElement(AdapterList, { onSelect: (d) => props.onNavigateDetail ? props.onNavigateDetail(d) : setSelectedDomain(d), filterStatus: filterStatus() }), selectedDomain() && /* @__PURE__ */ React.createElement("div", { class: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm", onClick: () => setSelectedDomain(null) }, /* @__PURE__ */ React.createElement("div", { class: "max-w-lg w-full mx-4", onClick: (e) => e.stopPropagation() }, /* @__PURE__ */ React.createElement(AdapterConfigForm, { domain: selectedDomain(), onSave: async () => {
208
+ setSelectedDomain(null);
209
+ }, onCancel: () => setSelectedDomain(null) }))));
210
+ }
211
+
212
+ // src/pages/AdapterDetailPage.tsx
213
+ var import_solid_js7 = require("solid-js");
214
+ var import_adapters_shared6 = require("@geenius/adapters-shared");
215
+ function AdapterDetailPage(props) {
216
+ const status = createAdapterStatus(props.domain);
217
+ const providers = (0, import_adapters_shared6.getProvidersForDomain)(props.domain);
218
+ const [isEditing, setIsEditing] = (0, import_solid_js7.createSignal)(false);
219
+ return /* @__PURE__ */ React.createElement("div", { class: `max-w-3xl mx-auto space-y-8 ${props.class ?? ""}` }, /* @__PURE__ */ React.createElement(import_solid_js7.Show, { when: props.onBack }, /* @__PURE__ */ React.createElement("button", { onClick: props.onBack, class: "text-sm text-white/30 hover:text-white/60" }, "\u2190 Back")), /* @__PURE__ */ React.createElement("div", { class: "flex items-start gap-5" }, /* @__PURE__ */ React.createElement("div", { class: "flex h-16 w-16 items-center justify-center rounded-2xl bg-white/5 text-3xl" }, import_adapters_shared6.DOMAIN_ICONS[props.domain]), /* @__PURE__ */ React.createElement("div", { class: "flex-1" }, /* @__PURE__ */ React.createElement("div", { class: "flex items-center gap-3" }, /* @__PURE__ */ React.createElement("h1", { class: "text-2xl font-extrabold text-white/95" }, import_adapters_shared6.DOMAIN_LABELS[props.domain]), /* @__PURE__ */ React.createElement(AdapterStatusBadge, { status: status().status })), /* @__PURE__ */ React.createElement("p", { class: "mt-1 text-sm text-white/40" }, import_adapters_shared6.DOMAIN_DESCRIPTIONS[props.domain]))), /* @__PURE__ */ React.createElement("div", { class: "rounded-2xl border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { class: "text-xs font-semibold uppercase text-white/30 mb-4" }, "Status"), /* @__PURE__ */ React.createElement("div", { class: "grid gap-4 sm:grid-cols-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { class: "text-[0.625rem] text-white/30 uppercase" }, "Provider"), /* @__PURE__ */ React.createElement("p", { class: "mt-0.5 text-sm font-semibold text-white/80" }, status().provider !== "none" ? status().provider : "\u2014")), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { class: "text-[0.625rem] text-white/30 uppercase" }, "Status"), /* @__PURE__ */ React.createElement(AdapterStatusBadge, { status: status().status })), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { class: "text-[0.625rem] text-white/30 uppercase" }, "Last Checked"), /* @__PURE__ */ React.createElement("p", { class: "mt-0.5 text-sm text-white/60" }, status().lastCheckedAt ? new Date(status().lastCheckedAt).toLocaleTimeString() : "\u2014")))), /* @__PURE__ */ React.createElement("div", { class: "rounded-2xl border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { class: "text-xs font-semibold uppercase text-white/30 mb-4" }, "Available Providers (", providers.length, ")"), /* @__PURE__ */ React.createElement("div", { class: "divide-y divide-white/5" }, /* @__PURE__ */ React.createElement(import_solid_js7.For, { each: providers }, (p) => /* @__PURE__ */ React.createElement("div", { class: "flex items-center justify-between py-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { class: "text-sm font-semibold text-white/80" }, p.name), /* @__PURE__ */ React.createElement("p", { class: "text-xs text-white/30" }, p.description)), /* @__PURE__ */ React.createElement("span", { class: `rounded px-2 py-0.5 text-[0.625rem] font-bold uppercase ${p.tier === "pronto" ? "bg-emerald-500/10 text-emerald-400" : "bg-blue-500/10 text-blue-400"}` }, p.tier))))), /* @__PURE__ */ React.createElement(import_solid_js7.Show, { when: isEditing(), fallback: /* @__PURE__ */ React.createElement("button", { onClick: () => setIsEditing(true), class: "w-full rounded-2xl border border-dashed border-white/10 bg-white/[0.01] p-6 text-center text-sm text-white/30 hover:border-white/20" }, "\u2699\uFE0F Configure") }, /* @__PURE__ */ React.createElement(AdapterConfigForm, { domain: props.domain, onSave: async () => {
220
+ setIsEditing(false);
221
+ }, onCancel: () => setIsEditing(false) })));
222
+ }
223
+ // Annotate the CommonJS export names for ESM import in node:
224
+ 0 && (module.exports = {
225
+ ADAPTER_DOMAINS,
226
+ AdapterCard,
227
+ AdapterConfigForm,
228
+ AdapterDetailPage,
229
+ AdapterList,
230
+ AdapterProvider,
231
+ AdapterStatusBadge,
232
+ AdaptersPage,
233
+ DOMAIN_DESCRIPTIONS,
234
+ DOMAIN_ICONS,
235
+ DOMAIN_LABELS,
236
+ configureAdapters,
237
+ createAdapterStatus,
238
+ createAdapterStatuses,
239
+ createAdapters,
240
+ createAdmin,
241
+ createAi,
242
+ createAuth,
243
+ createDb,
244
+ createIsAdapterReady,
245
+ createPayments,
246
+ createStorage,
247
+ getAdapterConfig,
248
+ useAdapterContext
249
+ });
250
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.tsx","../src/provider/AdapterProvider.tsx","../src/primitives/index.ts","../src/components/AdapterStatusBadge.tsx","../src/components/AdapterCard.tsx","../src/components/AdapterList.tsx","../src/components/AdapterConfigForm.tsx","../src/pages/AdaptersPage.tsx","../src/pages/AdapterDetailPage.tsx"],"sourcesContent":["// @geenius/adapters-solidjs — Barrel export\n\nexport type {\n AuthAdapter, OAuthProvider, DbAdapter, PaymentsAdapter, AiAdapter, FileStorageAdapter,\n AdminAdapter, AdapterDomain, AdapterConfig, AdapterStatusType, AdapterStatusInfo,\n} from '@geenius/adapters-shared'\n\nexport { ADAPTER_DOMAINS, DOMAIN_LABELS, DOMAIN_ICONS, DOMAIN_DESCRIPTIONS, configureAdapters, getAdapterConfig } from '@geenius/adapters-shared'\n\nexport { AdapterProvider, useAdapterContext } from './provider'\nexport type { AdapterProviderProps, AdapterSet, AdapterContextValue } from './provider'\n\nexport { createDb, createAuth, createPayments, createAi, createStorage, createAdmin, createAdapters, createAdapterStatuses, createAdapterStatus, createIsAdapterReady } from './primitives'\n\nexport { AdapterStatusBadge, AdapterCard, AdapterList, AdapterConfigForm } from './components'\n\nexport { AdaptersPage, AdapterDetailPage } from './pages'\n","// @geenius/adapters-solidjs — AdapterProvider\n\nimport { createContext, useContext } from 'solid-js'\nimport { createStore } from 'solid-js/store'\nimport type { JSX } from 'solid-js'\nimport type {\n AuthAdapter, DbAdapter, PaymentsAdapter, AiAdapter, FileStorageAdapter, AdminAdapter,\n AdapterDomain, AdapterStatusInfo,\n} from '@geenius/adapters-shared'\nimport { ADAPTER_DOMAINS, DOMAIN_LABELS } from '@geenius/adapters-shared'\n\nexport interface AdapterSet {\n db?: DbAdapter\n auth?: AuthAdapter\n payments?: PaymentsAdapter\n ai?: AiAdapter\n storage?: FileStorageAdapter\n admin?: AdminAdapter\n}\n\nexport interface AdapterContextValue {\n adapters: AdapterSet\n statuses: Record<AdapterDomain, AdapterStatusInfo>\n getAdapter: <K extends keyof AdapterSet>(domain: K) => NonNullable<AdapterSet[K]>\n isReady: (domain: AdapterDomain) => boolean\n isLoading: boolean\n}\n\nconst AdapterContext = createContext<AdapterContextValue>()\n\nexport interface AdapterProviderProps {\n adapters: AdapterSet\n children: JSX.Element\n}\n\nexport function AdapterProvider(props: AdapterProviderProps) {\n const initStatuses = {} as Record<AdapterDomain, AdapterStatusInfo>\n for (const d of ADAPTER_DOMAINS) {\n const adapter = props.adapters[d as keyof AdapterSet]\n initStatuses[d] = { domain: d, provider: adapter ? 'configured' : 'none', status: adapter ? 'connected' : 'disconnected', lastCheckedAt: Date.now() }\n }\n\n const [statuses] = createStore(initStatuses)\n\n const getAdapter = <K extends keyof AdapterSet>(domain: K): NonNullable<AdapterSet[K]> => {\n const adapter = props.adapters[domain]\n if (!adapter) throw new Error(`${DOMAIN_LABELS[domain as AdapterDomain] ?? domain} adapter not configured`)\n return adapter as NonNullable<AdapterSet[K]>\n }\n\n const isReady = (domain: AdapterDomain) => !!props.adapters[domain as keyof AdapterSet] && statuses[domain]?.status === 'connected'\n\n const value: AdapterContextValue = { adapters: props.adapters, statuses, getAdapter, isReady, isLoading: false }\n\n return <AdapterContext.Provider value={value}>{props.children}</AdapterContext.Provider>\n}\n\nexport function useAdapterContext(): AdapterContextValue {\n const ctx = useContext(AdapterContext)\n if (!ctx) throw new Error('useAdapterContext must be used within <AdapterProvider>')\n return ctx\n}\n","// @geenius/adapters-solidjs — Primitives\n\nimport { createMemo } from 'solid-js'\nimport { useAdapterContext } from '../provider/AdapterProvider'\nimport type {\n AuthAdapter, DbAdapter, PaymentsAdapter, AiAdapter, FileStorageAdapter, AdminAdapter,\n AdapterDomain, AdapterStatusInfo,\n} from '@geenius/adapters-shared'\n\n/** Access the database adapter */\nexport function createDb() {\n const ctx = useAdapterContext()\n return ctx.getAdapter('db')\n}\n\n/** Access the auth adapter */\nexport function createAuth() {\n const ctx = useAdapterContext()\n return ctx.getAdapter('auth')\n}\n\n/** Access the payments adapter */\nexport function createPayments() {\n const ctx = useAdapterContext()\n return ctx.getAdapter('payments')\n}\n\n/** Access the AI adapter */\nexport function createAi() {\n const ctx = useAdapterContext()\n return ctx.getAdapter('ai')\n}\n\n/** Access the file storage adapter */\nexport function createStorage() {\n const ctx = useAdapterContext()\n return ctx.getAdapter('storage')\n}\n\n/** Access the admin adapter */\nexport function createAdmin() {\n const ctx = useAdapterContext()\n return ctx.getAdapter('admin')\n}\n\n/** Access all adapter statuses */\nexport function createAdapterStatuses() {\n const ctx = useAdapterContext()\n return ctx.statuses\n}\n\n/** Access status for a specific domain */\nexport function createAdapterStatus(domain: AdapterDomain) {\n const ctx = useAdapterContext()\n return createMemo(() => ctx.statuses[domain])\n}\n\n/** Check if adapter is ready */\nexport function createIsAdapterReady(domain: AdapterDomain) {\n const ctx = useAdapterContext()\n return createMemo(() => ctx.isReady(domain))\n}\n\n/** Access full adapters object */\nexport function createAdapters() {\n const ctx = useAdapterContext()\n return {\n db: ctx.adapters.db,\n auth: ctx.adapters.auth,\n payments: ctx.adapters.payments,\n ai: ctx.adapters.ai,\n storage: ctx.adapters.storage,\n admin: ctx.adapters.admin,\n statuses: ctx.statuses,\n isLoading: ctx.isLoading,\n isReady: ctx.isReady,\n }\n}\n","// @geenius/adapters-solidjs — AdapterStatusBadge\nimport type { AdapterStatusType } from '@geenius/adapters-shared'\n\nconst LABELS: Record<AdapterStatusType, string> = { connected: 'Connected', disconnected: 'Disconnected', error: 'Error', initializing: 'Initializing' }\nconst STYLES: Record<AdapterStatusType, { bg: string; text: string; dot: string }> = {\n connected: { bg: 'bg-emerald-500/10', text: 'text-emerald-400', dot: 'bg-emerald-400' },\n disconnected: { bg: 'bg-white/5', text: 'text-white/40', dot: 'bg-white/30' },\n error: { bg: 'bg-red-500/10', text: 'text-red-400', dot: 'bg-red-400' },\n initializing: { bg: 'bg-amber-500/10', text: 'text-amber-400', dot: 'bg-amber-400' },\n}\n\nexport function AdapterStatusBadge(props: { status: AdapterStatusType; showLabel?: boolean; class?: string }) {\n const s = () => STYLES[props.status]\n return (\n <span class={`inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 ${s().bg} ${props.class ?? ''}`}>\n <span class={`h-1.5 w-1.5 rounded-full ${s().dot} ${props.status === 'initializing' ? 'animate-pulse' : ''}`} />\n {props.showLabel !== false && <span class={`text-[0.625rem] font-semibold uppercase tracking-wider ${s().text}`}>{LABELS[props.status]}</span>}\n </span>\n )\n}\n","// @geenius/adapters-solidjs — AdapterCard\nimport { Show } from 'solid-js'\nimport type { AdapterDomain, AdapterStatusInfo } from '@geenius/adapters-shared'\nimport { DOMAIN_LABELS, DOMAIN_ICONS, DOMAIN_DESCRIPTIONS } from '@geenius/adapters-shared'\nimport { AdapterStatusBadge } from './AdapterStatusBadge'\n\nexport function AdapterCard(props: { domain: AdapterDomain; status: AdapterStatusInfo; onClick?: () => void; class?: string }) {\n return (\n <button type=\"button\" onClick={props.onClick} class={`group flex w-full items-start gap-4 rounded-2xl border border-white/10 bg-white/[0.03] p-5 text-left backdrop-blur-sm transition-all hover:border-white/15 hover:bg-white/[0.05] ${props.class ?? ''}`}>\n <div class=\"flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-xl bg-white/5 text-2xl transition-transform group-hover:scale-105\">{DOMAIN_ICONS[props.domain]}</div>\n <div class=\"min-w-0 flex-1\">\n <div class=\"flex items-center justify-between gap-2\"><h3 class=\"truncate text-sm font-bold text-white/90\">{DOMAIN_LABELS[props.domain]}</h3><AdapterStatusBadge status={props.status.status} /></div>\n <p class=\"mt-0.5 text-xs text-white/40 line-clamp-2\">{DOMAIN_DESCRIPTIONS[props.domain]}</p>\n <Show when={props.status.provider && props.status.provider !== 'none'}>\n <div class=\"mt-2 flex items-center gap-2\">\n <span class=\"rounded-md bg-white/5 px-2 py-0.5 text-[0.625rem] font-semibold text-white/50\">{props.status.provider}</span>\n <Show when={props.status.latency}><span class=\"text-[0.625rem] text-white/30\">{props.status.latency}ms</span></Show>\n </div>\n </Show>\n <Show when={props.status.error}><p class=\"mt-1.5 truncate text-[0.625rem] text-red-400/80\">{props.status.error}</p></Show>\n </div>\n </button>\n )\n}\n","// @geenius/adapters-solidjs — AdapterList\nimport { createSignal, createMemo, Show, For } from 'solid-js'\nimport { createAdapters } from '../primitives'\nimport { AdapterCard } from './AdapterCard'\nimport { ADAPTER_DOMAINS, DOMAIN_LABELS } from '@geenius/adapters-shared'\nimport type { AdapterDomain, AdapterStatusType } from '@geenius/adapters-shared'\n\nexport function AdapterList(props: { onSelect?: (d: AdapterDomain) => void; filterStatus?: AdapterStatusType; class?: string }) {\n const ctx = createAdapters()\n const [search, setSearch] = createSignal('')\n\n const filtered = createMemo(() => {\n let domains = [...ADAPTER_DOMAINS]\n const q = search().toLowerCase()\n if (q) domains = domains.filter(d => DOMAIN_LABELS[d].toLowerCase().includes(q) || d.includes(q))\n if (props.filterStatus) domains = domains.filter(d => ctx.statuses[d]?.status === props.filterStatus)\n return domains\n })\n\n return (\n <div class={props.class ?? ''}>\n <input type=\"text\" value={search()} onInput={e => setSearch(e.currentTarget.value)} placeholder=\"Search adapters...\" class=\"w-full rounded-xl border border-white/10 bg-white/[0.02] px-4 py-2.5 text-sm text-white/90 placeholder:text-white/20 focus:border-indigo-500/50 focus:outline-none mb-4\" />\n <Show when={filtered().length > 0} fallback={<div class=\"rounded-xl border border-white/5 bg-white/[0.01] p-8 text-center\"><p class=\"text-sm text-white/40\">No adapters match</p></div>}>\n <div class=\"grid gap-3 sm:grid-cols-2\"><For each={filtered()}>{d => <AdapterCard domain={d} status={ctx.statuses[d]} onClick={() => props.onSelect?.(d)} />}</For></div>\n </Show>\n </div>\n )\n}\n","// @geenius/adapters-solidjs — AdapterConfigForm\nimport { createSignal, For, Show } from 'solid-js'\nimport type { AdapterDomain, DomainAdapterConfig } from '@geenius/adapters-shared'\nimport { DOMAIN_LABELS, getProvidersForDomain } from '@geenius/adapters-shared'\n\nexport function AdapterConfigForm(props: { domain: AdapterDomain; initialConfig?: DomainAdapterConfig; onSave: (c: DomainAdapterConfig) => Promise<void> | void; onCancel?: () => void; class?: string }) {\n const providers = getProvidersForDomain(props.domain)\n const [provider, setProvider] = createSignal(props.initialConfig?.provider ?? providers[0]?.id ?? '')\n const [apiKey, setApiKey] = createSignal(props.initialConfig?.apiKey ?? '')\n const [baseUrl, setBaseUrl] = createSignal(props.initialConfig?.baseUrl ?? '')\n const [isSaving, setIsSaving] = createSignal(false)\n const [error, setError] = createSignal<string | null>(null)\n\n const needsApiKey = () => !['localStorage', 'noop'].includes(provider())\n const needsBaseUrl = () => ['ollama', 'minio', 'neon', 'supabase'].includes(provider())\n\n const handleSubmit = async (e: Event) => {\n e.preventDefault(); setError(null)\n if (!provider()) { setError('Select a provider'); return }\n setIsSaving(true)\n try { await props.onSave({ provider: provider(), apiKey: apiKey() || undefined, baseUrl: baseUrl() || undefined }) }\n catch (e) { setError(e instanceof Error ? e.message : 'Failed') }\n finally { setIsSaving(false) }\n }\n\n return (\n <form onSubmit={handleSubmit} class={`space-y-5 rounded-2xl border border-white/10 bg-white/[0.03] p-6 backdrop-blur-sm ${props.class ?? ''}`}>\n <div><h3 class=\"text-lg font-bold text-white/90\">Configure {DOMAIN_LABELS[props.domain]}</h3></div>\n <Show when={error()}><div class=\"rounded-lg border border-red-500/20 bg-red-500/10 px-4 py-3 text-sm text-red-400\">{error()}</div></Show>\n <div>\n <span class=\"mb-1.5 block text-xs font-semibold uppercase tracking-wider text-white/40\">Provider</span>\n <div class=\"grid gap-2 sm:grid-cols-2\">\n <For each={providers}>{p => (\n <button type=\"button\" onClick={() => setProvider(p.id)} class={`flex flex-col rounded-xl border p-3 text-left transition-all ${provider() === p.id ? 'border-indigo-500/30 bg-indigo-500/10' : 'border-white/10 bg-white/[0.02] hover:bg-white/[0.04]'}`}>\n <span class=\"text-xs font-semibold text-white/80\">{p.name}</span>\n <span class=\"mt-0.5 text-[0.625rem] text-white/40\">{p.description}</span>\n <span class={`mt-1 self-start rounded px-1.5 py-0.5 text-[0.5625rem] font-bold uppercase ${p.tier === 'pronto' ? 'bg-emerald-500/10 text-emerald-400' : 'bg-purple-500/10 text-purple-400'}`}>{p.tier}</span>\n </button>\n )}</For>\n </div>\n </div>\n <Show when={needsApiKey()}>\n <div><label class=\"mb-1.5 block text-xs font-semibold uppercase tracking-wider text-white/40\">API Key</label><input type=\"password\" value={apiKey()} onInput={e => setApiKey(e.currentTarget.value)} class=\"w-full rounded-xl border border-white/10 bg-white/[0.02] px-4 py-3 text-sm text-white/90 placeholder:text-white/20 focus:border-indigo-500/50 focus:outline-none\" placeholder=\"API key\" /></div>\n </Show>\n <Show when={needsBaseUrl()}>\n <div><label class=\"mb-1.5 block text-xs font-semibold uppercase tracking-wider text-white/40\">Base URL</label><input type=\"url\" value={baseUrl()} onInput={e => setBaseUrl(e.currentTarget.value)} class=\"w-full rounded-xl border border-white/10 bg-white/[0.02] px-4 py-3 text-sm text-white/90 placeholder:text-white/20 focus:border-indigo-500/50 focus:outline-none\" placeholder=\"https://...\" /></div>\n </Show>\n <div class=\"flex justify-end gap-3 pt-2\">\n <Show when={props.onCancel}><button type=\"button\" onClick={props.onCancel} class=\"rounded-xl px-5 py-2.5 text-sm font-semibold text-white/50 hover:text-white/70\">Cancel</button></Show>\n <button type=\"submit\" disabled={isSaving() || !provider()} class=\"rounded-xl bg-indigo-500 px-6 py-2.5 text-sm font-semibold text-white hover:bg-indigo-400 disabled:opacity-50\">{isSaving() ? 'Saving…' : 'Save'}</button>\n </div>\n </form>\n )\n}\n","// @geenius/adapters-solidjs — AdaptersPage\nimport { createSignal, For } from 'solid-js'\nimport { createAdapters } from '../primitives'\nimport { AdapterList } from '../components/AdapterList'\nimport { AdapterConfigForm } from '../components/AdapterConfigForm'\nimport { AdapterStatusBadge } from '../components/AdapterStatusBadge'\nimport { ADAPTER_DOMAINS, ADAPTER_STATUSES } from '@geenius/adapters-shared'\nimport type { AdapterDomain, AdapterStatusType } from '@geenius/adapters-shared'\n\nexport function AdaptersPage(props: { onNavigateDetail?: (d: AdapterDomain) => void; class?: string }) {\n const ctx = createAdapters()\n const [selectedDomain, setSelectedDomain] = createSignal<AdapterDomain | null>(null)\n const [filterStatus, setFilterStatus] = createSignal<AdapterStatusType | undefined>()\n const connected = () => ADAPTER_DOMAINS.filter(d => ctx.statuses[d]?.status === 'connected').length\n const errors = () => ADAPTER_DOMAINS.filter(d => ctx.statuses[d]?.status === 'error').length\n\n return (\n <div class={`max-w-4xl mx-auto space-y-8 ${props.class ?? ''}`}>\n <div><h1 class=\"text-2xl font-extrabold text-white/95 tracking-tight\">Adapters</h1><p class=\"mt-1 text-sm text-white/40\">Manage infrastructure adapters.</p></div>\n <div class=\"grid gap-3 sm:grid-cols-3\">\n <div class=\"rounded-2xl border border-white/10 bg-white/[0.03] p-4\"><p class=\"text-xs font-semibold uppercase text-white/30\">Total</p><p class=\"mt-1 text-2xl font-extrabold text-white/90\">{ADAPTER_DOMAINS.length}</p></div>\n <div class=\"rounded-2xl border border-emerald-500/10 bg-emerald-500/[0.03] p-4\"><p class=\"text-xs font-semibold uppercase text-emerald-400/60\">Connected</p><p class=\"mt-1 text-2xl font-extrabold text-emerald-400\">{connected()}</p></div>\n {errors() > 0 && <div class=\"rounded-2xl border border-red-500/10 bg-red-500/[0.03] p-4\"><p class=\"text-xs font-semibold uppercase text-red-400/60\">Errors</p><p class=\"mt-1 text-2xl font-extrabold text-red-400\">{errors()}</p></div>}\n </div>\n <div class=\"flex items-center gap-2\">\n <button onClick={() => setFilterStatus(undefined)} class={`rounded-lg px-3 py-1.5 text-xs font-semibold ${!filterStatus() ? 'bg-white/10 text-white/80' : 'text-white/30'}`}>All</button>\n <For each={[...ADAPTER_STATUSES]}>{s => <button onClick={() => setFilterStatus(s)} class={`flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-semibold ${filterStatus() === s ? 'bg-white/10 text-white/80' : 'text-white/30'}`}><AdapterStatusBadge status={s} showLabel={false} />{s}</button>}</For>\n </div>\n <AdapterList onSelect={d => props.onNavigateDetail ? props.onNavigateDetail(d) : setSelectedDomain(d)} filterStatus={filterStatus()} />\n {selectedDomain() && (\n <div class=\"fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm\" onClick={() => setSelectedDomain(null)}>\n <div class=\"max-w-lg w-full mx-4\" onClick={e => e.stopPropagation()}>\n <AdapterConfigForm domain={selectedDomain()!} onSave={async () => { setSelectedDomain(null) }} onCancel={() => setSelectedDomain(null)} />\n </div>\n </div>\n )}\n </div>\n )\n}\n","// @geenius/adapters-solidjs — AdapterDetailPage\nimport { createSignal, Show, For } from 'solid-js'\nimport { createAdapters, createAdapterStatus } from '../primitives'\nimport { AdapterStatusBadge } from '../components/AdapterStatusBadge'\nimport { AdapterConfigForm } from '../components/AdapterConfigForm'\nimport type { AdapterDomain } from '@geenius/adapters-shared'\nimport { DOMAIN_LABELS, DOMAIN_ICONS, DOMAIN_DESCRIPTIONS, getProvidersForDomain } from '@geenius/adapters-shared'\n\nexport function AdapterDetailPage(props: { domain: AdapterDomain; onBack?: () => void; class?: string }) {\n const status = createAdapterStatus(props.domain)\n const providers = getProvidersForDomain(props.domain)\n const [isEditing, setIsEditing] = createSignal(false)\n\n return (\n <div class={`max-w-3xl mx-auto space-y-8 ${props.class ?? ''}`}>\n <Show when={props.onBack}><button onClick={props.onBack} class=\"text-sm text-white/30 hover:text-white/60\">← Back</button></Show>\n <div class=\"flex items-start gap-5\">\n <div class=\"flex h-16 w-16 items-center justify-center rounded-2xl bg-white/5 text-3xl\">{DOMAIN_ICONS[props.domain]}</div>\n <div class=\"flex-1\"><div class=\"flex items-center gap-3\"><h1 class=\"text-2xl font-extrabold text-white/95\">{DOMAIN_LABELS[props.domain]}</h1><AdapterStatusBadge status={status().status} /></div><p class=\"mt-1 text-sm text-white/40\">{DOMAIN_DESCRIPTIONS[props.domain]}</p></div>\n </div>\n <div class=\"rounded-2xl border border-white/10 bg-white/[0.03] p-6\">\n <h2 class=\"text-xs font-semibold uppercase text-white/30 mb-4\">Status</h2>\n <div class=\"grid gap-4 sm:grid-cols-3\">\n <div><p class=\"text-[0.625rem] text-white/30 uppercase\">Provider</p><p class=\"mt-0.5 text-sm font-semibold text-white/80\">{status().provider !== 'none' ? status().provider : '—'}</p></div>\n <div><p class=\"text-[0.625rem] text-white/30 uppercase\">Status</p><AdapterStatusBadge status={status().status} /></div>\n <div><p class=\"text-[0.625rem] text-white/30 uppercase\">Last Checked</p><p class=\"mt-0.5 text-sm text-white/60\">{status().lastCheckedAt ? new Date(status().lastCheckedAt!).toLocaleTimeString() : '—'}</p></div>\n </div>\n </div>\n <div class=\"rounded-2xl border border-white/10 bg-white/[0.03] p-6\">\n <h2 class=\"text-xs font-semibold uppercase text-white/30 mb-4\">Available Providers ({providers.length})</h2>\n <div class=\"divide-y divide-white/5\"><For each={providers}>{p => <div class=\"flex items-center justify-between py-3\"><div><p class=\"text-sm font-semibold text-white/80\">{p.name}</p><p class=\"text-xs text-white/30\">{p.description}</p></div><span class={`rounded px-2 py-0.5 text-[0.625rem] font-bold uppercase ${p.tier === 'pronto' ? 'bg-emerald-500/10 text-emerald-400' : 'bg-blue-500/10 text-blue-400'}`}>{p.tier}</span></div>}</For></div>\n </div>\n <Show when={isEditing()} fallback={<button onClick={() => setIsEditing(true)} class=\"w-full rounded-2xl border border-dashed border-white/10 bg-white/[0.01] p-6 text-center text-sm text-white/30 hover:border-white/20\">⚙️ Configure</button>}>\n <AdapterConfigForm domain={props.domain} onSave={async () => { setIsEditing(false) }} onCancel={() => setIsEditing(false)} />\n </Show>\n </div>\n )\n}\n"],"mappings":"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","names":["import_adapters_shared","import_solid_js","import_solid_js","import_adapters_shared","import_solid_js","import_adapters_shared","import_solid_js","import_adapters_shared","e","import_solid_js","import_adapters_shared","import_solid_js","import_adapters_shared"]}
@@ -0,0 +1,202 @@
1
+ // src/index.tsx
2
+ import { ADAPTER_DOMAINS as ADAPTER_DOMAINS4, DOMAIN_LABELS as DOMAIN_LABELS6, DOMAIN_ICONS as DOMAIN_ICONS3, DOMAIN_DESCRIPTIONS as DOMAIN_DESCRIPTIONS3, configureAdapters, getAdapterConfig } from "@geenius/adapters-shared";
3
+
4
+ // src/provider/AdapterProvider.tsx
5
+ import { createContext, useContext } from "solid-js";
6
+ import { createStore } from "solid-js/store";
7
+ import { ADAPTER_DOMAINS, DOMAIN_LABELS } from "@geenius/adapters-shared";
8
+ var AdapterContext = createContext();
9
+ function AdapterProvider(props) {
10
+ const initStatuses = {};
11
+ for (const d of ADAPTER_DOMAINS) {
12
+ const adapter = props.adapters[d];
13
+ initStatuses[d] = { domain: d, provider: adapter ? "configured" : "none", status: adapter ? "connected" : "disconnected", lastCheckedAt: Date.now() };
14
+ }
15
+ const [statuses] = createStore(initStatuses);
16
+ const getAdapter = (domain) => {
17
+ const adapter = props.adapters[domain];
18
+ if (!adapter) throw new Error(`${DOMAIN_LABELS[domain] ?? domain} adapter not configured`);
19
+ return adapter;
20
+ };
21
+ const isReady = (domain) => !!props.adapters[domain] && statuses[domain]?.status === "connected";
22
+ const value = { adapters: props.adapters, statuses, getAdapter, isReady, isLoading: false };
23
+ return /* @__PURE__ */ React.createElement(AdapterContext.Provider, { value }, props.children);
24
+ }
25
+ function useAdapterContext() {
26
+ const ctx = useContext(AdapterContext);
27
+ if (!ctx) throw new Error("useAdapterContext must be used within <AdapterProvider>");
28
+ return ctx;
29
+ }
30
+
31
+ // src/primitives/index.ts
32
+ import { createMemo } from "solid-js";
33
+ function createDb() {
34
+ const ctx = useAdapterContext();
35
+ return ctx.getAdapter("db");
36
+ }
37
+ function createAuth() {
38
+ const ctx = useAdapterContext();
39
+ return ctx.getAdapter("auth");
40
+ }
41
+ function createPayments() {
42
+ const ctx = useAdapterContext();
43
+ return ctx.getAdapter("payments");
44
+ }
45
+ function createAi() {
46
+ const ctx = useAdapterContext();
47
+ return ctx.getAdapter("ai");
48
+ }
49
+ function createStorage() {
50
+ const ctx = useAdapterContext();
51
+ return ctx.getAdapter("storage");
52
+ }
53
+ function createAdmin() {
54
+ const ctx = useAdapterContext();
55
+ return ctx.getAdapter("admin");
56
+ }
57
+ function createAdapterStatuses() {
58
+ const ctx = useAdapterContext();
59
+ return ctx.statuses;
60
+ }
61
+ function createAdapterStatus(domain) {
62
+ const ctx = useAdapterContext();
63
+ return createMemo(() => ctx.statuses[domain]);
64
+ }
65
+ function createIsAdapterReady(domain) {
66
+ const ctx = useAdapterContext();
67
+ return createMemo(() => ctx.isReady(domain));
68
+ }
69
+ function createAdapters() {
70
+ const ctx = useAdapterContext();
71
+ return {
72
+ db: ctx.adapters.db,
73
+ auth: ctx.adapters.auth,
74
+ payments: ctx.adapters.payments,
75
+ ai: ctx.adapters.ai,
76
+ storage: ctx.adapters.storage,
77
+ admin: ctx.adapters.admin,
78
+ statuses: ctx.statuses,
79
+ isLoading: ctx.isLoading,
80
+ isReady: ctx.isReady
81
+ };
82
+ }
83
+
84
+ // src/components/AdapterStatusBadge.tsx
85
+ var LABELS = { connected: "Connected", disconnected: "Disconnected", error: "Error", initializing: "Initializing" };
86
+ var STYLES = {
87
+ connected: { bg: "bg-emerald-500/10", text: "text-emerald-400", dot: "bg-emerald-400" },
88
+ disconnected: { bg: "bg-white/5", text: "text-white/40", dot: "bg-white/30" },
89
+ error: { bg: "bg-red-500/10", text: "text-red-400", dot: "bg-red-400" },
90
+ initializing: { bg: "bg-amber-500/10", text: "text-amber-400", dot: "bg-amber-400" }
91
+ };
92
+ function AdapterStatusBadge(props) {
93
+ const s = () => STYLES[props.status];
94
+ return /* @__PURE__ */ React.createElement("span", { class: `inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 ${s().bg} ${props.class ?? ""}` }, /* @__PURE__ */ React.createElement("span", { class: `h-1.5 w-1.5 rounded-full ${s().dot} ${props.status === "initializing" ? "animate-pulse" : ""}` }), props.showLabel !== false && /* @__PURE__ */ React.createElement("span", { class: `text-[0.625rem] font-semibold uppercase tracking-wider ${s().text}` }, LABELS[props.status]));
95
+ }
96
+
97
+ // src/components/AdapterCard.tsx
98
+ import { Show } from "solid-js";
99
+ import { DOMAIN_LABELS as DOMAIN_LABELS2, DOMAIN_ICONS, DOMAIN_DESCRIPTIONS } from "@geenius/adapters-shared";
100
+ function AdapterCard(props) {
101
+ return /* @__PURE__ */ React.createElement("button", { type: "button", onClick: props.onClick, class: `group flex w-full items-start gap-4 rounded-2xl border border-white/10 bg-white/[0.03] p-5 text-left backdrop-blur-sm transition-all hover:border-white/15 hover:bg-white/[0.05] ${props.class ?? ""}` }, /* @__PURE__ */ React.createElement("div", { class: "flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-xl bg-white/5 text-2xl transition-transform group-hover:scale-105" }, DOMAIN_ICONS[props.domain]), /* @__PURE__ */ React.createElement("div", { class: "min-w-0 flex-1" }, /* @__PURE__ */ React.createElement("div", { class: "flex items-center justify-between gap-2" }, /* @__PURE__ */ React.createElement("h3", { class: "truncate text-sm font-bold text-white/90" }, DOMAIN_LABELS2[props.domain]), /* @__PURE__ */ React.createElement(AdapterStatusBadge, { status: props.status.status })), /* @__PURE__ */ React.createElement("p", { class: "mt-0.5 text-xs text-white/40 line-clamp-2" }, DOMAIN_DESCRIPTIONS[props.domain]), /* @__PURE__ */ React.createElement(Show, { when: props.status.provider && props.status.provider !== "none" }, /* @__PURE__ */ React.createElement("div", { class: "mt-2 flex items-center gap-2" }, /* @__PURE__ */ React.createElement("span", { class: "rounded-md bg-white/5 px-2 py-0.5 text-[0.625rem] font-semibold text-white/50" }, props.status.provider), /* @__PURE__ */ React.createElement(Show, { when: props.status.latency }, /* @__PURE__ */ React.createElement("span", { class: "text-[0.625rem] text-white/30" }, props.status.latency, "ms")))), /* @__PURE__ */ React.createElement(Show, { when: props.status.error }, /* @__PURE__ */ React.createElement("p", { class: "mt-1.5 truncate text-[0.625rem] text-red-400/80" }, props.status.error))));
102
+ }
103
+
104
+ // src/components/AdapterList.tsx
105
+ import { createSignal, createMemo as createMemo2, Show as Show2, For } from "solid-js";
106
+ import { ADAPTER_DOMAINS as ADAPTER_DOMAINS2, DOMAIN_LABELS as DOMAIN_LABELS3 } from "@geenius/adapters-shared";
107
+ function AdapterList(props) {
108
+ const ctx = createAdapters();
109
+ const [search, setSearch] = createSignal("");
110
+ const filtered = createMemo2(() => {
111
+ let domains = [...ADAPTER_DOMAINS2];
112
+ const q = search().toLowerCase();
113
+ if (q) domains = domains.filter((d) => DOMAIN_LABELS3[d].toLowerCase().includes(q) || d.includes(q));
114
+ if (props.filterStatus) domains = domains.filter((d) => ctx.statuses[d]?.status === props.filterStatus);
115
+ return domains;
116
+ });
117
+ return /* @__PURE__ */ React.createElement("div", { class: props.class ?? "" }, /* @__PURE__ */ React.createElement("input", { type: "text", value: search(), onInput: (e) => setSearch(e.currentTarget.value), placeholder: "Search adapters...", class: "w-full rounded-xl border border-white/10 bg-white/[0.02] px-4 py-2.5 text-sm text-white/90 placeholder:text-white/20 focus:border-indigo-500/50 focus:outline-none mb-4" }), /* @__PURE__ */ React.createElement(Show2, { when: filtered().length > 0, fallback: /* @__PURE__ */ React.createElement("div", { class: "rounded-xl border border-white/5 bg-white/[0.01] p-8 text-center" }, /* @__PURE__ */ React.createElement("p", { class: "text-sm text-white/40" }, "No adapters match")) }, /* @__PURE__ */ React.createElement("div", { class: "grid gap-3 sm:grid-cols-2" }, /* @__PURE__ */ React.createElement(For, { each: filtered() }, (d) => /* @__PURE__ */ React.createElement(AdapterCard, { domain: d, status: ctx.statuses[d], onClick: () => props.onSelect?.(d) })))));
118
+ }
119
+
120
+ // src/components/AdapterConfigForm.tsx
121
+ import { createSignal as createSignal2, For as For2, Show as Show3 } from "solid-js";
122
+ import { DOMAIN_LABELS as DOMAIN_LABELS4, getProvidersForDomain } from "@geenius/adapters-shared";
123
+ function AdapterConfigForm(props) {
124
+ const providers = getProvidersForDomain(props.domain);
125
+ const [provider, setProvider] = createSignal2(props.initialConfig?.provider ?? providers[0]?.id ?? "");
126
+ const [apiKey, setApiKey] = createSignal2(props.initialConfig?.apiKey ?? "");
127
+ const [baseUrl, setBaseUrl] = createSignal2(props.initialConfig?.baseUrl ?? "");
128
+ const [isSaving, setIsSaving] = createSignal2(false);
129
+ const [error, setError] = createSignal2(null);
130
+ const needsApiKey = () => !["localStorage", "noop"].includes(provider());
131
+ const needsBaseUrl = () => ["ollama", "minio", "neon", "supabase"].includes(provider());
132
+ const handleSubmit = async (e) => {
133
+ e.preventDefault();
134
+ setError(null);
135
+ if (!provider()) {
136
+ setError("Select a provider");
137
+ return;
138
+ }
139
+ setIsSaving(true);
140
+ try {
141
+ await props.onSave({ provider: provider(), apiKey: apiKey() || void 0, baseUrl: baseUrl() || void 0 });
142
+ } catch (e2) {
143
+ setError(e2 instanceof Error ? e2.message : "Failed");
144
+ } finally {
145
+ setIsSaving(false);
146
+ }
147
+ };
148
+ return /* @__PURE__ */ React.createElement("form", { onSubmit: handleSubmit, class: `space-y-5 rounded-2xl border border-white/10 bg-white/[0.03] p-6 backdrop-blur-sm ${props.class ?? ""}` }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h3", { class: "text-lg font-bold text-white/90" }, "Configure ", DOMAIN_LABELS4[props.domain])), /* @__PURE__ */ React.createElement(Show3, { when: error() }, /* @__PURE__ */ React.createElement("div", { class: "rounded-lg border border-red-500/20 bg-red-500/10 px-4 py-3 text-sm text-red-400" }, error())), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("span", { class: "mb-1.5 block text-xs font-semibold uppercase tracking-wider text-white/40" }, "Provider"), /* @__PURE__ */ React.createElement("div", { class: "grid gap-2 sm:grid-cols-2" }, /* @__PURE__ */ React.createElement(For2, { each: providers }, (p) => /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => setProvider(p.id), class: `flex flex-col rounded-xl border p-3 text-left transition-all ${provider() === p.id ? "border-indigo-500/30 bg-indigo-500/10" : "border-white/10 bg-white/[0.02] hover:bg-white/[0.04]"}` }, /* @__PURE__ */ React.createElement("span", { class: "text-xs font-semibold text-white/80" }, p.name), /* @__PURE__ */ React.createElement("span", { class: "mt-0.5 text-[0.625rem] text-white/40" }, p.description), /* @__PURE__ */ React.createElement("span", { class: `mt-1 self-start rounded px-1.5 py-0.5 text-[0.5625rem] font-bold uppercase ${p.tier === "pronto" ? "bg-emerald-500/10 text-emerald-400" : "bg-purple-500/10 text-purple-400"}` }, p.tier))))), /* @__PURE__ */ React.createElement(Show3, { when: needsApiKey() }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("label", { class: "mb-1.5 block text-xs font-semibold uppercase tracking-wider text-white/40" }, "API Key"), /* @__PURE__ */ React.createElement("input", { type: "password", value: apiKey(), onInput: (e) => setApiKey(e.currentTarget.value), class: "w-full rounded-xl border border-white/10 bg-white/[0.02] px-4 py-3 text-sm text-white/90 placeholder:text-white/20 focus:border-indigo-500/50 focus:outline-none", placeholder: "API key" }))), /* @__PURE__ */ React.createElement(Show3, { when: needsBaseUrl() }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("label", { class: "mb-1.5 block text-xs font-semibold uppercase tracking-wider text-white/40" }, "Base URL"), /* @__PURE__ */ React.createElement("input", { type: "url", value: baseUrl(), onInput: (e) => setBaseUrl(e.currentTarget.value), class: "w-full rounded-xl border border-white/10 bg-white/[0.02] px-4 py-3 text-sm text-white/90 placeholder:text-white/20 focus:border-indigo-500/50 focus:outline-none", placeholder: "https://..." }))), /* @__PURE__ */ React.createElement("div", { class: "flex justify-end gap-3 pt-2" }, /* @__PURE__ */ React.createElement(Show3, { when: props.onCancel }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: props.onCancel, class: "rounded-xl px-5 py-2.5 text-sm font-semibold text-white/50 hover:text-white/70" }, "Cancel")), /* @__PURE__ */ React.createElement("button", { type: "submit", disabled: isSaving() || !provider(), class: "rounded-xl bg-indigo-500 px-6 py-2.5 text-sm font-semibold text-white hover:bg-indigo-400 disabled:opacity-50" }, isSaving() ? "Saving\u2026" : "Save")));
149
+ }
150
+
151
+ // src/pages/AdaptersPage.tsx
152
+ import { createSignal as createSignal3, For as For3 } from "solid-js";
153
+ import { ADAPTER_DOMAINS as ADAPTER_DOMAINS3, ADAPTER_STATUSES } from "@geenius/adapters-shared";
154
+ function AdaptersPage(props) {
155
+ const ctx = createAdapters();
156
+ const [selectedDomain, setSelectedDomain] = createSignal3(null);
157
+ const [filterStatus, setFilterStatus] = createSignal3();
158
+ const connected = () => ADAPTER_DOMAINS3.filter((d) => ctx.statuses[d]?.status === "connected").length;
159
+ const errors = () => ADAPTER_DOMAINS3.filter((d) => ctx.statuses[d]?.status === "error").length;
160
+ return /* @__PURE__ */ React.createElement("div", { class: `max-w-4xl mx-auto space-y-8 ${props.class ?? ""}` }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h1", { class: "text-2xl font-extrabold text-white/95 tracking-tight" }, "Adapters"), /* @__PURE__ */ React.createElement("p", { class: "mt-1 text-sm text-white/40" }, "Manage infrastructure adapters.")), /* @__PURE__ */ React.createElement("div", { class: "grid gap-3 sm:grid-cols-3" }, /* @__PURE__ */ React.createElement("div", { class: "rounded-2xl border border-white/10 bg-white/[0.03] p-4" }, /* @__PURE__ */ React.createElement("p", { class: "text-xs font-semibold uppercase text-white/30" }, "Total"), /* @__PURE__ */ React.createElement("p", { class: "mt-1 text-2xl font-extrabold text-white/90" }, ADAPTER_DOMAINS3.length)), /* @__PURE__ */ React.createElement("div", { class: "rounded-2xl border border-emerald-500/10 bg-emerald-500/[0.03] p-4" }, /* @__PURE__ */ React.createElement("p", { class: "text-xs font-semibold uppercase text-emerald-400/60" }, "Connected"), /* @__PURE__ */ React.createElement("p", { class: "mt-1 text-2xl font-extrabold text-emerald-400" }, connected())), errors() > 0 && /* @__PURE__ */ React.createElement("div", { class: "rounded-2xl border border-red-500/10 bg-red-500/[0.03] p-4" }, /* @__PURE__ */ React.createElement("p", { class: "text-xs font-semibold uppercase text-red-400/60" }, "Errors"), /* @__PURE__ */ React.createElement("p", { class: "mt-1 text-2xl font-extrabold text-red-400" }, errors()))), /* @__PURE__ */ React.createElement("div", { class: "flex items-center gap-2" }, /* @__PURE__ */ React.createElement("button", { onClick: () => setFilterStatus(void 0), class: `rounded-lg px-3 py-1.5 text-xs font-semibold ${!filterStatus() ? "bg-white/10 text-white/80" : "text-white/30"}` }, "All"), /* @__PURE__ */ React.createElement(For3, { each: [...ADAPTER_STATUSES] }, (s) => /* @__PURE__ */ React.createElement("button", { onClick: () => setFilterStatus(s), class: `flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-semibold ${filterStatus() === s ? "bg-white/10 text-white/80" : "text-white/30"}` }, /* @__PURE__ */ React.createElement(AdapterStatusBadge, { status: s, showLabel: false }), s))), /* @__PURE__ */ React.createElement(AdapterList, { onSelect: (d) => props.onNavigateDetail ? props.onNavigateDetail(d) : setSelectedDomain(d), filterStatus: filterStatus() }), selectedDomain() && /* @__PURE__ */ React.createElement("div", { class: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm", onClick: () => setSelectedDomain(null) }, /* @__PURE__ */ React.createElement("div", { class: "max-w-lg w-full mx-4", onClick: (e) => e.stopPropagation() }, /* @__PURE__ */ React.createElement(AdapterConfigForm, { domain: selectedDomain(), onSave: async () => {
161
+ setSelectedDomain(null);
162
+ }, onCancel: () => setSelectedDomain(null) }))));
163
+ }
164
+
165
+ // src/pages/AdapterDetailPage.tsx
166
+ import { createSignal as createSignal4, Show as Show4, For as For4 } from "solid-js";
167
+ import { DOMAIN_LABELS as DOMAIN_LABELS5, DOMAIN_ICONS as DOMAIN_ICONS2, DOMAIN_DESCRIPTIONS as DOMAIN_DESCRIPTIONS2, getProvidersForDomain as getProvidersForDomain2 } from "@geenius/adapters-shared";
168
+ function AdapterDetailPage(props) {
169
+ const status = createAdapterStatus(props.domain);
170
+ const providers = getProvidersForDomain2(props.domain);
171
+ const [isEditing, setIsEditing] = createSignal4(false);
172
+ return /* @__PURE__ */ React.createElement("div", { class: `max-w-3xl mx-auto space-y-8 ${props.class ?? ""}` }, /* @__PURE__ */ React.createElement(Show4, { when: props.onBack }, /* @__PURE__ */ React.createElement("button", { onClick: props.onBack, class: "text-sm text-white/30 hover:text-white/60" }, "\u2190 Back")), /* @__PURE__ */ React.createElement("div", { class: "flex items-start gap-5" }, /* @__PURE__ */ React.createElement("div", { class: "flex h-16 w-16 items-center justify-center rounded-2xl bg-white/5 text-3xl" }, DOMAIN_ICONS2[props.domain]), /* @__PURE__ */ React.createElement("div", { class: "flex-1" }, /* @__PURE__ */ React.createElement("div", { class: "flex items-center gap-3" }, /* @__PURE__ */ React.createElement("h1", { class: "text-2xl font-extrabold text-white/95" }, DOMAIN_LABELS5[props.domain]), /* @__PURE__ */ React.createElement(AdapterStatusBadge, { status: status().status })), /* @__PURE__ */ React.createElement("p", { class: "mt-1 text-sm text-white/40" }, DOMAIN_DESCRIPTIONS2[props.domain]))), /* @__PURE__ */ React.createElement("div", { class: "rounded-2xl border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { class: "text-xs font-semibold uppercase text-white/30 mb-4" }, "Status"), /* @__PURE__ */ React.createElement("div", { class: "grid gap-4 sm:grid-cols-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { class: "text-[0.625rem] text-white/30 uppercase" }, "Provider"), /* @__PURE__ */ React.createElement("p", { class: "mt-0.5 text-sm font-semibold text-white/80" }, status().provider !== "none" ? status().provider : "\u2014")), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { class: "text-[0.625rem] text-white/30 uppercase" }, "Status"), /* @__PURE__ */ React.createElement(AdapterStatusBadge, { status: status().status })), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { class: "text-[0.625rem] text-white/30 uppercase" }, "Last Checked"), /* @__PURE__ */ React.createElement("p", { class: "mt-0.5 text-sm text-white/60" }, status().lastCheckedAt ? new Date(status().lastCheckedAt).toLocaleTimeString() : "\u2014")))), /* @__PURE__ */ React.createElement("div", { class: "rounded-2xl border border-white/10 bg-white/[0.03] p-6" }, /* @__PURE__ */ React.createElement("h2", { class: "text-xs font-semibold uppercase text-white/30 mb-4" }, "Available Providers (", providers.length, ")"), /* @__PURE__ */ React.createElement("div", { class: "divide-y divide-white/5" }, /* @__PURE__ */ React.createElement(For4, { each: providers }, (p) => /* @__PURE__ */ React.createElement("div", { class: "flex items-center justify-between py-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("p", { class: "text-sm font-semibold text-white/80" }, p.name), /* @__PURE__ */ React.createElement("p", { class: "text-xs text-white/30" }, p.description)), /* @__PURE__ */ React.createElement("span", { class: `rounded px-2 py-0.5 text-[0.625rem] font-bold uppercase ${p.tier === "pronto" ? "bg-emerald-500/10 text-emerald-400" : "bg-blue-500/10 text-blue-400"}` }, p.tier))))), /* @__PURE__ */ React.createElement(Show4, { when: isEditing(), fallback: /* @__PURE__ */ React.createElement("button", { onClick: () => setIsEditing(true), class: "w-full rounded-2xl border border-dashed border-white/10 bg-white/[0.01] p-6 text-center text-sm text-white/30 hover:border-white/20" }, "\u2699\uFE0F Configure") }, /* @__PURE__ */ React.createElement(AdapterConfigForm, { domain: props.domain, onSave: async () => {
173
+ setIsEditing(false);
174
+ }, onCancel: () => setIsEditing(false) })));
175
+ }
176
+ export {
177
+ ADAPTER_DOMAINS4 as ADAPTER_DOMAINS,
178
+ AdapterCard,
179
+ AdapterConfigForm,
180
+ AdapterDetailPage,
181
+ AdapterList,
182
+ AdapterProvider,
183
+ AdapterStatusBadge,
184
+ AdaptersPage,
185
+ DOMAIN_DESCRIPTIONS3 as DOMAIN_DESCRIPTIONS,
186
+ DOMAIN_ICONS3 as DOMAIN_ICONS,
187
+ DOMAIN_LABELS6 as DOMAIN_LABELS,
188
+ configureAdapters,
189
+ createAdapterStatus,
190
+ createAdapterStatuses,
191
+ createAdapters,
192
+ createAdmin,
193
+ createAi,
194
+ createAuth,
195
+ createDb,
196
+ createIsAdapterReady,
197
+ createPayments,
198
+ createStorage,
199
+ getAdapterConfig,
200
+ useAdapterContext
201
+ };
202
+ //# sourceMappingURL=index.mjs.map