@fayz-ai/core 0.1.7 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/{chunk-EGWWQ7AT.cjs → chunk-5X2VX3RQ.cjs} +15 -4
- package/dist/chunk-5X2VX3RQ.cjs.map +1 -0
- package/dist/{chunk-YSBXGHAM.js → chunk-ATLZ3SGJ.js} +20 -11
- package/dist/chunk-ATLZ3SGJ.js.map +1 -0
- package/dist/{chunk-KAYQFSR6.js → chunk-CHGX6UYR.js} +15 -5
- package/dist/chunk-CHGX6UYR.js.map +1 -0
- package/dist/chunk-EKOH5PRX.js +33 -0
- package/dist/chunk-EKOH5PRX.js.map +1 -0
- package/dist/{chunk-SNQW6TRF.cjs → chunk-ILPJFUU6.cjs} +20 -11
- package/dist/chunk-ILPJFUU6.cjs.map +1 -0
- package/dist/chunk-MTDQDB7M.cjs +81 -0
- package/dist/chunk-MTDQDB7M.cjs.map +1 -0
- package/dist/chunk-NE4GLVVT.js +77 -0
- package/dist/chunk-NE4GLVVT.js.map +1 -0
- package/dist/chunk-OHRATZZH.cjs +35 -0
- package/dist/chunk-OHRATZZH.cjs.map +1 -0
- package/dist/{chunk-5EAZOMVP.js → chunk-QWUGGF2B.js} +30 -2
- package/dist/chunk-QWUGGF2B.js.map +1 -0
- package/dist/{chunk-LSVBDYFQ.cjs → chunk-VXEXM6IY.cjs} +30 -2
- package/dist/chunk-VXEXM6IY.cjs.map +1 -0
- package/dist/data/archetype.d.ts.map +1 -1
- package/dist/data/index.cjs +7 -7
- package/dist/data/index.js +1 -1
- package/dist/i18n/index.cjs +10 -10
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/i18n/shell-translations.d.ts.map +1 -1
- package/dist/index.cjs +134 -67
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +50 -8
- package/dist/index.js.map +1 -1
- package/dist/integrations/index.cjs +12 -0
- package/dist/integrations/index.cjs.map +1 -0
- package/dist/integrations/index.d.ts +119 -0
- package/dist/integrations/index.d.ts.map +1 -0
- package/dist/integrations/index.js +3 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/plugin/index.cjs +7 -7
- package/dist/plugin/index.js +1 -1
- package/dist/plugin/runtime.d.ts +3 -0
- package/dist/plugin/runtime.d.ts.map +1 -1
- package/dist/router/history.d.ts +41 -0
- package/dist/router/history.d.ts.map +1 -0
- package/dist/testing/index.cjs +20 -0
- package/dist/testing/index.cjs.map +1 -0
- package/dist/testing/index.d.ts +19 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +3 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/types/crud.d.ts +24 -1
- package/dist/types/crud.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/plugins.d.ts +72 -1
- package/dist/types/plugins.d.ts.map +1 -1
- package/package.json +14 -2
- package/src/i18n/index.ts +24 -0
- package/src/i18n/shell-translations.ts +4 -0
- package/src/index.ts +32 -3
- package/src/integrations/index.ts +170 -0
- package/src/manifest/index.ts +1 -1
- package/src/plugin/runtime.ts +16 -2
- package/src/router/history.ts +86 -0
- package/src/testing/index.ts +116 -0
- package/src/types/crud.ts +25 -0
- package/src/types/index.ts +2 -2
- package/src/types/plugins.ts +75 -1
- package/dist/chunk-5EAZOMVP.js.map +0 -1
- package/dist/chunk-EGWWQ7AT.cjs.map +0 -1
- package/dist/chunk-KAYQFSR6.js.map +0 -1
- package/dist/chunk-LSVBDYFQ.cjs.map +0 -1
- package/dist/chunk-SNQW6TRF.cjs.map +0 -1
- package/dist/chunk-YSBXGHAM.js.map +0 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Faya Labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -142,6 +142,7 @@ function createEmptyRuntime(context = EMPTY_CONTEXT) {
|
|
|
142
142
|
capabilities: [],
|
|
143
143
|
aiTools: [],
|
|
144
144
|
registries: /* @__PURE__ */ new Map(),
|
|
145
|
+
connectorsByHost: /* @__PURE__ */ new Map(),
|
|
145
146
|
pluginFeatures: [],
|
|
146
147
|
issues: []
|
|
147
148
|
};
|
|
@@ -167,7 +168,7 @@ function resolvePluginRuntime({
|
|
|
167
168
|
issues.push({
|
|
168
169
|
type: "incompatible_api_version",
|
|
169
170
|
pluginId: plugin.id,
|
|
170
|
-
message: `Plugin "${plugin.id}" requires plugin API v${plugin.apiVersion}, but this runtime supports v${PLUGIN_API_VERSION}. Upgrade @fayz-ai/
|
|
171
|
+
message: `Plugin "${plugin.id}" requires plugin API v${plugin.apiVersion}, but this runtime supports v${PLUGIN_API_VERSION}. Upgrade @fayz-ai/core.`
|
|
171
172
|
});
|
|
172
173
|
continue;
|
|
173
174
|
}
|
|
@@ -256,6 +257,7 @@ function resolvePluginRuntime({
|
|
|
256
257
|
const capabilities = [];
|
|
257
258
|
const aiTools = [];
|
|
258
259
|
const registries = /* @__PURE__ */ new Map();
|
|
260
|
+
const connectorsByHost = /* @__PURE__ */ new Map();
|
|
259
261
|
const pluginFeatures = [];
|
|
260
262
|
for (const plugin of activePlugins) {
|
|
261
263
|
routes.push(...plugin.routes.map((r) => ({ ...r, plugin })));
|
|
@@ -268,6 +270,11 @@ function resolvePluginRuntime({
|
|
|
268
270
|
capabilities.push(...plugin.capabilities ?? []);
|
|
269
271
|
aiTools.push(...plugin.resolvedAITools);
|
|
270
272
|
if (plugin.resolvedRegistries.length > 0) registries.set(plugin.id, plugin.resolvedRegistries);
|
|
273
|
+
for (const connector of plugin.connectors ?? []) {
|
|
274
|
+
const list = connectorsByHost.get(connector.hostPluginId) ?? [];
|
|
275
|
+
list.push(connector);
|
|
276
|
+
connectorsByHost.set(connector.hostPluginId, list);
|
|
277
|
+
}
|
|
271
278
|
if (plugin.declaredFeatures) pluginFeatures.push(...plugin.declaredFeatures);
|
|
272
279
|
widgets.push(...plugin.widgets.map((w, i) => ({
|
|
273
280
|
...w,
|
|
@@ -289,7 +296,7 @@ function resolvePluginRuntime({
|
|
|
289
296
|
settingsTabs.sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
|
|
290
297
|
widgets.sort((a, b) => a.zone !== b.zone ? a.zone.localeCompare(b.zone) : a.order - b.order);
|
|
291
298
|
dashboardWidgets.sort((a, b) => a.order - b.order);
|
|
292
|
-
return { context, plugins: resolvedPlugins, activePlugins, routes, navigation, settingsTabs, widgets, dashboardWidgets, capabilities, aiTools, issues, registries, pluginFeatures };
|
|
299
|
+
return { context, plugins: resolvedPlugins, activePlugins, routes, navigation, settingsTabs, widgets, dashboardWidgets, capabilities, aiTools, issues, registries, connectorsByHost, pluginFeatures };
|
|
293
300
|
}
|
|
294
301
|
function getWidgetsForZone(runtime, zone, contextOverrides) {
|
|
295
302
|
const ctx = { ...runtime.context, ...contextOverrides };
|
|
@@ -314,6 +321,9 @@ function usePluginRuntime() {
|
|
|
314
321
|
function usePluginRuntimeOptional() {
|
|
315
322
|
return React__namespace.useContext(PluginRuntimeContext);
|
|
316
323
|
}
|
|
324
|
+
function useConnectorsForPlugin(hostPluginId) {
|
|
325
|
+
return usePluginRuntime().connectorsByHost.get(hostPluginId) ?? [];
|
|
326
|
+
}
|
|
317
327
|
|
|
318
328
|
exports.PLUGIN_API_VERSION = PLUGIN_API_VERSION;
|
|
319
329
|
exports.PluginRuntimeProvider = PluginRuntimeProvider;
|
|
@@ -349,7 +359,8 @@ exports.registerScaffold = registerScaffold;
|
|
|
349
359
|
exports.resolvePluginComponent = resolvePluginComponent;
|
|
350
360
|
exports.resolvePluginRuntime = resolvePluginRuntime;
|
|
351
361
|
exports.scaffoldRegistry = scaffoldRegistry;
|
|
362
|
+
exports.useConnectorsForPlugin = useConnectorsForPlugin;
|
|
352
363
|
exports.usePluginRuntime = usePluginRuntime;
|
|
353
364
|
exports.usePluginRuntimeOptional = usePluginRuntimeOptional;
|
|
354
|
-
//# sourceMappingURL=chunk-
|
|
355
|
-
//# sourceMappingURL=chunk-
|
|
365
|
+
//# sourceMappingURL=chunk-5X2VX3RQ.cjs.map
|
|
366
|
+
//# sourceMappingURL=chunk-5X2VX3RQ.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/registry/index.ts","../src/plugin/runtime.ts"],"names":["React"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAuCO,IAAM,WAAN,MAAkB;AAAA,EAGvB,YAAqB,IAAA,EAAc;AAAd,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAFrB,IAAA,IAAA,CAAiB,OAAA,uBAAc,GAAA,EAA8B;AAAA,EAEzB;AAAA,EAEpC,QAAA,CAAS,EAAA,EAAY,KAAA,EAAU,IAAA,GAAqB,EAAC,EAAS;AAC5D,IAAA,IAAA,CAAK,QAAQ,GAAA,CAAI,EAAA,EAAI,EAAE,EAAA,EAAI,KAAA,EAAO,MAAM,CAAA;AAAA,EAC1C;AAAA,EAEA,IAAI,EAAA,EAA2B;AAC7B,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA,EAAG,KAAA;AAAA,EAC/B;AAAA,EAEA,SAAS,EAAA,EAA0C;AACjD,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA;AAAA,EAC5B;AAAA,EAEA,IAAI,EAAA,EAAqB;AACvB,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA;AAAA,EAC5B;AAAA,EAEA,IAAA,GAA2B;AACzB,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,OAAA,CAAQ,QAAQ,CAAA;AAAA,EACzC;AAAA,EAEA,GAAA,GAAgB;AACd,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,OAAA,CAAQ,MAAM,CAAA;AAAA,EACvC;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AAAA,EACrB;AACF;AAGO,SAAS,WAAW,EAAA,EAAqB;AAC9C,EAAA,OAAO,EAAA,CAAG,WAAW,SAAS,CAAA;AAChC;AAsCO,IAAM,iBAAA,GAAoB,IAAI,QAAA,CAAuB,WAAW;AAChE,IAAM,aAAA,GAAgB,IAAI,QAAA,CAAuB,OAAO;AACxD,IAAM,YAAA,GAAe,IAAI,QAAA,CAAuB,MAAM;AACtD,IAAM,gBAAA,GAAmB,IAAI,QAAA,CAAuB,UAAU;AAC9D,IAAM,cAAA,GAAiB,IAAI,QAAA,CAA2B,QAAQ;AAE9D,IAAM,cAAA,GAAiB,IAAI,QAAA,CAAc,QAAQ;AAIjD,IAAM,iBAAA,GAAoB,CAAC,EAAA,EAAY,CAAA,EAAiB,SAC7D,iBAAA,CAAkB,QAAA,CAAS,EAAA,EAAI,CAAA,EAAG,IAAI;AACjC,IAAM,YAAA,GAAe,CAAC,EAAA,KAAe,iBAAA,CAAkB,IAAI,EAAE;AAE7D,IAAM,aAAA,GAAgB,CAAC,EAAA,EAAY,CAAA,EAAiB,SACzD,aAAA,CAAc,QAAA,CAAS,EAAA,EAAI,CAAA,EAAG,IAAI;AAC7B,IAAM,QAAA,GAAW,CAAC,EAAA,KAAe,aAAA,CAAc,IAAI,EAAE;AACrD,IAAM,UAAA,GAAa,MAAM,aAAA,CAAc,IAAA;AAEvC,IAAM,YAAA,GAAe,CAAC,EAAA,EAAY,CAAA,EAAiB,SACxD,YAAA,CAAa,QAAA,CAAS,EAAA,EAAI,CAAA,EAAG,IAAI;AAC5B,IAAM,OAAA,GAAU,CAAC,EAAA,KAAe,YAAA,CAAa,IAAI,EAAE;AAEnD,IAAM,gBAAA,GAAmB,CAAC,EAAA,EAAY,CAAA,EAAiB,SAC5D,gBAAA,CAAiB,QAAA,CAAS,EAAA,EAAI,CAAA,EAAG,IAAI;AAChC,IAAM,WAAA,GAAc,CAAC,EAAA,KAAe,gBAAA,CAAiB,IAAI,EAAE;AAE3D,IAAM,cAAA,GAAiB,CAAC,GAAA,EAAuB,IAAA,KACpD,eAAe,QAAA,CAAS,GAAA,CAAI,EAAA,EAAI,GAAA,EAAK,IAAI;AACpC,IAAM,SAAA,GAAY,CAAC,EAAA,KAAe,cAAA,CAAe,IAAI,EAAE;AACvD,IAAM,WAAA,GAAc,MAAM,cAAA,CAAe,IAAA;AAGzC,IAAM,cAAA,GAAiB,CAAC,EAAA,EAAY,QAAA,EAAe,SACxD,cAAA,CAAe,QAAA,CAAS,EAAA,EAAI,QAAA,EAAU,IAAI;AACrC,IAAM,SAAA,GAAY,CAAC,EAAA,KAAe,cAAA,CAAe,IAAI,EAAE;AACvD,IAAM,WAAA,GAAc,MAAM,cAAA,CAAe,IAAA;AAQzC,IAAM,qBAAA,GAAwB,IAAI,QAAA,CAAwB,gBAAgB;AAC1E,IAAM,qBAAA,GAAwB,CAAC,EAAA,EAAY,OAAA,EAAwB,SACxE,qBAAA,CAAsB,QAAA,CAAS,EAAA,EAAI,OAAA,EAAS,IAAI;AAC3C,IAAM,gBAAA,GAAmB,CAAC,EAAA,KAAe,qBAAA,CAAsB,IAAI,EAAE;AACrE,IAAM,mBAAA,GAAsB,MAAM,qBAAA,CAAsB,IAAA;ACvIxD,IAAM,kBAAA,GAAqB;AAI3B,SAAS,uBACd,GAAA,EAC0C;AAC1C,EAAA,IAAI,GAAA,CAAI,SAAA,EAAW,OAAO,GAAA,CAAI,SAAA;AAC9B,EAAA,IAAI,GAAA,CAAI,WAAA,EAAa,OAAO,YAAA,CAAa,IAAI,WAAW,CAAA;AACxD,EAAA,OAAO,MAAA;AACT;AASA,IAAM,aAAA,GAAsC;AAAA,EAC1C,MAAA,EAAQ,IAAA;AAAA,EACR,IAAA,EAAM,IAAA;AAAA,EACN,WAAA,EAAa,GAAA;AAAA,EACb,WAAA,EAAa,GAAA;AAAA,EACb,MAAA,EAAQ;AACV,CAAA;AAEA,SAAS,QAAQ,KAAA,EAAuB;AACtC,EAAA,OAAO,KAAA,CAAM,aAAY,CAAE,OAAA,CAAQ,eAAe,GAAG,CAAA,CAAE,OAAA,CAAQ,QAAA,EAAU,EAAE,CAAA;AAC7E;AAEA,SAAS,mBAAA,CAAoB,SAAiB,WAAA,EAA8B;AAC1E,EAAA,IAAI,OAAA,KAAY,aAAa,OAAO,IAAA;AACpC,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,IAAI,CAAA,EAAG;AAC1B,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAChC,IAAA,OAAO,gBAAgB,IAAA,IAAQ,WAAA,CAAY,UAAA,CAAW,CAAA,EAAG,IAAI,CAAA,CAAA,CAAG,CAAA;AAAA,EAClE;AACA,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG,OAAO,WAAA,CAAY,UAAA,CAAW,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA;AAC7E,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,eAAA,CAAgB,QAA8B,OAAA,EAAwC;AAC7F,EAAA,IAAI,MAAA,CAAO,UAAA,IAAc,OAAA,CAAQ,aAAA,IAAiB,CAAC,QAAQ,aAAA,CAAc,MAAA,CAAO,UAAU,CAAA,EAAG,OAAO,KAAA;AACpG,EAAA,MAAM,aAAiD,MAAA,CAAO,UAAA;AAC9D,EAAA,IAAI,CAAC,YAAY,OAAO,IAAA;AAExB,EAAA,IAAI,UAAA,CAAW,WAAW,CAAC,UAAA,CAAW,QAAQ,QAAA,CAAS,OAAA,CAAQ,MAAM,CAAA,EAAG,OAAO,KAAA;AAC/E,EAAA,IAAI,UAAA,CAAW,KAAA,IAAS,OAAA,CAAQ,IAAA,EAAM,IAAA,IAAQ,CAAC,UAAA,CAAW,KAAA,CAAM,QAAA,CAAS,OAAA,CAAQ,IAAA,CAAK,IAAI,GAAG,OAAO,KAAA;AACpG,EAAA,IAAI,WAAW,KAAA,IAAS,CAAC,OAAA,CAAQ,IAAA,EAAM,MAAM,OAAO,KAAA;AACpD,EAAA,IAAI,UAAA,CAAW,KAAA,IAAS,OAAA,CAAQ,MAAA,EAAQ,IAAA,IAAQ,CAAC,UAAA,CAAW,KAAA,CAAM,QAAA,CAAS,OAAA,CAAQ,MAAA,CAAO,IAAI,GAAG,OAAO,KAAA;AACxG,EAAA,IAAI,WAAW,KAAA,IAAS,CAAC,OAAA,CAAQ,MAAA,EAAQ,MAAM,OAAO,KAAA;AACtD,EAAA,IAAI,UAAA,CAAW,MAAA,IAAU,CAAC,UAAA,CAAW,OAAO,IAAA,CAAK,CAAC,CAAA,KAAM,mBAAA,CAAoB,CAAA,EAAG,OAAA,CAAQ,WAAW,CAAC,GAAG,OAAO,KAAA;AAC7G,EAAA,IAAI,UAAA,CAAW,aAAA,EAAe,IAAA,CAAK,CAAC,CAAA,KAAM,mBAAA,CAAoB,CAAA,EAAG,OAAA,CAAQ,WAAW,CAAC,CAAA,EAAG,OAAO,KAAA;AAC/F,EAAA,IAAI,UAAA,CAAW,aAAa,MAAA,EAAQ;AAClC,IAAA,IAAI,CAAC,OAAA,CAAQ,aAAA,EAAe,OAAO,KAAA;AACnC,IAAA,IAAI,CAAC,UAAA,CAAW,WAAA,CAAY,KAAA,CAAM,CAAC,GAAA,KAAQ,OAAA,CAAQ,aAAA,GAAgB,GAAG,CAAC,CAAA,EAAG,OAAO,KAAA;AAAA,EACnF;AACA,EAAA,IAAI,WAAW,IAAA,IAAQ,CAAC,WAAW,IAAA,CAAK,OAAO,GAAG,OAAO,KAAA;AACzD,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,sBAAsB,MAAA,EAA6C;AAC1E,EAAA,OAAA,CAAQ,OAAO,QAAA,IAAY,IAAI,GAAA,CAAI,CAAC,OAAO,KAAA,MAAW;AAAA,IACpD,GAAG,KAAA;AAAA,IACH,QAAA,EAAU,KAAA,CAAM,QAAA,IAAY,MAAA,CAAO,EAAA;AAAA,IACnC,KAAA,EAAO,MAAM,KAAA,IAAS,KAAA;AAAA,IACtB,EAAA,EAAI,KAAA,CAAM,EAAA,IAAM,CAAA,EAAG,MAAA,CAAO,EAAE,CAAA,CAAA,EAAI,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,GACtD,CAAE,CAAA;AACJ;AAEA,SAAS,kBAAA,CAAmB,UAAgC,aAAA,EAA8B;AACxF,EAAA,OAAO;AAAA,IACL,OAAA;AAAA,IACA,SAAS,EAAC;AAAA,IACV,eAAe,EAAC;AAAA,IAChB,QAAQ,EAAC;AAAA,IACT,YAAY,EAAC;AAAA,IACb,cAAc,EAAC;AAAA,IACf,SAAS,EAAC;AAAA,IACV,kBAAkB,EAAC;AAAA,IACnB,cAAc,EAAC;AAAA,IACf,SAAS,EAAC;AAAA,IACV,UAAA,sBAAgB,GAAA,EAAI;AAAA,IACpB,gBAAA,sBAAsB,GAAA,EAAI;AAAA,IAC1B,gBAAgB,EAAC;AAAA,IACjB,QAAQ;AAAC,GACX;AACF;AAEO,SAAS,aAAuC,MAAA,EAAc;AACnE,EAAA,OAAO,MAAA;AACT;AAEO,SAAS,oBAAA,CAAqB;AAAA,EACnC,UAAU,EAAC;AAAA,EACX,gBAAgB,EAAC;AAAA,EACjB,iBAAA;AAAA,EACA;AACF,CAAA,EAA+C;AAC7C,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG,OAAO,mBAAmB,OAAO,CAAA;AAE3D,EAAA,MAAM,SAA+B,EAAC;AACtC,EAAA,MAAM,iBAAA,uBAAwB,GAAA,EAA4B;AAE1D,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,IAAI,iBAAA,CAAkB,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA,EAAG;AACpC,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,kBAAA,EAAoB,QAAA,EAAU,MAAA,CAAO,EAAA,EAAI,OAAA,EAAS,CAAA,QAAA,EAAW,MAAA,CAAO,EAAE,CAAA,4BAAA,CAAA,EAAgC,CAAA;AAC1H,MAAA;AAAA,IACF;AACA,IAAA,IAAI,MAAA,CAAO,UAAA,IAAc,IAAA,IAAQ,MAAA,CAAO,aAAa,kBAAA,EAAoB;AACvE,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,IAAA,EAAM,0BAAA;AAAA,QACN,UAAU,MAAA,CAAO,EAAA;AAAA,QACjB,OAAA,EAAS,WAAW,MAAA,CAAO,EAAE,0BAA0B,MAAA,CAAO,UAAU,gCAAgC,kBAAkB,CAAA,wBAAA;AAAA,OAC3H,CAAA;AACD,MAAA;AAAA,IACF;AACA,IAAA,iBAAA,CAAkB,GAAA,CAAI,MAAA,CAAO,EAAA,EAAI,MAAM,CAAA;AAAA,EACzC;AAEA,EAAA,MAAM,QAAA,uBAAe,GAAA,EAAiC;AACtD,EAAA,KAAA,MAAW,KAAK,aAAA,EAAe,QAAA,CAAS,GAAA,CAAI,CAAA,CAAE,UAAU,CAAC,CAAA;AACzD,EAAA,MAAM,kBAAA,GAAqB,iBAAA,IAAqB,aAAA,CAAc,MAAA,GAAS,CAAA;AAEvE,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAY;AAClC,EAAA,MAAM,gBAAA,uBAAuB,GAAA,EAAwD;AAErF,EAAA,KAAA,MAAW,MAAA,IAAU,iBAAA,CAAkB,MAAA,EAAO,EAAG;AAC/C,IAAA,MAAM,OAAA,GAAU,QAAA,CAAS,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA;AACtC,IAAA,IAAI,OAAA,EAAS,WAAW,QAAA,EAAU;AAChC,MAAA,SAAA,CAAU,GAAA,CAAI,OAAO,EAAE,CAAA;AACvB,MAAA,gBAAA,CAAiB,GAAA,CAAI,MAAA,CAAO,EAAA,EAAI,QAAQ,CAAA;AACxC,MAAA;AAAA,IACF;AACA,IAAA,IAAI,OAAO,cAAA,KAAmB,IAAA,IAAS,CAAC,kBAAA,IAAsB,MAAA,CAAO,mBAAmB,KAAA,EAAQ;AAC9F,MAAA,SAAA,CAAU,GAAA,CAAI,OAAO,EAAE,CAAA;AACvB,MAAA,gBAAA,CAAiB,GAAA,CAAI,MAAA,CAAO,EAAA,EAAI,SAAS,CAAA;AAAA,IAC3C;AAAA,EACF;AAEA,EAAA,MAAM,aAAuB,EAAC;AAC9B,EAAA,MAAM,QAAA,uBAAe,GAAA,EAAY;AACjC,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAEhC,EAAA,SAAS,KAAA,CAAM,QAAA,EAAkB,QAAA,GAAqB,EAAC,EAAS;AAC9D,IAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA,EAAG;AAC3B,IAAA,MAAM,MAAA,GAAS,iBAAA,CAAkB,GAAA,CAAI,QAAQ,CAAA;AAC7C,IAAA,IAAI,CAAC,MAAA,EAAQ;AACb,IAAA,IAAI,QAAA,CAAS,GAAA,CAAI,QAAQ,CAAA,EAAG;AAC1B,MAAA,MAAA,CAAO,KAAK,EAAE,IAAA,EAAM,qBAAA,EAAuB,QAAA,EAAU,SAAS,CAAA,qBAAA,EAAwB,CAAC,GAAG,QAAA,EAAU,QAAQ,CAAA,CAAE,IAAA,CAAK,MAAM,CAAC,KAAK,CAAA;AAC/H,MAAA;AAAA,IACF;AACA,IAAA,QAAA,CAAS,IAAI,QAAQ,CAAA;AACrB,IAAA,KAAA,MAAW,KAAA,IAAS,MAAA,CAAO,YAAA,IAAgB,EAAC,EAAG;AAC7C,MAAA,IAAI,CAAC,iBAAA,CAAkB,GAAA,CAAI,KAAK,CAAA,EAAG;AACjC,QAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,oBAAA,EAAsB,UAAU,YAAA,EAAc,KAAA,EAAO,OAAA,EAAS,CAAA,QAAA,EAAW,MAAA,CAAO,EAAE,CAAA,6BAAA,EAAgC,KAAK,MAAM,CAAA;AACjJ,QAAA;AAAA,MACF;AACA,MAAA,IAAI,SAAA,CAAU,IAAI,QAAQ,CAAA,IAAK,CAAC,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA,EAAG;AACpD,QAAA,SAAA,CAAU,IAAI,KAAK,CAAA;AACnB,QAAA,gBAAA,CAAiB,GAAA,CAAI,OAAO,YAAY,CAAA;AAAA,MAC1C;AACA,MAAA,KAAA,CAAM,KAAA,EAAO,CAAC,GAAG,QAAA,EAAU,QAAQ,CAAC,CAAA;AAAA,IACtC;AACA,IAAA,QAAA,CAAS,OAAO,QAAQ,CAAA;AACxB,IAAA,OAAA,CAAQ,IAAI,QAAQ,CAAA;AACpB,IAAA,UAAA,CAAW,KAAK,QAAQ,CAAA;AAAA,EAC1B;AAEA,EAAA,KAAA,MAAW,EAAA,IAAM,iBAAA,CAAkB,IAAA,EAAK,QAAS,EAAE,CAAA;AAEnD,EAAA,MAAM,YAAA,uBAAmB,GAAA,EAAoC;AAE7D,EAAA,KAAA,MAAW,YAAY,UAAA,EAAY;AACjC,IAAA,MAAM,MAAA,GAAS,iBAAA,CAAkB,GAAA,CAAI,QAAQ,CAAA;AAC7C,IAAA,IAAI,CAAC,MAAA,EAAQ;AACb,IAAA,MAAM,OAAA,GAAU,QAAA,CAAS,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA;AACtC,IAAA,MAAM,OAAA,GAAA,CAAW,MAAA,CAAO,YAAA,IAAgB,EAAC,EAAG,MAAA,CAAO,CAAC,EAAA,KAAO,CAAC,iBAAA,CAAkB,GAAA,CAAI,EAAE,CAAC,CAAA;AACrF,IAAA,MAAM,aAAa,CAAC,MAAA,CAAO,cAAc,MAAA,CAAO,UAAA,KAAe,QAAQ,MAAA,EAAQ,UAAA;AAC/E,IAAA,IAAI,CAAC,UAAA,EAAY;AACf,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,mBAAA,EAAqB,UAAU,MAAA,CAAO,EAAA,EAAI,OAAA,EAAS,CAAA,QAAA,EAAW,OAAO,EAAE,CAAA,qBAAA,EAAwB,MAAA,CAAO,UAAU,MAAM,CAAA;AAAA,IAC5I;AACA,IAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA,IAAK,UAAA;AAClD,IAAA,MAAM,SAAA,GAAA,CAAa,MAAA,CAAO,YAAA,IAAgB,EAAC,EAAG,KAAA,CAAM,CAAC,EAAA,KAAO,YAAA,CAAa,GAAA,CAAI,EAAE,CAAA,EAAG,QAAQ,CAAA;AAC1F,IAAA,MAAM,kBAAA,GAAqB,OAAA,EAAS,MAAA,KAAW,UAAA,IAAc,SAAS,MAAA,KAAW,SAAA;AACjF,IAAA,MAAM,cAAA,GAAiB,WAAW,YAAA,GAAe,IAAA,GAAO,UAAU,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA,IAAK,CAAC,kBAAA;AACrF,IAAA,MAAM,QAAA,GAAW,cAAA,IAAkB,UAAA,IAAc,OAAA,CAAQ,WAAW,CAAA,IAAK,SAAA;AAEzE,IAAA,YAAA,CAAa,GAAA,CAAI,OAAO,EAAA,EAAI;AAAA,MAC1B,GAAG,MAAA;AAAA,MACH,MAAA,EAAQ,QAAA,GAAW,QAAA,GAAY,OAAA,EAAS,MAAA,IAAU,UAAA;AAAA,MAClD,QAAA;AAAA,MACA,gBAAA,EAAkB,WAAW,MAAA,GAAS,UAAA;AAAA,MACtC,MAAA,EAAQ,OAAA,EAAS,MAAA,IAAU,EAAC;AAAA,MAC5B,mBAAA,EAAqB,OAAA;AAAA,MACrB,YAAA,EAAc,sBAAsB,MAAM,CAAA;AAAA,MAC1C,OAAA,EAAS,MAAA,CAAO,OAAA,IAAW,EAAC;AAAA,MAC5B,kBAAA,EAAoB,MAAA,CAAO,UAAA,IAAc,EAAC;AAAA,MAC1C,eAAA,EAAiB,MAAA,CAAO,OAAA,IAAW;AAAC,KACrC,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,eAAA,GAAkB,UAAA,CACrB,GAAA,CAAI,CAAC,OAAO,YAAA,CAAa,GAAA,CAAI,EAAE,CAAC,EAChC,MAAA,CAAO,CAAC,CAAA,KAAmC,OAAA,CAAQ,CAAC,CAAC,CAAA;AAExD,EAAA,MAAM,gBAAgB,eAAA,CAAgB,MAAA,CAAO,CAAC,CAAA,KAAM,EAAE,QAAQ,CAAA;AAC9D,EAAA,MAAM,SAA+B,EAAC;AACtC,EAAA,MAAM,aAAsC,EAAC;AAC7C,EAAA,MAAM,eAAoC,EAAC;AAC3C,EAAA,MAAM,UAAkC,EAAC;AACzC,EAAA,MAAM,mBAA8C,EAAC;AACrD,EAAA,MAAM,eAAmC,EAAC;AAC1C,EAAA,MAAM,UAA0B,EAAC;AACjC,EAAA,MAAM,UAAA,uBAAiB,GAAA,EAAiC;AACxD,EAAA,MAAM,gBAAA,uBAAuB,GAAA,EAAmC;AAChE,EAAA,MAAM,iBAAuC,EAAC;AAE9C,EAAA,KAAA,MAAW,UAAU,aAAA,EAAe;AAClC,IAAA,MAAA,CAAO,IAAA,CAAK,GAAG,MAAA,CAAO,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,MAAA,EAAO,CAAE,CAAC,CAAA;AAC3D,IAAA,UAAA,CAAW,KAAK,GAAG,MAAA,CAAO,WAAW,GAAA,CAAI,CAAC,OAAO,CAAA,MAAO;AAAA,MACtD,GAAG,KAAA;AAAA,MACH,EAAA,EAAI,KAAA,CAAM,EAAA,IAAM,CAAA,EAAG,MAAA,CAAO,EAAE,CAAA,CAAA,EAAI,KAAA,CAAM,KAAK,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA;AAAA,MAChD,IAAA,EAAM,KAAA,CAAM,IAAA,IAAQ,MAAA,CAAO;AAAA,MAC3B,CAAC,CAAA;AACH,IAAA,YAAA,CAAa,IAAA,CAAK,GAAG,MAAA,CAAO,YAAY,CAAA;AACxC,IAAA,YAAA,CAAa,IAAA,CAAK,GAAI,MAAA,CAAO,YAAA,IAAgB,EAAG,CAAA;AAChD,IAAA,OAAA,CAAQ,IAAA,CAAK,GAAG,MAAA,CAAO,eAAe,CAAA;AACtC,IAAA,IAAI,MAAA,CAAO,mBAAmB,MAAA,GAAS,CAAA,aAAc,GAAA,CAAI,MAAA,CAAO,EAAA,EAAI,MAAA,CAAO,kBAAkB,CAAA;AAE7F,IAAA,KAAA,MAAW,SAAA,IAAa,MAAA,CAAO,UAAA,IAAc,EAAC,EAAG;AAC/C,MAAA,MAAM,OAAO,gBAAA,CAAiB,GAAA,CAAI,SAAA,CAAU,YAAY,KAAK,EAAC;AAC9D,MAAA,IAAA,CAAK,KAAK,SAAS,CAAA;AACnB,MAAA,gBAAA,CAAiB,GAAA,CAAI,SAAA,CAAU,YAAA,EAAc,IAAI,CAAA;AAAA,IACnD;AACA,IAAA,IAAI,OAAO,gBAAA,EAAkB,cAAA,CAAe,IAAA,CAAK,GAAG,OAAO,gBAAgB,CAAA;AAC3E,IAAA,OAAA,CAAQ,KAAK,GAAG,MAAA,CAAO,QAAQ,GAAA,CAAI,CAAC,GAAG,CAAA,MAAO;AAAA,MAC5C,GAAG,CAAA;AAAA,MACH,KAAA,EAAO,EAAE,KAAA,IAAS,CAAA;AAAA,MAClB,MAAA,EAAQ,EAAE,GAAG,MAAA,CAAO,QAAQ,GAAI,CAAA,CAAE,KAAA,IAAS,EAAC,EAAG;AAAA,MAC/C;AAAA,MACA,CAAC,CAAA;AACH,IAAA,gBAAA,CAAiB,IAAA,CAAK,IAAI,MAAA,CAAO,gBAAA,IAAoB,EAAC,EAAG,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,MAAO;AAAA,MACtE,GAAG,CAAA;AAAA,MACH,MAAA,EAAQ,CAAA,CAAE,MAAA,IAAU,MAAA,CAAO,EAAA;AAAA,MAC3B,KAAA,EAAO,EAAE,YAAA,IAAgB,CAAA;AAAA,MACzB;AAAA,MACA,CAAC,CAAA;AAAA,EACL;AAEA,EAAA,UAAA,CAAW,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM;AACxB,IAAA,MAAM,QAAQ,EAAE,IAAA,EAAM,GAAG,SAAA,EAAW,CAAA,EAAG,UAAU,CAAA,EAAE;AACnD,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,CAAE,OAAO,CAAA,IAAK,EAAA,KAAO,KAAA,CAAM,CAAA,CAAE,OAAO,CAAA,IAAK,EAAA,CAAA,IAAO,CAAA,CAAE,QAAA,GAAW,CAAA,CAAE,QAAA;AAAA,EAC/E,CAAC,CAAA;AACD,EAAA,YAAA,CAAa,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAA,CAAO,EAAE,KAAA,IAAS,CAAA,KAAM,CAAA,CAAE,KAAA,IAAS,CAAA,CAAE,CAAA;AAC3D,EAAA,OAAA,CAAQ,KAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,SAAS,CAAA,CAAE,IAAA,GAAO,CAAA,CAAE,IAAA,CAAK,cAAc,CAAA,CAAE,IAAI,IAAI,CAAA,CAAE,KAAA,GAAQ,EAAE,KAAK,CAAA;AAC3F,EAAA,gBAAA,CAAiB,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,KAAA,GAAQ,EAAE,KAAK,CAAA;AAEjD,EAAA,OAAO,EAAE,OAAA,EAAS,OAAA,EAAS,eAAA,EAAiB,eAAe,MAAA,EAAQ,UAAA,EAAY,YAAA,EAAc,OAAA,EAAS,kBAAkB,YAAA,EAAc,OAAA,EAAS,MAAA,EAAQ,UAAA,EAAY,kBAAkB,cAAA,EAAe;AACtM;AAEO,SAAS,iBAAA,CACd,OAAA,EACA,IAAA,EACA,gBAAA,EACwB;AACxB,EAAA,MAAM,MAAM,EAAE,GAAG,OAAA,CAAQ,OAAA,EAAS,GAAG,gBAAA,EAAiB;AACtD,EAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,IAAA,IAAQ,eAAA,CAAgB,CAAA,EAAG,GAAG,CAAC,CAAA;AACjF;AAEO,SAAS,mBAAA,CACd,SACA,OAAA,EAC2B;AAC3B,EAAA,MAAM,MAAM,EAAE,GAAG,QAAQ,OAAA,EAAS,GAAG,QAAQ,gBAAA,EAAiB;AAC9D,EAAA,OAAO,OAAA,CAAQ,gBAAA,CAAiB,MAAA,CAAO,CAAC,CAAA,KAAM;AAC5C,IAAA,MAAM,QAAA,GAAW,CAAA,CAAE,QAAA,IAAY,CAAC,QAAQ,aAAa,CAAA;AACrD,IAAA,IAAI,CAAC,QAAA,CAAS,QAAA,CAAS,OAAA,CAAQ,OAAO,GAAG,OAAO,KAAA;AAChD,IAAA,IAAI,QAAQ,MAAA,IAAU,CAAA,CAAE,MAAA,KAAW,OAAA,CAAQ,QAAQ,OAAO,KAAA;AAC1D,IAAA,IAAI,CAAA,CAAE,UAAA,IAAc,GAAA,CAAI,MAAA,EAAQ,UAAA,IAAc,EAAE,UAAA,KAAe,GAAA,CAAI,MAAA,CAAO,UAAA,EAAY,OAAO,KAAA;AAC7F,IAAA,IAAI,CAAA,CAAE,UAAA,IAAc,GAAA,CAAI,aAAA,IAAiB,CAAC,IAAI,aAAA,CAAc,CAAA,CAAE,UAAU,CAAA,EAAG,OAAO,KAAA;AAClF,IAAA,OAAO,IAAA;AAAA,EACT,CAAC,CAAA;AACH;AAEA,IAAM,oBAAA,GAA6BA,+BAAoC,IAAI,CAAA;AACpE,IAAM,wBAAwB,oBAAA,CAAqB;AAEnD,SAAS,gBAAA,GAAkC;AAChD,EAAA,OAAaA,gBAAA,CAAA,UAAA,CAAW,oBAAoB,CAAA,IAAK,kBAAA,EAAmB;AACtE;AAEO,SAAS,wBAAA,GAAiD;AAC/D,EAAA,OAAaA,4BAAW,oBAAoB,CAAA;AAC9C;AAGO,SAAS,uBAAuB,YAAA,EAA6C;AAClF,EAAA,OAAO,kBAAiB,CAAE,gBAAA,CAAiB,GAAA,CAAI,YAAY,KAAK,EAAC;AACnE","file":"chunk-5X2VX3RQ.cjs","sourcesContent":["import type { ComponentType } from 'react'\n\n// ---------------------------------------------------------------------------\n// Uniform registry — the indirection layer that lets a pure-data AppManifest\n// reference code by string id. Generalizes the entity registry pattern to\n// components, blocks, pages, metrics, scaffolds and plugins.\n//\n// Naming convention: SDK/plugin artifacts use a namespaced id\n// (`agenda.week-view`, `crud.detail-header`); app-local custom code uses the\n// reserved `custom:` prefix (`custom:tannat.HarvestBoard`). The platform never\n// generates `custom:` ids — they only come from an app's registry.tsx.\n// ---------------------------------------------------------------------------\n\n/** A JSON Schema object (loosely typed; validated by tooling, not at runtime). */\nexport type JsonSchema = Record<string, unknown>\n\nexport type RegistrySource = 'sdk' | 'plugin' | 'app'\n\nexport interface RegistryMeta {\n /** Human label for the platform editor. */\n label?: string\n description?: string\n /** Where this artifact came from (for introspection / conflict reporting). */\n source?: RegistrySource\n /** Owning plugin id, when source is 'plugin'. */\n pluginId?: string\n /** JSON Schema for this artifact's props/config — drives the visual editor\n * and constrains AI generation. Optional but strongly encouraged. */\n propsSchema?: JsonSchema\n}\n\nexport interface RegistryEntry<T> {\n id: string\n value: T\n meta: RegistryMeta\n}\n\n/** A typed, introspectable id→value map. Last registration wins (so an app's\n * registry.tsx can override an SDK artifact by re-registering its id). */\nexport class Registry<T> {\n private readonly entries = new Map<string, RegistryEntry<T>>()\n\n constructor(readonly kind: string) {}\n\n register(id: string, value: T, meta: RegistryMeta = {}): void {\n this.entries.set(id, { id, value, meta })\n }\n\n get(id: string): T | undefined {\n return this.entries.get(id)?.value\n }\n\n getEntry(id: string): RegistryEntry<T> | undefined {\n return this.entries.get(id)\n }\n\n has(id: string): boolean {\n return this.entries.has(id)\n }\n\n list(): RegistryEntry<T>[] {\n return Array.from(this.entries.values())\n }\n\n ids(): string[] {\n return Array.from(this.entries.keys())\n }\n\n clear(): void {\n this.entries.clear()\n }\n}\n\n/** True for app-local custom artifacts (`custom:*`). */\nexport function isCustomId(id: string): boolean {\n return id.startsWith('custom:')\n}\n\n// ---------------------------------------------------------------------------\n// Metric definitions (consumed by dashboard / reports / KPI panels).\n// ---------------------------------------------------------------------------\n\nexport type MetricFormat = 'number' | 'currency' | 'percent' | 'duration' | 'rating'\n\nexport interface MetricContext {\n tenantId?: string\n /** ISO date range the metric should compute over, when applicable. */\n range?: { from: string; to: string }\n [key: string]: unknown\n}\n\nexport interface MetricValue {\n value: number\n previousValue?: number\n trend?: 'up' | 'down' | 'flat'\n}\n\nexport interface MetricDefinition {\n id: string\n label?: string\n category?: string\n format?: MetricFormat\n compute: (ctx: MetricContext) => Promise<MetricValue> | MetricValue\n}\n\n// ---------------------------------------------------------------------------\n// Concrete registries. Components/blocks/pages/scaffolds hold React component\n// types; metrics hold definitions; plugins hold opaque manifests (typed at the\n// plugin layer to avoid a circular import).\n// ---------------------------------------------------------------------------\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyComponent = ComponentType<any>\n\nexport const componentRegistry = new Registry<AnyComponent>('component')\nexport const blockRegistry = new Registry<AnyComponent>('block')\nexport const pageRegistry = new Registry<AnyComponent>('page')\nexport const scaffoldRegistry = new Registry<AnyComponent>('scaffold')\nexport const metricRegistry = new Registry<MetricDefinition>('metric')\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const pluginRegistry = new Registry<any>('plugin')\n\n// Thin functional facade (the public API surface) -----------------------------\n\nexport const registerComponent = (id: string, c: AnyComponent, meta?: RegistryMeta) =>\n componentRegistry.register(id, c, meta)\nexport const getComponent = (id: string) => componentRegistry.get(id)\n\nexport const registerBlock = (id: string, c: AnyComponent, meta?: RegistryMeta) =>\n blockRegistry.register(id, c, meta)\nexport const getBlock = (id: string) => blockRegistry.get(id)\nexport const listBlocks = () => blockRegistry.list()\n\nexport const registerPage = (id: string, c: AnyComponent, meta?: RegistryMeta) =>\n pageRegistry.register(id, c, meta)\nexport const getPage = (id: string) => pageRegistry.get(id)\n\nexport const registerScaffold = (id: string, c: AnyComponent, meta?: RegistryMeta) =>\n scaffoldRegistry.register(id, c, meta)\nexport const getScaffold = (id: string) => scaffoldRegistry.get(id)\n\nexport const registerMetric = (def: MetricDefinition, meta?: RegistryMeta) =>\n metricRegistry.register(def.id, def, meta)\nexport const getMetric = (id: string) => metricRegistry.get(id)\nexport const listMetrics = () => metricRegistry.list()\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const registerPlugin = (id: string, manifest: any, meta?: RegistryMeta) =>\n pluginRegistry.register(id, manifest, meta)\nexport const getPlugin = (id: string) => pluginRegistry.get(id)\nexport const listPlugins = () => pluginRegistry.list()\n\n// Plugin factories — a generated app registers each installed @fayz-ai/plugin-*\n// factory by id (src/plugins.generated.ts), so a scaffold can resolve a\n// manifest's PluginRef (id + JSON config) to a live PluginManifest:\n// getPluginFactory(ref.id)?.(ref.config)\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type PluginFactory = (config?: Record<string, unknown>) => any\nexport const pluginFactoryRegistry = new Registry<PluginFactory>('plugin-factory')\nexport const registerPluginFactory = (id: string, factory: PluginFactory, meta?: RegistryMeta) =>\n pluginFactoryRegistry.register(id, factory, meta)\nexport const getPluginFactory = (id: string) => pluginFactoryRegistry.get(id)\nexport const listPluginFactories = () => pluginFactoryRegistry.list()\n","import * as React from 'react'\nimport type {\n PluginManifest,\n PluginRuntime,\n PluginRuntimeContext,\n PluginRuntimeIssue,\n PluginRuntimeRoute,\n PluginSettingsTab,\n PluginWidgetDefinition,\n PluginWidgetZone,\n ResolvedPluginManifest,\n ResolvedPluginWidget,\n TenantPluginBinding,\n PluginRegistryDef,\n PluginAITool,\n PluginNavigationEntry,\n PluginCapability,\n PluginWidgetVisibility,\n ResolvedDashboardWidget,\n DashboardSurface,\n} from '../types/plugins'\nimport type { FeatureDeclaration } from '../types/permissions'\nimport type { ConnectorDefinition } from '../integrations'\nimport { getComponent } from '../registry'\n\n/** The plugin contract version this runtime understands. A plugin declaring a\n * higher apiVersion is rejected rather than mis-rendered. */\nexport const PLUGIN_API_VERSION = 1\n\n/** Resolve a plugin route/widget/settings/onboarding target to a component,\n * whether it provided the component directly or a registered component id. */\nexport function resolvePluginComponent(\n def: { component?: React.ComponentType<unknown>; componentId?: string },\n): React.ComponentType<unknown> | undefined {\n if (def.component) return def.component\n if (def.componentId) return getComponent(def.componentId) as React.ComponentType<unknown> | undefined\n return undefined\n}\n\ninterface ResolvePluginRuntimeOptions {\n plugins?: PluginManifest[]\n tenantPlugins?: TenantPluginBinding[]\n hasTenantBindings?: boolean\n context: PluginRuntimeContext\n}\n\nconst EMPTY_CONTEXT: PluginRuntimeContext = {\n tenant: null,\n user: null,\n currentPath: '/',\n matchedPath: '/',\n layout: 'sidebar',\n}\n\nfunction slugify(input: string): string {\n return input.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '')\n}\n\nfunction matchesRoutePattern(pattern: string, currentPath: string): boolean {\n if (pattern === currentPath) return true\n if (pattern.endsWith('/*')) {\n const base = pattern.slice(0, -2)\n return currentPath === base || currentPath.startsWith(`${base}/`)\n }\n if (pattern.endsWith('*')) return currentPath.startsWith(pattern.slice(0, -1))\n return false\n}\n\nfunction isWidgetVisible(widget: ResolvedPluginWidget, context: PluginRuntimeContext): boolean {\n if (widget.permission && context.hasPermission && !context.hasPermission(widget.permission)) return false\n const visibility: PluginWidgetVisibility | undefined = widget.visibility\n if (!visibility) return true\n\n if (visibility.layouts && !visibility.layouts.includes(context.layout)) return false\n if (visibility.roles && context.user?.role && !visibility.roles.includes(context.user.role)) return false\n if (visibility.roles && !context.user?.role) return false\n if (visibility.plans && context.tenant?.plan && !visibility.plans.includes(context.tenant.plan)) return false\n if (visibility.plans && !context.tenant?.plan) return false\n if (visibility.routes && !visibility.routes.some((p) => matchesRoutePattern(p, context.currentPath))) return false\n if (visibility.excludeRoutes?.some((p) => matchesRoutePattern(p, context.currentPath))) return false\n if (visibility.permissions?.length) {\n if (!context.hasPermission) return false\n if (!visibility.permissions.every((req) => context.hasPermission?.(req))) return false\n }\n if (visibility.when && !visibility.when(context)) return false\n return true\n}\n\nfunction normalizeSettingsTabs(plugin: PluginManifest): PluginSettingsTab[] {\n return (plugin.settings ?? []).map((entry, index) => ({\n ...entry,\n pluginId: entry.pluginId ?? plugin.id,\n order: entry.order ?? index,\n id: entry.id ?? `${plugin.id}-${slugify(entry.label)}`,\n }))\n}\n\nfunction createEmptyRuntime(context: PluginRuntimeContext = EMPTY_CONTEXT): PluginRuntime {\n return {\n context,\n plugins: [],\n activePlugins: [],\n routes: [],\n navigation: [],\n settingsTabs: [],\n widgets: [],\n dashboardWidgets: [],\n capabilities: [],\n aiTools: [],\n registries: new Map(),\n connectorsByHost: new Map(),\n pluginFeatures: [],\n issues: [],\n }\n}\n\nexport function definePlugin<T extends PluginManifest>(plugin: T): T {\n return plugin\n}\n\nexport function resolvePluginRuntime({\n plugins = [],\n tenantPlugins = [],\n hasTenantBindings,\n context,\n}: ResolvePluginRuntimeOptions): PluginRuntime {\n if (plugins.length === 0) return createEmptyRuntime(context)\n\n const issues: PluginRuntimeIssue[] = []\n const normalizedPlugins = new Map<string, PluginManifest>()\n\n for (const plugin of plugins) {\n if (normalizedPlugins.has(plugin.id)) {\n issues.push({ type: 'duplicate_plugin', pluginId: plugin.id, message: `Plugin \"${plugin.id}\" registered more than once.` })\n continue\n }\n if (plugin.apiVersion != null && plugin.apiVersion > PLUGIN_API_VERSION) {\n issues.push({\n type: 'incompatible_api_version',\n pluginId: plugin.id,\n message: `Plugin \"${plugin.id}\" requires plugin API v${plugin.apiVersion}, but this runtime supports v${PLUGIN_API_VERSION}. Upgrade @fayz-ai/core.`,\n })\n continue\n }\n normalizedPlugins.set(plugin.id, plugin)\n }\n\n const bindings = new Map<string, TenantPluginBinding>()\n for (const b of tenantPlugins) bindings.set(b.pluginId, b)\n const bindingsAreManaged = hasTenantBindings ?? tenantPlugins.length > 0\n\n const requested = new Set<string>()\n const activationReason = new Map<string, ResolvedPluginManifest['activationReason']>()\n\n for (const plugin of normalizedPlugins.values()) {\n const binding = bindings.get(plugin.id)\n if (binding?.status === 'active') {\n requested.add(plugin.id)\n activationReason.set(plugin.id, 'tenant')\n continue\n }\n if (plugin.defaultEnabled === true || (!bindingsAreManaged && plugin.defaultEnabled !== false)) {\n requested.add(plugin.id)\n activationReason.set(plugin.id, 'default')\n }\n }\n\n const orderedIds: string[] = []\n const visiting = new Set<string>()\n const visited = new Set<string>()\n\n function visit(pluginId: string, ancestry: string[] = []): void {\n if (visited.has(pluginId)) return\n const plugin = normalizedPlugins.get(pluginId)\n if (!plugin) return\n if (visiting.has(pluginId)) {\n issues.push({ type: 'circular_dependency', pluginId, message: `Circular dependency: ${[...ancestry, pluginId].join(' -> ')}.` })\n return\n }\n visiting.add(pluginId)\n for (const depId of plugin.dependencies ?? []) {\n if (!normalizedPlugins.has(depId)) {\n issues.push({ type: 'missing_dependency', pluginId, dependencyId: depId, message: `Plugin \"${plugin.id}\" depends on missing plugin \"${depId}\".` })\n continue\n }\n if (requested.has(pluginId) && !requested.has(depId)) {\n requested.add(depId)\n activationReason.set(depId, 'dependency')\n }\n visit(depId, [...ancestry, pluginId])\n }\n visiting.delete(pluginId)\n visited.add(pluginId)\n orderedIds.push(pluginId)\n }\n\n for (const id of normalizedPlugins.keys()) visit(id)\n\n const resolvedById = new Map<string, ResolvedPluginManifest>()\n\n for (const pluginId of orderedIds) {\n const plugin = normalizedPlugins.get(pluginId)\n if (!plugin) continue\n const binding = bindings.get(plugin.id)\n const missing = (plugin.dependencies ?? []).filter((id) => !normalizedPlugins.has(id))\n const compatible = !plugin.verticalId || plugin.verticalId === context.tenant?.verticalId\n if (!compatible) {\n issues.push({ type: 'vertical_mismatch', pluginId: plugin.id, message: `Plugin \"${plugin.id}\" requires vertical \"${plugin.verticalId}\".` })\n }\n const reason = activationReason.get(plugin.id) ?? 'inactive'\n const depsReady = (plugin.dependencies ?? []).every((id) => resolvedById.get(id)?.isActive)\n const explicitlyDisabled = binding?.status === 'disabled' || binding?.status === 'removed'\n const shouldActivate = reason === 'dependency' ? true : requested.has(plugin.id) && !explicitlyDisabled\n const isActive = shouldActivate && compatible && missing.length === 0 && depsReady\n\n resolvedById.set(plugin.id, {\n ...plugin,\n status: isActive ? 'active' : (binding?.status ?? 'disabled'),\n isActive,\n activationReason: isActive ? reason : 'inactive',\n config: binding?.config ?? {},\n missingDependencies: missing,\n settingsTabs: normalizeSettingsTabs(plugin),\n widgets: plugin.widgets ?? [],\n resolvedRegistries: plugin.registries ?? [],\n resolvedAITools: plugin.aiTools ?? [],\n })\n }\n\n const resolvedPlugins = orderedIds\n .map((id) => resolvedById.get(id))\n .filter((p): p is ResolvedPluginManifest => Boolean(p))\n\n const activePlugins = resolvedPlugins.filter((p) => p.isActive)\n const routes: PluginRuntimeRoute[] = []\n const navigation: PluginNavigationEntry[] = []\n const settingsTabs: PluginSettingsTab[] = []\n const widgets: ResolvedPluginWidget[] = []\n const dashboardWidgets: ResolvedDashboardWidget[] = []\n const capabilities: PluginCapability[] = []\n const aiTools: PluginAITool[] = []\n const registries = new Map<string, PluginRegistryDef[]>()\n const connectorsByHost = new Map<string, ConnectorDefinition[]>()\n const pluginFeatures: FeatureDeclaration[] = []\n\n for (const plugin of activePlugins) {\n routes.push(...plugin.routes.map((r) => ({ ...r, plugin })))\n navigation.push(...plugin.navigation.map((entry, i) => ({\n ...entry,\n id: entry.id ?? `${plugin.id}:${entry.route}:${i}`,\n icon: entry.icon ?? plugin.icon,\n })))\n settingsTabs.push(...plugin.settingsTabs)\n capabilities.push(...(plugin.capabilities ?? []))\n aiTools.push(...plugin.resolvedAITools)\n if (plugin.resolvedRegistries.length > 0) registries.set(plugin.id, plugin.resolvedRegistries)\n // Group each addon's connectors under the host plugin they extend.\n for (const connector of plugin.connectors ?? []) {\n const list = connectorsByHost.get(connector.hostPluginId) ?? []\n list.push(connector)\n connectorsByHost.set(connector.hostPluginId, list)\n }\n if (plugin.declaredFeatures) pluginFeatures.push(...plugin.declaredFeatures)\n widgets.push(...plugin.widgets.map((w, i) => ({\n ...w,\n order: w.order ?? i,\n config: { ...plugin.config, ...(w.props ?? {}) },\n plugin,\n })))\n dashboardWidgets.push(...(plugin.dashboardWidgets ?? []).map((w, i) => ({\n ...w,\n domain: w.domain ?? plugin.id,\n order: w.defaultOrder ?? i,\n plugin,\n })))\n }\n\n navigation.sort((a, b) => {\n const order = { main: 0, secondary: 1, settings: 2 }\n return (order[a.section] ?? 99) - (order[b.section] ?? 99) || a.position - b.position\n })\n settingsTabs.sort((a, b) => (a.order ?? 0) - (b.order ?? 0))\n widgets.sort((a, b) => a.zone !== b.zone ? a.zone.localeCompare(b.zone) : a.order - b.order)\n dashboardWidgets.sort((a, b) => a.order - b.order)\n\n return { context, plugins: resolvedPlugins, activePlugins, routes, navigation, settingsTabs, widgets, dashboardWidgets, capabilities, aiTools, issues, registries, connectorsByHost, pluginFeatures }\n}\n\nexport function getWidgetsForZone(\n runtime: PluginRuntime,\n zone: PluginWidgetZone,\n contextOverrides?: Partial<PluginRuntimeContext>,\n): ResolvedPluginWidget[] {\n const ctx = { ...runtime.context, ...contextOverrides }\n return runtime.widgets.filter((w) => w.zone === zone && isWidgetVisible(w, ctx))\n}\n\nexport function getDashboardWidgets(\n runtime: PluginRuntime,\n options: { surface: DashboardSurface; domain?: string; contextOverrides?: Partial<PluginRuntimeContext> },\n): ResolvedDashboardWidget[] {\n const ctx = { ...runtime.context, ...options.contextOverrides }\n return runtime.dashboardWidgets.filter((w) => {\n const surfaces = w.surfaces ?? ['home', 'plugin-home']\n if (!surfaces.includes(options.surface)) return false\n if (options.domain && w.domain !== options.domain) return false\n if (w.verticalId && ctx.tenant?.verticalId && w.verticalId !== ctx.tenant.verticalId) return false\n if (w.permission && ctx.hasPermission && !ctx.hasPermission(w.permission)) return false\n return true\n })\n}\n\nconst PluginRuntimeContext = React.createContext<PluginRuntime | null>(null)\nexport const PluginRuntimeProvider = PluginRuntimeContext.Provider\n\nexport function usePluginRuntime(): PluginRuntime {\n return React.useContext(PluginRuntimeContext) ?? createEmptyRuntime()\n}\n\nexport function usePluginRuntimeOptional(): PluginRuntime | null {\n return React.useContext(PluginRuntimeContext)\n}\n\n/** Connectors contributed by addon plugins that extend the given host plugin. */\nexport function useConnectorsForPlugin(hostPluginId: string): ConnectorDefinition[] {\n return usePluginRuntime().connectorsByHost.get(hostPluginId) ?? []\n}\n"]}
|
|
@@ -392,11 +392,15 @@ function createArchetypeProvider(config) {
|
|
|
392
392
|
staff_members: "v_staff"
|
|
393
393
|
};
|
|
394
394
|
const viewName = VIEW_MAP[config.projectTable] ?? `v_${config.projectTable}`;
|
|
395
|
+
const isPure = config.projectTable === ac.table;
|
|
395
396
|
return {
|
|
396
397
|
async list(query) {
|
|
397
398
|
const tenantId = config.tenantId();
|
|
398
399
|
if (!tenantId) return { data: [], total: 0 };
|
|
399
|
-
let q = getClient().from(viewName).select("*", { count: "exact" }).eq("tenant_id", tenantId);
|
|
400
|
+
let q = isPure ? coreClient().from(ac.table).select("*", { count: "exact" }).eq("tenant_id", tenantId) : getClient().from(viewName).select("*", { count: "exact" }).eq("tenant_id", tenantId);
|
|
401
|
+
if (isPure && HAS_KIND.has(config.archetype)) {
|
|
402
|
+
q = q.eq("kind", config.archetypeKind);
|
|
403
|
+
}
|
|
400
404
|
if (query.search && config.searchColumns && config.searchColumns.length > 0) {
|
|
401
405
|
const term = `%${query.search}%`;
|
|
402
406
|
const orClauses = config.searchColumns.map((col) => camelToSnake2(col)).map((col) => `${col}.ilike.${term}`);
|
|
@@ -429,14 +433,16 @@ function createArchetypeProvider(config) {
|
|
|
429
433
|
const { data: archetypeRow, error: archetypeError } = await coreClient().from(ac.table).insert(archetypeData).select().single();
|
|
430
434
|
if (archetypeError) throw archetypeError;
|
|
431
435
|
const archetypeId = archetypeRow.id;
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
436
|
+
if (!isPure) {
|
|
437
|
+
projectData[fkColumn] = archetypeId;
|
|
438
|
+
projectData.tenant_id = tenantId;
|
|
439
|
+
const { error: projectError } = await getClient().from(config.projectTable).insert(projectData);
|
|
440
|
+
if (projectError) {
|
|
441
|
+
await coreClient().from(ac.table).delete().eq("id", archetypeId);
|
|
442
|
+
throw projectError;
|
|
443
|
+
}
|
|
438
444
|
}
|
|
439
|
-
return { id: archetypeId, ...archetypeRow, ...projectData };
|
|
445
|
+
return { id: archetypeId, ...archetypeRow, ...isPure ? {} : projectData };
|
|
440
446
|
},
|
|
441
447
|
async update(id, data) {
|
|
442
448
|
const { archetypeData, projectData } = splitFields(data);
|
|
@@ -444,11 +450,14 @@ function createArchetypeProvider(config) {
|
|
|
444
450
|
const { error } = await coreClient().from(ac.table).update(archetypeData).eq("id", id);
|
|
445
451
|
if (error) throw error;
|
|
446
452
|
}
|
|
447
|
-
if (Object.keys(projectData).length > 0) {
|
|
453
|
+
if (!isPure && Object.keys(projectData).length > 0) {
|
|
448
454
|
const { error } = await getClient().from(config.projectTable).update(projectData).eq(fkColumn, id);
|
|
449
455
|
if (error) throw error;
|
|
450
456
|
}
|
|
451
457
|
const { data: archetypeRow } = await coreClient().from(ac.table).select("*").eq("id", id).single();
|
|
458
|
+
if (isPure) {
|
|
459
|
+
return mapRow2({ ...archetypeRow, id });
|
|
460
|
+
}
|
|
452
461
|
const { data: projectRow } = await getClient().from(config.projectTable).select("*").eq(fkColumn, id).single();
|
|
453
462
|
const flat = { ...archetypeRow, ...projectRow, id };
|
|
454
463
|
delete flat[fkColumn];
|
|
@@ -639,5 +648,5 @@ function resolveDataProvider(entityDef, mockData, options = {}) {
|
|
|
639
648
|
}
|
|
640
649
|
|
|
641
650
|
export { clearGlobalCache, createArchetypeProvider, createCacheStore, createFayzApiProvider, createMockProvider, createSupabaseProvider, getActiveTenantId, getSupabaseClientOptional, globalCache, resolveDataProvider, setActiveTenantId, setGlobalSupabaseClient, stableKey, withCache };
|
|
642
|
-
//# sourceMappingURL=chunk-
|
|
643
|
-
//# sourceMappingURL=chunk-
|
|
651
|
+
//# sourceMappingURL=chunk-ATLZ3SGJ.js.map
|
|
652
|
+
//# sourceMappingURL=chunk-ATLZ3SGJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/data/supabase.ts","../src/data/fayz-api.ts","../src/data/mock.ts","../src/data/archetype.ts","../src/lib/cache.ts","../src/data/cached.ts","../src/tenant/index.ts","../src/data/resolve.ts"],"names":["resolveTenantId","camelToSnake","snakeToCamel","mapRow"],"mappings":"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","file":"chunk-ATLZ3SGJ.js","sourcesContent":["import type { DataProvider, CrudQuery, CrudResult } from './types'\n\nexport interface SupabaseProviderConfig {\n schema?: string\n tenantId?: string | (() => string | undefined)\n tenantIdColumn?: string\n searchColumns?: string[]\n selectColumns?: string\n columnMap?: Record<string, string>\n filters?: Record<string, string>\n defaults?: Record<string, unknown>\n supabaseClient?: unknown\n}\n\nfunction camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (c) => '_' + c.toLowerCase())\n}\n\nfunction snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase())\n}\n\nfunction mapRow<T>(row: Record<string, unknown>, columnMap?: Record<string, string>): T {\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(row)) {\n const camelKey = columnMap?.[key] ?? snakeToCamel(key)\n result[camelKey] = value\n }\n return result as T\n}\n\nfunction mapEntity(entity: Record<string, unknown>, columnMap?: Record<string, string>): Record<string, unknown> {\n const reverseMap: Record<string, string> = {}\n if (columnMap) {\n for (const [snake, camel] of Object.entries(columnMap)) {\n reverseMap[camel] = snake\n }\n }\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(entity)) {\n if (key === 'id' || key === 'createdAt' || key === 'updatedAt' || key === 'tenantId') continue\n const snakeKey = reverseMap[key] ?? camelToSnake(key)\n result[snakeKey] = value\n }\n return result\n}\n\n// Global Supabase client registry — set once via createFayzApp\nlet _globalSupabaseClient: unknown | null = null\n\nexport function setGlobalSupabaseClient(client: unknown): void {\n _globalSupabaseClient = client\n}\n\nexport function getSupabaseClientOptional(): unknown | null {\n return _globalSupabaseClient\n}\n\nexport function createSupabaseProvider<T extends { id: string }>(\n table: string,\n config?: SupabaseProviderConfig,\n): DataProvider<T> {\n const schema = config?.schema ?? 'public'\n const tenantIdCol = config?.tenantIdColumn ?? 'tenant_id'\n const searchCols = config?.searchColumns ?? []\n const selectCols = config?.selectColumns ?? '*'\n const columnMap = config?.columnMap\n\n function resolveTenantId(): string | undefined {\n if (!config?.tenantId) return undefined\n return typeof config.tenantId === 'function' ? config.tenantId() : config.tenantId\n }\n\n function getClient() {\n const supabase = (config?.supabaseClient ?? _globalSupabaseClient) as {\n schema: (s: string) => unknown\n from: (t: string) => unknown\n } | null\n if (!supabase) throw new Error(`[@fayz-ai/core] Supabase client not available. Call createFayzApp with a provider first.`)\n return schema === 'public' ? (supabase as { from: (t: string) => unknown }) : (supabase.schema(schema) as { from: (t: string) => unknown })\n }\n\n return {\n async list(query: CrudQuery): Promise<CrudResult<T>> {\n let q = (getClient().from(table) as { select: (...args: unknown[]) => unknown })\n .select(selectCols, { count: 'exact' }) as Record<string, unknown>\n\n const tenantId = resolveTenantId()\n if (tenantId) q = (q as { eq: (col: string, val: string) => unknown }).eq(tenantIdCol, tenantId) as Record<string, unknown>\n\n if (config?.filters) {\n for (const [col, val] of Object.entries(config.filters)) {\n q = (q as { eq: (c: string, v: string) => unknown }).eq(col, val) as Record<string, unknown>\n }\n }\n\n // Faceted / dynamic filters from the query (equality, mapped to columns).\n if (query.filters) {\n for (const [key, val] of Object.entries(query.filters)) {\n if (val == null || val === '') continue\n const col = columnMap?.[key] ?? camelToSnake(key)\n q = (q as { eq: (c: string, v: unknown) => unknown }).eq(col, val) as Record<string, unknown>\n }\n }\n\n if (query.search && searchCols.length > 0) {\n const term = `%${query.search}%`\n const orClause = searchCols.map((col) => `${camelToSnake(col)}.ilike.${term}`).join(',')\n q = (q as { or: (c: string) => unknown }).or(orClause) as Record<string, unknown>\n }\n\n if (query.sortBy) {\n q = (q as { order: (col: string, opts: unknown) => unknown })\n .order(camelToSnake(query.sortBy), { ascending: query.sortDir !== 'desc' }) as Record<string, unknown>\n } else {\n q = (q as { order: (col: string, opts: unknown) => unknown })\n .order('created_at', { ascending: false }) as Record<string, unknown>\n }\n\n const page = query.page ?? 1\n const pageSize = query.pageSize ?? 50\n const from = (page - 1) * pageSize\n q = (q as { range: (f: number, t: number) => unknown }).range(from, from + pageSize - 1) as Record<string, unknown>\n\n const { data, error, count } = await q as { data: Record<string, unknown>[] | null; error: unknown; count: number | null }\n if (error) throw error\n\n return {\n data: (data ?? []).map((row) => mapRow<T>(row, columnMap)),\n total: count ?? 0,\n }\n },\n\n async create(data) {\n const row = mapEntity(data as Record<string, unknown>, columnMap)\n const tenantId = resolveTenantId()\n if (tenantId) row[tenantIdCol] = tenantId\n if (config?.defaults) {\n for (const [col, val] of Object.entries(config.defaults)) {\n if (row[col] === undefined) row[col] = val\n }\n }\n\n const { data: created, error } = (await (getClient().from(table) as {\n insert: (r: unknown) => { select: () => { single: () => Promise<{ data: unknown; error: unknown }> } }\n }).insert(row).select().single()) as { data: Record<string, unknown> | null; error: unknown }\n\n if (error) throw error\n return mapRow<T>(created!, columnMap)\n },\n\n async update(id, data) {\n const row = mapEntity(data as Record<string, unknown>, columnMap)\n const { data: updated, error } = (await (getClient().from(table) as {\n update: (r: unknown) => { eq: (c: string, v: string) => { select: () => { single: () => Promise<{ data: unknown; error: unknown }> } } }\n }).update(row).eq('id', id).select().single()) as { data: Record<string, unknown> | null; error: unknown }\n\n if (error) throw error\n return mapRow<T>(updated!, columnMap)\n },\n\n async remove(id) {\n const { error } = (await (getClient().from(table) as {\n delete: () => { eq: (c: string, v: string) => Promise<{ error: unknown }> }\n }).delete().eq('id', id)) as { error: unknown }\n if (error) throw error\n },\n }\n}\n","import type { CrudQuery, CrudResult, DataProvider } from './types'\n\ntype FayzApiFilterOperator = 'eq' | 'neq' | 'gt' | 'lt' | 'gte' | 'lte' | 'like' | 'ilike' | 'is_null' | 'is_not_null'\n\ninterface FayzApiTableFilter {\n column: string\n operator: FayzApiFilterOperator\n value?: unknown\n}\n\nexport interface FayzApiProviderConfig {\n baseUrl?: string\n projectId?: string\n tenantId?: string | (() => string | undefined)\n tenantIdColumn?: string | false\n entityKey?: string\n table?: string\n schema?: string\n idColumn?: string\n searchColumns?: string[]\n runtimeToken?: string | (() => string | undefined | Promise<string | undefined>)\n headers?: () => HeadersInit | Promise<HeadersInit>\n fetcher?: typeof fetch\n}\n\nfunction resolveTenantId(config?: FayzApiProviderConfig): string | undefined {\n const tenantId = config?.tenantId\n return typeof tenantId === 'function' ? tenantId() : tenantId\n}\n\nasync function resolveRuntimeToken(config?: FayzApiProviderConfig): Promise<string | undefined> {\n const runtimeToken = config?.runtimeToken\n return typeof runtimeToken === 'function' ? runtimeToken() : runtimeToken\n}\n\nfunction trimTrailingSlash(value: string): string {\n return value.replace(/\\/+$/, '')\n}\n\nfunction appendQuery(\n url: URL,\n query: CrudQuery,\n tenantId?: string,\n tenantIdColumn = 'tenant_id',\n searchColumns: string[] = [],\n): void {\n const filters = normalizeFilters(query.filters)\n if (query.search && searchColumns[0]) {\n filters.push({ column: searchColumns[0], operator: 'ilike', value: `%${query.search}%` })\n }\n if (query.sortBy) url.searchParams.set('sortColumn', query.sortBy)\n if (query.sortDir) url.searchParams.set('sortDirection', query.sortDir)\n if (query.page != null) url.searchParams.set('page', String(query.page))\n if (query.pageSize != null) url.searchParams.set('limit', String(query.pageSize))\n if (tenantId) filters.push({ column: tenantIdColumn, operator: 'eq', value: tenantId })\n if (filters.length > 0) url.searchParams.set('filters', JSON.stringify(filters))\n}\n\nasync function parseResponse<T>(response: Response): Promise<T> {\n if (!response.ok) {\n const text = await response.text().catch(() => '')\n throw new Error(`[@fayz-ai/core] Fayz API request failed (${response.status}): ${text || response.statusText}`)\n }\n return response.json() as Promise<T>\n}\n\nfunction isFilterOperator(value: unknown): value is FayzApiFilterOperator {\n return typeof value === 'string' && [\n 'eq',\n 'neq',\n 'gt',\n 'lt',\n 'gte',\n 'lte',\n 'like',\n 'ilike',\n 'is_null',\n 'is_not_null',\n ].includes(value)\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction normalizeFilters(filters?: Record<string, unknown>): FayzApiTableFilter[] {\n if (!filters) return []\n return Object.entries(filters).map(([column, raw]) => {\n if (isRecord(raw) && isFilterOperator(raw.operator)) {\n return { column, operator: raw.operator, value: raw.value }\n }\n return { column, operator: 'eq', value: raw }\n })\n}\n\nexport function createFayzApiProvider<T extends { id: string }>(\n entityOrTable: string,\n config: FayzApiProviderConfig = {},\n): DataProvider<T> {\n const fetcher = config.fetcher ?? fetch\n const baseUrl = trimTrailingSlash(config.baseUrl ?? '')\n const projectId = config.projectId\n const table = config.table ?? entityOrTable\n const idColumn = config.idColumn ?? 'id'\n\n async function headers(runtimeToken?: string): Promise<HeadersInit> {\n return {\n 'Content-Type': 'application/json',\n ...(config.headers ? await config.headers() : {}),\n ...(runtimeToken ? { Authorization: `Bearer ${runtimeToken}` } : {}),\n }\n }\n\n function tableRowsUrl(runtime = false): URL {\n const prefix = baseUrl || (typeof window !== 'undefined' ? window.location.origin : 'http://localhost')\n const encodedProjectId = encodeURIComponent(projectId ?? 'current')\n const encodedTable = encodeURIComponent(table)\n const route = runtime\n ? `/api/v1/runtime/projects/${encodedProjectId}/database/tables/${encodedTable}/rows`\n : `/api/projects/${encodedProjectId}/database/tables/${encodedTable}/rows`\n const url = new URL(route, prefix)\n if (config.schema) url.searchParams.set('schema', config.schema)\n return url\n }\n\n function withTenant(data: Record<string, unknown>, runtime = false): Record<string, unknown> {\n if (runtime) return data\n const tenantId = resolveTenantId(config)\n if (!tenantId || config.tenantIdColumn === false) return data\n return { ...data, [config.tenantIdColumn ?? 'tenant_id']: tenantId }\n }\n\n function primaryKeys(id: string): Record<string, unknown> {\n return { [idColumn]: id }\n }\n\n async function listRows(query: CrudQuery): Promise<CrudResult<T>> {\n const runtimeToken = await resolveRuntimeToken(config)\n const runtime = Boolean(runtimeToken)\n const url = tableRowsUrl(runtime)\n appendQuery(\n url,\n query,\n runtime || config.tenantIdColumn === false ? undefined : resolveTenantId(config),\n config.tenantIdColumn || undefined,\n config.searchColumns,\n )\n const result = await parseResponse<{ rows: T[]; total: number }>(await fetcher(url, { headers: await headers(runtimeToken) }))\n return { data: result.rows, total: result.total }\n }\n\n async function assertTenantScopedRowExists(id: string, runtime = false): Promise<void> {\n if (runtime) return\n const tenantId = config.tenantIdColumn === false ? undefined : resolveTenantId(config)\n if (!tenantId) return\n\n const result = await listRows({ filters: { [idColumn]: id }, page: 1, pageSize: 1 })\n if (result.data.length === 0) {\n throw new Error(`[@fayz-ai/core] Row \"${id}\" was not found for the active tenant.`)\n }\n }\n\n return {\n async list(query: CrudQuery): Promise<CrudResult<T>> {\n return listRows(query)\n },\n\n async create(data) {\n const runtimeToken = await resolveRuntimeToken(config)\n const runtime = Boolean(runtimeToken)\n return parseResponse<T>(await fetcher(tableRowsUrl(runtime), {\n method: 'POST',\n headers: await headers(runtimeToken),\n body: JSON.stringify(withTenant(data as Record<string, unknown>, runtime)),\n }))\n },\n\n async update(id, data) {\n const runtimeToken = await resolveRuntimeToken(config)\n const runtime = Boolean(runtimeToken)\n await assertTenantScopedRowExists(id, runtime)\n return parseResponse<T>(await fetcher(tableRowsUrl(runtime), {\n method: 'PATCH',\n headers: await headers(runtimeToken),\n body: JSON.stringify({ primaryKeys: primaryKeys(id), data }),\n }))\n },\n\n async remove(id) {\n const runtimeToken = await resolveRuntimeToken(config)\n const runtime = Boolean(runtimeToken)\n await assertTenantScopedRowExists(id, runtime)\n await parseResponse<{ deletedCount: number }>(await fetcher(tableRowsUrl(runtime), {\n method: 'DELETE',\n headers: await headers(runtimeToken),\n body: JSON.stringify({ rows: [primaryKeys(id)] }),\n }))\n },\n }\n}\n","import type { DataProvider, CrudQuery, CrudResult } from './types'\nimport type { EntityDef } from '../types/crud'\n\nexport function createMockProvider<T extends { id: string; [key: string]: unknown }>(\n entityDefOrSearchKeys: EntityDef<T> | string[],\n initialData: T[] = [],\n): DataProvider<T> {\n let items = [...initialData]\n\n const searchableKeys = Array.isArray(entityDefOrSearchKeys)\n ? entityDefOrSearchKeys\n : entityDefOrSearchKeys.fields.filter((f) => f.searchable).map((f) => f.key)\n\n const defaultSort = Array.isArray(entityDefOrSearchKeys) ? undefined : entityDefOrSearchKeys.defaultSort\n const defaultSortDir = Array.isArray(entityDefOrSearchKeys) ? 'asc' : (entityDefOrSearchKeys.defaultSortDir ?? 'asc')\n\n return {\n async list(query: CrudQuery): Promise<CrudResult<T>> {\n let filtered = [...items]\n\n if (query.search && searchableKeys.length > 0) {\n const term = query.search.toLowerCase()\n filtered = filtered.filter((item) =>\n searchableKeys.some((key) => {\n const val = item[key]\n return typeof val === 'string' && val.toLowerCase().includes(term)\n }),\n )\n }\n\n // Faceted / dynamic filters (equality match per key).\n if (query.filters) {\n for (const [key, val] of Object.entries(query.filters)) {\n if (val == null || val === '') continue\n filtered = filtered.filter((item) => item[key] === val)\n }\n }\n\n const sortBy = query.sortBy ?? defaultSort\n const sortDir = query.sortDir ?? defaultSortDir\n if (sortBy) {\n filtered.sort((a, b) => {\n const av = a[sortBy] ?? ''\n const bv = b[sortBy] ?? ''\n const cmp = typeof av === 'number' && typeof bv === 'number'\n ? av - bv\n : String(av).localeCompare(String(bv))\n return sortDir === 'desc' ? -cmp : cmp\n })\n }\n\n const total = filtered.length\n const page = query.page ?? 1\n const pageSize = query.pageSize ?? 50\n const start = (page - 1) * pageSize\n const data = filtered.slice(start, start + pageSize)\n return { data, total }\n },\n\n async create(data) {\n const now = new Date().toISOString()\n const item = {\n ...data,\n id: crypto.randomUUID(),\n tenantId: 'mock-tenant',\n createdAt: now,\n updatedAt: now,\n } as unknown as T\n items.unshift(item)\n return item\n },\n\n async update(id, data) {\n const idx = items.findIndex((i) => i.id === id)\n if (idx === -1) throw new Error(`[@fayz-ai/core] Mock provider: item not found: ${id}`)\n items[idx] = { ...items[idx], ...data, updatedAt: new Date().toISOString() }\n return items[idx]!\n },\n\n async remove(id) {\n items = items.filter((i) => i.id !== id)\n },\n }\n}\n","import type { DataProvider, CrudQuery, CrudResult } from './types'\nimport { getSupabaseClientOptional } from './supabase'\nimport type { EntityArchetype } from '../types/entities'\n\n// Archetypes that have a `kind` discriminator column\nconst HAS_KIND = new Set<EntityArchetype>(['person', 'category', 'order', 'transaction', 'schedule', 'location'])\n\nconst ARCHETYPE_CONFIG: Record<EntityArchetype, { table: string; fkColumn: string }> = {\n person: { table: 'persons', fkColumn: 'person_id' },\n category: { table: 'categories', fkColumn: 'category_id' },\n product: { table: 'products', fkColumn: 'product_id' },\n service: { table: 'services', fkColumn: 'service_id' },\n location: { table: 'locations', fkColumn: 'location_id' },\n order: { table: 'orders', fkColumn: 'order_id' },\n transaction: { table: 'transactions', fkColumn: 'transaction_id' },\n\n schedule: { table: 'schedules', fkColumn: 'schedule_id' },\n}\n\nconst ARCHETYPE_COLUMNS: Record<EntityArchetype, Set<string>> = {\n person: new Set(['name', 'email', 'phone', 'document_number', 'avatar_url', 'date_of_birth', 'address', 'city', 'state', 'country', 'postal_code', 'tags', 'is_active', 'notes', 'metadata']),\n category: new Set(['name', 'slug', 'parent_id', 'icon', 'color', 'sort_order', 'is_active', 'metadata']),\n product: new Set(['name', 'description', 'sku', 'price', 'cost', 'currency', 'unit', 'image_url', 'stock', 'min_stock', 'status', 'is_active', 'tags', 'metadata', 'category_id']),\n service: new Set(['name', 'description', 'price', 'cost', 'currency', 'duration_minutes', 'image_url', 'status', 'is_active', 'tags', 'metadata', 'category_id']),\n location: new Set(['name', 'email', 'phone', 'address', 'city', 'state', 'country', 'postal_code', 'is_headquarters', 'is_active', 'tags', 'notes', 'metadata']),\n order: new Set(['reference_number', 'status', 'party_id', 'assignee_id', 'location_id', 'subtotal', 'discount', 'tax', 'total', 'currency', 'due_at', 'completed_at', 'notes', 'tags', 'metadata']),\n transaction: new Set(['order_id', 'party_id', 'amount', 'currency', 'payment_method', 'reference', 'status', 'transacted_at', 'notes', 'metadata']),\n\n schedule: new Set(['assignee_id', 'location_id', 'day_of_week', 'specific_date', 'starts_at', 'ends_at', 'is_active', 'metadata']),\n}\n\nfunction camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (c) => '_' + c.toLowerCase())\n}\n\nfunction snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, c) => c.toUpperCase())\n}\n\nfunction mapRow<T>(row: Record<string, unknown>): T {\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(row)) {\n result[snakeToCamel(key)] = value\n }\n return result as T\n}\n\nexport interface ArchetypeProviderConfig {\n archetype: EntityArchetype\n archetypeKind: string\n projectTable: string\n tenantId: () => string | undefined\n searchColumns?: string[]\n}\n\nexport function createArchetypeProvider<T extends { id: string }>(\n config: ArchetypeProviderConfig,\n): DataProvider<T> {\n const ac = ARCHETYPE_CONFIG[config.archetype]\n const archetypeColumns = ARCHETYPE_COLUMNS[config.archetype]\n const { fkColumn } = ac\n\n function getClient() {\n const supabase = getSupabaseClientOptional() as any\n if (!supabase) throw new Error('Supabase client not available')\n return supabase\n }\n\n function coreClient() {\n return getClient().schema('saas_core')\n }\n\n function splitFields(data: Record<string, unknown>): { archetypeData: Record<string, unknown>; projectData: Record<string, unknown> } {\n const archetypeData: Record<string, unknown> = {}\n const projectData: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(data)) {\n if (['id', 'createdAt', 'updatedAt', 'tenantId', fkColumn].includes(key)) continue\n const snakeKey = camelToSnake(key)\n if (archetypeColumns.has(snakeKey)) {\n archetypeData[snakeKey] = value\n } else {\n projectData[snakeKey] = value\n }\n }\n return { archetypeData, projectData }\n }\n\n // View name convention: v_{shortName} — maps project table to its view\n const VIEW_MAP: Record<string, string> = {\n clients: 'v_clients',\n staff_members: 'v_staff',\n }\n const viewName = VIEW_MAP[config.projectTable] ?? `v_${config.projectTable}`\n\n // Pure-archetype entity: the project table IS the archetype base (e.g. a\n // customers list configured with `table: 'persons'`, no separate public\n // extension table). Read/write saas_core.<base> directly — there is no public\n // extension row and no v_ view to join. Extension-table entities (clients,\n // staff_members, …) are unaffected.\n const isPure = config.projectTable === ac.table\n\n return {\n async list(query: CrudQuery): Promise<CrudResult<T>> {\n const tenantId = config.tenantId()\n if (!tenantId) return { data: [], total: 0 }\n\n // Pure archetype → read saas_core.<base> directly (filtered by kind);\n // otherwise the v_ view (JOINs public extension with saas_core archetype).\n let q = isPure\n ? coreClient().from(ac.table).select('*', { count: 'exact' }).eq('tenant_id', tenantId)\n : getClient().from(viewName).select('*', { count: 'exact' }).eq('tenant_id', tenantId)\n\n if (isPure && HAS_KIND.has(config.archetype)) {\n q = q.eq('kind', config.archetypeKind)\n }\n\n // Search\n if (query.search && config.searchColumns && config.searchColumns.length > 0) {\n const term = `%${query.search}%`\n const orClauses = config.searchColumns\n .map((col) => camelToSnake(col))\n .map((col) => `${col}.ilike.${term}`)\n if (orClauses.length > 0) {\n q = q.or(orClauses.join(','))\n }\n }\n\n // Sort\n if (query.sortBy) {\n q = q.order(camelToSnake(query.sortBy), { ascending: query.sortDir !== 'desc' })\n } else {\n q = q.order('created_at', { ascending: false })\n }\n\n // Pagination\n const page = query.page ?? 1\n const pageSize = query.pageSize ?? 50\n const from = (page - 1) * pageSize\n q = q.range(from, from + pageSize - 1)\n\n const { data, error, count } = await q\n if (error) throw error\n\n const rows = (data ?? []).map((row: Record<string, unknown>) => mapRow<T>(row))\n return { data: rows, total: count ?? 0 }\n },\n\n async create(data) {\n const tenantId = config.tenantId()\n if (!tenantId) throw new Error('No tenant selected')\n\n const { archetypeData, projectData } = splitFields(data as Record<string, unknown>)\n\n // 1. Insert into archetype table\n archetypeData.tenant_id = tenantId\n if (HAS_KIND.has(config.archetype)) {\n archetypeData.kind = config.archetypeKind\n }\n\n const { data: archetypeRow, error: archetypeError } = await coreClient()\n .from(ac.table)\n .insert(archetypeData)\n .select()\n .single()\n\n if (archetypeError) throw archetypeError\n const archetypeId = (archetypeRow as any).id\n\n // 2. Insert into project table with archetype FK as PK.\n // Pure-archetype entities have no extension table — skip this step.\n if (!isPure) {\n projectData[fkColumn] = archetypeId\n projectData.tenant_id = tenantId\n\n const { error: projectError } = await getClient()\n .from(config.projectTable)\n .insert(projectData)\n\n if (projectError) {\n await coreClient().from(ac.table).delete().eq('id', archetypeId)\n throw projectError\n }\n }\n\n return { id: archetypeId, ...archetypeRow, ...(isPure ? {} : projectData) } as unknown as T\n },\n\n async update(id, data) {\n const { archetypeData, projectData } = splitFields(data as Record<string, unknown>)\n\n if (Object.keys(archetypeData).length > 0) {\n const { error } = await coreClient()\n .from(ac.table)\n .update(archetypeData)\n .eq('id', id)\n if (error) throw error\n }\n\n if (!isPure && Object.keys(projectData).length > 0) {\n const { error } = await getClient()\n .from(config.projectTable)\n .update(projectData)\n .eq(fkColumn, id)\n if (error) throw error\n }\n\n // Re-fetch (archetype only for pure entities; otherwise join the extension)\n const { data: archetypeRow } = await coreClient().from(ac.table).select('*').eq('id', id).single()\n if (isPure) {\n return mapRow<T>({ ...archetypeRow, id } as Record<string, unknown>)\n }\n const { data: projectRow } = await getClient().from(config.projectTable).select('*').eq(fkColumn, id).single()\n\n const flat = { ...archetypeRow, ...projectRow, id }\n delete (flat as any)[fkColumn]\n return mapRow<T>(flat as Record<string, unknown>)\n },\n\n async remove(id) {\n const { error } = await coreClient()\n .from(ac.table)\n .delete()\n .eq('id', id)\n if (error) throw error\n },\n }\n}\n","// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface CacheEntry<T = unknown> {\n data: T\n expiresAt: number\n lastAccess: number\n}\n\nexport interface CacheStore {\n get<T>(key: string): T | undefined\n set<T>(key: string, data: T, ttl?: number): void\n /** Clear all entries whose key starts with `prefix` */\n invalidate(prefix: string): void\n clear(): void\n size(): number\n}\n\nexport interface CacheConfig {\n /** Default time-to-live in ms (default: 60 000 — 1 minute) */\n defaultTTL?: number\n /** Maximum cached entries before LRU eviction (default: 500) */\n maxEntries?: number\n}\n\n// ---------------------------------------------------------------------------\n// Stable key helper — deterministic JSON for cache keys\n// ---------------------------------------------------------------------------\n\nfunction sortDeep(value: unknown): unknown {\n if (value === null || value === undefined || typeof value !== 'object') return value\n if (Array.isArray(value)) return value.map(sortDeep)\n const sorted: Record<string, unknown> = {}\n for (const k of Object.keys(value as Record<string, unknown>).sort()) {\n sorted[k] = sortDeep((value as Record<string, unknown>)[k])\n }\n return sorted\n}\n\nexport function stableKey(...parts: unknown[]): string {\n return parts.map((p) => (typeof p === 'string' ? p : JSON.stringify(sortDeep(p)))).join(':')\n}\n\n// ---------------------------------------------------------------------------\n// CacheStore implementation\n// ---------------------------------------------------------------------------\n\nexport function createCacheStore(config?: CacheConfig): CacheStore {\n const defaultTTL = config?.defaultTTL ?? 60_000\n const maxEntries = config?.maxEntries ?? 500\n const entries = new Map<string, CacheEntry>()\n\n function evictLRU() {\n if (entries.size <= maxEntries) return\n // Find the entry with the oldest lastAccess\n let oldestKey: string | null = null\n let oldestAccess = Infinity\n for (const [key, entry] of entries) {\n if (entry.lastAccess < oldestAccess) {\n oldestAccess = entry.lastAccess\n oldestKey = key\n }\n }\n if (oldestKey) entries.delete(oldestKey)\n }\n\n return {\n get<T>(key: string): T | undefined {\n const entry = entries.get(key)\n if (!entry) return undefined\n if (Date.now() > entry.expiresAt) {\n entries.delete(key)\n return undefined\n }\n entry.lastAccess = Date.now()\n return entry.data as T\n },\n\n set<T>(key: string, data: T, ttl?: number): void {\n const now = Date.now()\n entries.set(key, {\n data,\n expiresAt: now + (ttl ?? defaultTTL),\n lastAccess: now,\n })\n evictLRU()\n },\n\n invalidate(prefix: string): void {\n for (const key of entries.keys()) {\n if (key.startsWith(prefix)) {\n entries.delete(key)\n }\n }\n },\n\n clear(): void {\n entries.clear()\n },\n\n size(): number {\n return entries.size\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Global singleton — auto-flushes on tenant/org switch\n// ---------------------------------------------------------------------------\n\nexport const globalCache = createCacheStore()\n\n/** Flush the global cache — called by the tenant accessor when the active\n * tenant changes (replaces the old org-store subscription). */\nexport function clearGlobalCache(): void {\n globalCache.clear()\n}\n","import type { DataProvider, CrudQuery, CrudResult } from './types'\nimport { globalCache, stableKey } from '../lib/cache'\n\nexport interface ProviderCacheOptions {\n /** Table/entity name — used as cache key namespace */\n table: string\n /** Dynamic tenant ID resolver */\n tenantId: () => string | undefined\n /** Override default TTL for this entity (ms) */\n ttl?: number\n}\n\n/**\n * Wraps a DataProvider with transparent read caching + mutation invalidation.\n *\n * - `list()` results are cached by query params\n * - `create()`, `update()`, `remove()` invalidate all cached entries for the table\n */\nexport function withCache<T extends { id: string }>(\n provider: DataProvider<T>,\n options: ProviderCacheOptions,\n): DataProvider<T> {\n function prefix(): string {\n return `${options.tenantId() ?? '_'}:${options.table}`\n }\n\n return {\n async list(query: CrudQuery): Promise<CrudResult<T>> {\n const key = `${prefix()}:${stableKey(query)}`\n const cached = globalCache.get<CrudResult<T>>(key)\n if (cached) return cached\n\n const result = await provider.list(query)\n globalCache.set(key, result, options.ttl)\n return result\n },\n\n async create(data) {\n const result = await provider.create(data)\n globalCache.invalidate(prefix())\n return result\n },\n\n async update(id, data) {\n const result = await provider.update(id, data)\n globalCache.invalidate(prefix())\n return result\n },\n\n async remove(id) {\n await provider.remove(id)\n globalCache.invalidate(prefix())\n },\n }\n}\n","// Active tenant context — a global accessor the data layer reads for tenant\n// scoping and cache keying. The host (saas shell / app) sets it from its org\n// store via setActiveTenantId; the data providers stay decoupled from any\n// specific org-store implementation (runtime DI).\nimport { clearGlobalCache } from '../lib/cache'\n\nlet _activeTenantId: string | undefined\n\nexport function setActiveTenantId(id: string | undefined): void {\n if (id !== _activeTenantId) {\n _activeTenantId = id\n clearGlobalCache()\n }\n}\n\nexport function getActiveTenantId(): string | undefined {\n return _activeTenantId\n}\n","import type { EntityDef } from '../types/crud'\nimport type { BackendRef } from '../manifest'\nimport type { DataProvider } from './types'\nimport { getSupabaseClientOptional } from './supabase'\nimport { createSupabaseProvider } from './supabase'\nimport { createArchetypeProvider } from './archetype'\nimport { createMockProvider } from './mock'\nimport { createFayzApiProvider, type FayzApiProviderConfig } from './fayz-api'\nimport { withCache } from './cached'\nimport { getActiveTenantId } from '../tenant'\n\n/**\n * Resolve the best data provider for an EntityDef.\n * Supabase → Archetype → Mock (in order of preference).\n *\n * Reusable by createCrudPage, PluginRegistryManager, or any component\n * that needs a DataProvider from an EntityDef.\n */\nexport interface ResolveDataProviderOptions {\n backend?: BackendRef\n fayzApi?: Omit<FayzApiProviderConfig, 'entityKey' | 'table'>\n customProviders?: Record<string, <T extends { id: string }>(entityDef: EntityDef<T>, mockData?: T[]) => DataProvider<T>>\n}\n\nexport function resolveDataProvider<T extends { id: string }>(\n entityDef: EntityDef<T>,\n mockData?: T[],\n options: ResolveDataProviderOptions = {},\n): DataProvider<T> {\n const backend = options.backend\n\n if (backend?.provider === 'mock') {\n return createMockProvider(entityDef, mockData)\n }\n\n if (backend?.provider === 'fayz-api') {\n const table = entityDef.data?.table ?? entityDef.name\n return createFayzApiProvider<T>(table, {\n ...options.fayzApi,\n baseUrl: options.fayzApi?.baseUrl ?? backend.url,\n projectId: options.fayzApi?.projectId ?? backend.projectRef,\n entityKey: entityDef.name ?? table,\n table,\n schema: options.fayzApi?.schema ?? entityDef.data?.schema,\n idColumn: options.fayzApi?.idColumn ?? entityDef.data?.columnMap?.id,\n searchColumns: options.fayzApi?.searchColumns ?? entityDef.data?.searchColumns ?? entityDef.fields\n .filter((field) => field.searchable)\n .map((field) => field.key),\n tenantIdColumn: entityDef.data?.tenantScoped === false\n ? false\n : options.fayzApi?.tenantIdColumn ?? entityDef.data?.tenantIdColumn,\n tenantId: options.fayzApi?.tenantId ?? (() => getActiveTenantId()),\n })\n }\n\n if (backend?.provider === 'custom') {\n const adapterId = backend.adapterId\n const factory = adapterId ? options.customProviders?.[adapterId] : undefined\n if (!adapterId || !factory) {\n throw new Error(`[@fayz-ai/core] Custom data provider \"${adapterId ?? 'unknown'}\" is not registered.`)\n }\n return factory<T>(entityDef, mockData)\n }\n\n const client = getSupabaseClientOptional()\n\n if (client && entityDef.data?.table) {\n const tenantId = () => getActiveTenantId()\n const cacheOptions = {\n table: entityDef.data.table,\n tenantId,\n ttl: entityDef.data.cacheTTL,\n }\n\n if (entityDef.data.archetype && entityDef.data.archetypeKind && !entityDef.data.schema) {\n return withCache(createArchetypeProvider<T>({\n archetype: entityDef.data.archetype,\n archetypeKind: entityDef.data.archetypeKind,\n projectTable: entityDef.data.table,\n tenantId,\n searchColumns: entityDef.data.searchColumns ?? entityDef.fields\n .filter((field) => field.searchable)\n .map((field) => field.key),\n }), cacheOptions)\n }\n\n return withCache(createSupabaseProvider<T>(entityDef.data.table, {\n schema: entityDef.data.schema,\n tenantId: entityDef.data.tenantScoped === false ? undefined : tenantId,\n tenantIdColumn: entityDef.data.tenantIdColumn,\n searchColumns: entityDef.data.searchColumns ?? entityDef.fields\n .filter((field) => field.searchable)\n .map((field) => field.key),\n selectColumns: entityDef.data.selectColumns,\n columnMap: entityDef.data.columnMap,\n filters: entityDef.data.filters,\n defaults: entityDef.data.defaults,\n }), cacheOptions)\n }\n\n if (entityDef.data?.table) {\n console.warn(\n `[fayz/core] resolveDataProvider: falling back to mock for \"${entityDef.name}\" (table: ${entityDef.data.table}). ` +\n `Supabase client ${client ? 'available' : 'NOT initialized'}.`,\n )\n }\n return createMockProvider(entityDef, mockData)\n}\n"]}
|
|
@@ -120,6 +120,7 @@ function createEmptyRuntime(context = EMPTY_CONTEXT) {
|
|
|
120
120
|
capabilities: [],
|
|
121
121
|
aiTools: [],
|
|
122
122
|
registries: /* @__PURE__ */ new Map(),
|
|
123
|
+
connectorsByHost: /* @__PURE__ */ new Map(),
|
|
123
124
|
pluginFeatures: [],
|
|
124
125
|
issues: []
|
|
125
126
|
};
|
|
@@ -145,7 +146,7 @@ function resolvePluginRuntime({
|
|
|
145
146
|
issues.push({
|
|
146
147
|
type: "incompatible_api_version",
|
|
147
148
|
pluginId: plugin.id,
|
|
148
|
-
message: `Plugin "${plugin.id}" requires plugin API v${plugin.apiVersion}, but this runtime supports v${PLUGIN_API_VERSION}. Upgrade @fayz-ai/
|
|
149
|
+
message: `Plugin "${plugin.id}" requires plugin API v${plugin.apiVersion}, but this runtime supports v${PLUGIN_API_VERSION}. Upgrade @fayz-ai/core.`
|
|
149
150
|
});
|
|
150
151
|
continue;
|
|
151
152
|
}
|
|
@@ -234,6 +235,7 @@ function resolvePluginRuntime({
|
|
|
234
235
|
const capabilities = [];
|
|
235
236
|
const aiTools = [];
|
|
236
237
|
const registries = /* @__PURE__ */ new Map();
|
|
238
|
+
const connectorsByHost = /* @__PURE__ */ new Map();
|
|
237
239
|
const pluginFeatures = [];
|
|
238
240
|
for (const plugin of activePlugins) {
|
|
239
241
|
routes.push(...plugin.routes.map((r) => ({ ...r, plugin })));
|
|
@@ -246,6 +248,11 @@ function resolvePluginRuntime({
|
|
|
246
248
|
capabilities.push(...plugin.capabilities ?? []);
|
|
247
249
|
aiTools.push(...plugin.resolvedAITools);
|
|
248
250
|
if (plugin.resolvedRegistries.length > 0) registries.set(plugin.id, plugin.resolvedRegistries);
|
|
251
|
+
for (const connector of plugin.connectors ?? []) {
|
|
252
|
+
const list = connectorsByHost.get(connector.hostPluginId) ?? [];
|
|
253
|
+
list.push(connector);
|
|
254
|
+
connectorsByHost.set(connector.hostPluginId, list);
|
|
255
|
+
}
|
|
249
256
|
if (plugin.declaredFeatures) pluginFeatures.push(...plugin.declaredFeatures);
|
|
250
257
|
widgets.push(...plugin.widgets.map((w, i) => ({
|
|
251
258
|
...w,
|
|
@@ -267,7 +274,7 @@ function resolvePluginRuntime({
|
|
|
267
274
|
settingsTabs.sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
|
|
268
275
|
widgets.sort((a, b) => a.zone !== b.zone ? a.zone.localeCompare(b.zone) : a.order - b.order);
|
|
269
276
|
dashboardWidgets.sort((a, b) => a.order - b.order);
|
|
270
|
-
return { context, plugins: resolvedPlugins, activePlugins, routes, navigation, settingsTabs, widgets, dashboardWidgets, capabilities, aiTools, issues, registries, pluginFeatures };
|
|
277
|
+
return { context, plugins: resolvedPlugins, activePlugins, routes, navigation, settingsTabs, widgets, dashboardWidgets, capabilities, aiTools, issues, registries, connectorsByHost, pluginFeatures };
|
|
271
278
|
}
|
|
272
279
|
function getWidgetsForZone(runtime, zone, contextOverrides) {
|
|
273
280
|
const ctx = { ...runtime.context, ...contextOverrides };
|
|
@@ -292,7 +299,10 @@ function usePluginRuntime() {
|
|
|
292
299
|
function usePluginRuntimeOptional() {
|
|
293
300
|
return React.useContext(PluginRuntimeContext);
|
|
294
301
|
}
|
|
302
|
+
function useConnectorsForPlugin(hostPluginId) {
|
|
303
|
+
return usePluginRuntime().connectorsByHost.get(hostPluginId) ?? [];
|
|
304
|
+
}
|
|
295
305
|
|
|
296
|
-
export { PLUGIN_API_VERSION, PluginRuntimeProvider, Registry, blockRegistry, componentRegistry, definePlugin, getBlock, getComponent, getDashboardWidgets, getMetric, getPage, getPlugin, getPluginFactory, getScaffold, getWidgetsForZone, isCustomId, listBlocks, listMetrics, listPluginFactories, listPlugins, metricRegistry, pageRegistry, pluginFactoryRegistry, pluginRegistry, registerBlock, registerComponent, registerMetric, registerPage, registerPlugin, registerPluginFactory, registerScaffold, resolvePluginComponent, resolvePluginRuntime, scaffoldRegistry, usePluginRuntime, usePluginRuntimeOptional };
|
|
297
|
-
//# sourceMappingURL=chunk-
|
|
298
|
-
//# sourceMappingURL=chunk-
|
|
306
|
+
export { PLUGIN_API_VERSION, PluginRuntimeProvider, Registry, blockRegistry, componentRegistry, definePlugin, getBlock, getComponent, getDashboardWidgets, getMetric, getPage, getPlugin, getPluginFactory, getScaffold, getWidgetsForZone, isCustomId, listBlocks, listMetrics, listPluginFactories, listPlugins, metricRegistry, pageRegistry, pluginFactoryRegistry, pluginRegistry, registerBlock, registerComponent, registerMetric, registerPage, registerPlugin, registerPluginFactory, registerScaffold, resolvePluginComponent, resolvePluginRuntime, scaffoldRegistry, useConnectorsForPlugin, usePluginRuntime, usePluginRuntimeOptional };
|
|
307
|
+
//# sourceMappingURL=chunk-CHGX6UYR.js.map
|
|
308
|
+
//# sourceMappingURL=chunk-CHGX6UYR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/registry/index.ts","../src/plugin/runtime.ts"],"names":[],"mappings":";;;AAuCO,IAAM,WAAN,MAAkB;AAAA,EAGvB,YAAqB,IAAA,EAAc;AAAd,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAFrB,IAAA,IAAA,CAAiB,OAAA,uBAAc,GAAA,EAA8B;AAAA,EAEzB;AAAA,EAEpC,QAAA,CAAS,EAAA,EAAY,KAAA,EAAU,IAAA,GAAqB,EAAC,EAAS;AAC5D,IAAA,IAAA,CAAK,QAAQ,GAAA,CAAI,EAAA,EAAI,EAAE,EAAA,EAAI,KAAA,EAAO,MAAM,CAAA;AAAA,EAC1C;AAAA,EAEA,IAAI,EAAA,EAA2B;AAC7B,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA,EAAG,KAAA;AAAA,EAC/B;AAAA,EAEA,SAAS,EAAA,EAA0C;AACjD,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA;AAAA,EAC5B;AAAA,EAEA,IAAI,EAAA,EAAqB;AACvB,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA;AAAA,EAC5B;AAAA,EAEA,IAAA,GAA2B;AACzB,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,OAAA,CAAQ,QAAQ,CAAA;AAAA,EACzC;AAAA,EAEA,GAAA,GAAgB;AACd,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,OAAA,CAAQ,MAAM,CAAA;AAAA,EACvC;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AAAA,EACrB;AACF;AAGO,SAAS,WAAW,EAAA,EAAqB;AAC9C,EAAA,OAAO,EAAA,CAAG,WAAW,SAAS,CAAA;AAChC;AAsCO,IAAM,iBAAA,GAAoB,IAAI,QAAA,CAAuB,WAAW;AAChE,IAAM,aAAA,GAAgB,IAAI,QAAA,CAAuB,OAAO;AACxD,IAAM,YAAA,GAAe,IAAI,QAAA,CAAuB,MAAM;AACtD,IAAM,gBAAA,GAAmB,IAAI,QAAA,CAAuB,UAAU;AAC9D,IAAM,cAAA,GAAiB,IAAI,QAAA,CAA2B,QAAQ;AAE9D,IAAM,cAAA,GAAiB,IAAI,QAAA,CAAc,QAAQ;AAIjD,IAAM,iBAAA,GAAoB,CAAC,EAAA,EAAY,CAAA,EAAiB,SAC7D,iBAAA,CAAkB,QAAA,CAAS,EAAA,EAAI,CAAA,EAAG,IAAI;AACjC,IAAM,YAAA,GAAe,CAAC,EAAA,KAAe,iBAAA,CAAkB,IAAI,EAAE;AAE7D,IAAM,aAAA,GAAgB,CAAC,EAAA,EAAY,CAAA,EAAiB,SACzD,aAAA,CAAc,QAAA,CAAS,EAAA,EAAI,CAAA,EAAG,IAAI;AAC7B,IAAM,QAAA,GAAW,CAAC,EAAA,KAAe,aAAA,CAAc,IAAI,EAAE;AACrD,IAAM,UAAA,GAAa,MAAM,aAAA,CAAc,IAAA;AAEvC,IAAM,YAAA,GAAe,CAAC,EAAA,EAAY,CAAA,EAAiB,SACxD,YAAA,CAAa,QAAA,CAAS,EAAA,EAAI,CAAA,EAAG,IAAI;AAC5B,IAAM,OAAA,GAAU,CAAC,EAAA,KAAe,YAAA,CAAa,IAAI,EAAE;AAEnD,IAAM,gBAAA,GAAmB,CAAC,EAAA,EAAY,CAAA,EAAiB,SAC5D,gBAAA,CAAiB,QAAA,CAAS,EAAA,EAAI,CAAA,EAAG,IAAI;AAChC,IAAM,WAAA,GAAc,CAAC,EAAA,KAAe,gBAAA,CAAiB,IAAI,EAAE;AAE3D,IAAM,cAAA,GAAiB,CAAC,GAAA,EAAuB,IAAA,KACpD,eAAe,QAAA,CAAS,GAAA,CAAI,EAAA,EAAI,GAAA,EAAK,IAAI;AACpC,IAAM,SAAA,GAAY,CAAC,EAAA,KAAe,cAAA,CAAe,IAAI,EAAE;AACvD,IAAM,WAAA,GAAc,MAAM,cAAA,CAAe,IAAA;AAGzC,IAAM,cAAA,GAAiB,CAAC,EAAA,EAAY,QAAA,EAAe,SACxD,cAAA,CAAe,QAAA,CAAS,EAAA,EAAI,QAAA,EAAU,IAAI;AACrC,IAAM,SAAA,GAAY,CAAC,EAAA,KAAe,cAAA,CAAe,IAAI,EAAE;AACvD,IAAM,WAAA,GAAc,MAAM,cAAA,CAAe,IAAA;AAQzC,IAAM,qBAAA,GAAwB,IAAI,QAAA,CAAwB,gBAAgB;AAC1E,IAAM,qBAAA,GAAwB,CAAC,EAAA,EAAY,OAAA,EAAwB,SACxE,qBAAA,CAAsB,QAAA,CAAS,EAAA,EAAI,OAAA,EAAS,IAAI;AAC3C,IAAM,gBAAA,GAAmB,CAAC,EAAA,KAAe,qBAAA,CAAsB,IAAI,EAAE;AACrE,IAAM,mBAAA,GAAsB,MAAM,qBAAA,CAAsB,IAAA;ACvIxD,IAAM,kBAAA,GAAqB;AAI3B,SAAS,uBACd,GAAA,EAC0C;AAC1C,EAAA,IAAI,GAAA,CAAI,SAAA,EAAW,OAAO,GAAA,CAAI,SAAA;AAC9B,EAAA,IAAI,GAAA,CAAI,WAAA,EAAa,OAAO,YAAA,CAAa,IAAI,WAAW,CAAA;AACxD,EAAA,OAAO,MAAA;AACT;AASA,IAAM,aAAA,GAAsC;AAAA,EAC1C,MAAA,EAAQ,IAAA;AAAA,EACR,IAAA,EAAM,IAAA;AAAA,EACN,WAAA,EAAa,GAAA;AAAA,EACb,WAAA,EAAa,GAAA;AAAA,EACb,MAAA,EAAQ;AACV,CAAA;AAEA,SAAS,QAAQ,KAAA,EAAuB;AACtC,EAAA,OAAO,KAAA,CAAM,aAAY,CAAE,OAAA,CAAQ,eAAe,GAAG,CAAA,CAAE,OAAA,CAAQ,QAAA,EAAU,EAAE,CAAA;AAC7E;AAEA,SAAS,mBAAA,CAAoB,SAAiB,WAAA,EAA8B;AAC1E,EAAA,IAAI,OAAA,KAAY,aAAa,OAAO,IAAA;AACpC,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,IAAI,CAAA,EAAG;AAC1B,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAChC,IAAA,OAAO,gBAAgB,IAAA,IAAQ,WAAA,CAAY,UAAA,CAAW,CAAA,EAAG,IAAI,CAAA,CAAA,CAAG,CAAA;AAAA,EAClE;AACA,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG,OAAO,WAAA,CAAY,UAAA,CAAW,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA;AAC7E,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,eAAA,CAAgB,QAA8B,OAAA,EAAwC;AAC7F,EAAA,IAAI,MAAA,CAAO,UAAA,IAAc,OAAA,CAAQ,aAAA,IAAiB,CAAC,QAAQ,aAAA,CAAc,MAAA,CAAO,UAAU,CAAA,EAAG,OAAO,KAAA;AACpG,EAAA,MAAM,aAAiD,MAAA,CAAO,UAAA;AAC9D,EAAA,IAAI,CAAC,YAAY,OAAO,IAAA;AAExB,EAAA,IAAI,UAAA,CAAW,WAAW,CAAC,UAAA,CAAW,QAAQ,QAAA,CAAS,OAAA,CAAQ,MAAM,CAAA,EAAG,OAAO,KAAA;AAC/E,EAAA,IAAI,UAAA,CAAW,KAAA,IAAS,OAAA,CAAQ,IAAA,EAAM,IAAA,IAAQ,CAAC,UAAA,CAAW,KAAA,CAAM,QAAA,CAAS,OAAA,CAAQ,IAAA,CAAK,IAAI,GAAG,OAAO,KAAA;AACpG,EAAA,IAAI,WAAW,KAAA,IAAS,CAAC,OAAA,CAAQ,IAAA,EAAM,MAAM,OAAO,KAAA;AACpD,EAAA,IAAI,UAAA,CAAW,KAAA,IAAS,OAAA,CAAQ,MAAA,EAAQ,IAAA,IAAQ,CAAC,UAAA,CAAW,KAAA,CAAM,QAAA,CAAS,OAAA,CAAQ,MAAA,CAAO,IAAI,GAAG,OAAO,KAAA;AACxG,EAAA,IAAI,WAAW,KAAA,IAAS,CAAC,OAAA,CAAQ,MAAA,EAAQ,MAAM,OAAO,KAAA;AACtD,EAAA,IAAI,UAAA,CAAW,MAAA,IAAU,CAAC,UAAA,CAAW,OAAO,IAAA,CAAK,CAAC,CAAA,KAAM,mBAAA,CAAoB,CAAA,EAAG,OAAA,CAAQ,WAAW,CAAC,GAAG,OAAO,KAAA;AAC7G,EAAA,IAAI,UAAA,CAAW,aAAA,EAAe,IAAA,CAAK,CAAC,CAAA,KAAM,mBAAA,CAAoB,CAAA,EAAG,OAAA,CAAQ,WAAW,CAAC,CAAA,EAAG,OAAO,KAAA;AAC/F,EAAA,IAAI,UAAA,CAAW,aAAa,MAAA,EAAQ;AAClC,IAAA,IAAI,CAAC,OAAA,CAAQ,aAAA,EAAe,OAAO,KAAA;AACnC,IAAA,IAAI,CAAC,UAAA,CAAW,WAAA,CAAY,KAAA,CAAM,CAAC,GAAA,KAAQ,OAAA,CAAQ,aAAA,GAAgB,GAAG,CAAC,CAAA,EAAG,OAAO,KAAA;AAAA,EACnF;AACA,EAAA,IAAI,WAAW,IAAA,IAAQ,CAAC,WAAW,IAAA,CAAK,OAAO,GAAG,OAAO,KAAA;AACzD,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,sBAAsB,MAAA,EAA6C;AAC1E,EAAA,OAAA,CAAQ,OAAO,QAAA,IAAY,IAAI,GAAA,CAAI,CAAC,OAAO,KAAA,MAAW;AAAA,IACpD,GAAG,KAAA;AAAA,IACH,QAAA,EAAU,KAAA,CAAM,QAAA,IAAY,MAAA,CAAO,EAAA;AAAA,IACnC,KAAA,EAAO,MAAM,KAAA,IAAS,KAAA;AAAA,IACtB,EAAA,EAAI,KAAA,CAAM,EAAA,IAAM,CAAA,EAAG,MAAA,CAAO,EAAE,CAAA,CAAA,EAAI,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,GACtD,CAAE,CAAA;AACJ;AAEA,SAAS,kBAAA,CAAmB,UAAgC,aAAA,EAA8B;AACxF,EAAA,OAAO;AAAA,IACL,OAAA;AAAA,IACA,SAAS,EAAC;AAAA,IACV,eAAe,EAAC;AAAA,IAChB,QAAQ,EAAC;AAAA,IACT,YAAY,EAAC;AAAA,IACb,cAAc,EAAC;AAAA,IACf,SAAS,EAAC;AAAA,IACV,kBAAkB,EAAC;AAAA,IACnB,cAAc,EAAC;AAAA,IACf,SAAS,EAAC;AAAA,IACV,UAAA,sBAAgB,GAAA,EAAI;AAAA,IACpB,gBAAA,sBAAsB,GAAA,EAAI;AAAA,IAC1B,gBAAgB,EAAC;AAAA,IACjB,QAAQ;AAAC,GACX;AACF;AAEO,SAAS,aAAuC,MAAA,EAAc;AACnE,EAAA,OAAO,MAAA;AACT;AAEO,SAAS,oBAAA,CAAqB;AAAA,EACnC,UAAU,EAAC;AAAA,EACX,gBAAgB,EAAC;AAAA,EACjB,iBAAA;AAAA,EACA;AACF,CAAA,EAA+C;AAC7C,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG,OAAO,mBAAmB,OAAO,CAAA;AAE3D,EAAA,MAAM,SAA+B,EAAC;AACtC,EAAA,MAAM,iBAAA,uBAAwB,GAAA,EAA4B;AAE1D,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,IAAI,iBAAA,CAAkB,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA,EAAG;AACpC,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,kBAAA,EAAoB,QAAA,EAAU,MAAA,CAAO,EAAA,EAAI,OAAA,EAAS,CAAA,QAAA,EAAW,MAAA,CAAO,EAAE,CAAA,4BAAA,CAAA,EAAgC,CAAA;AAC1H,MAAA;AAAA,IACF;AACA,IAAA,IAAI,MAAA,CAAO,UAAA,IAAc,IAAA,IAAQ,MAAA,CAAO,aAAa,kBAAA,EAAoB;AACvE,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,IAAA,EAAM,0BAAA;AAAA,QACN,UAAU,MAAA,CAAO,EAAA;AAAA,QACjB,OAAA,EAAS,WAAW,MAAA,CAAO,EAAE,0BAA0B,MAAA,CAAO,UAAU,gCAAgC,kBAAkB,CAAA,wBAAA;AAAA,OAC3H,CAAA;AACD,MAAA;AAAA,IACF;AACA,IAAA,iBAAA,CAAkB,GAAA,CAAI,MAAA,CAAO,EAAA,EAAI,MAAM,CAAA;AAAA,EACzC;AAEA,EAAA,MAAM,QAAA,uBAAe,GAAA,EAAiC;AACtD,EAAA,KAAA,MAAW,KAAK,aAAA,EAAe,QAAA,CAAS,GAAA,CAAI,CAAA,CAAE,UAAU,CAAC,CAAA;AACzD,EAAA,MAAM,kBAAA,GAAqB,iBAAA,IAAqB,aAAA,CAAc,MAAA,GAAS,CAAA;AAEvE,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAY;AAClC,EAAA,MAAM,gBAAA,uBAAuB,GAAA,EAAwD;AAErF,EAAA,KAAA,MAAW,MAAA,IAAU,iBAAA,CAAkB,MAAA,EAAO,EAAG;AAC/C,IAAA,MAAM,OAAA,GAAU,QAAA,CAAS,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA;AACtC,IAAA,IAAI,OAAA,EAAS,WAAW,QAAA,EAAU;AAChC,MAAA,SAAA,CAAU,GAAA,CAAI,OAAO,EAAE,CAAA;AACvB,MAAA,gBAAA,CAAiB,GAAA,CAAI,MAAA,CAAO,EAAA,EAAI,QAAQ,CAAA;AACxC,MAAA;AAAA,IACF;AACA,IAAA,IAAI,OAAO,cAAA,KAAmB,IAAA,IAAS,CAAC,kBAAA,IAAsB,MAAA,CAAO,mBAAmB,KAAA,EAAQ;AAC9F,MAAA,SAAA,CAAU,GAAA,CAAI,OAAO,EAAE,CAAA;AACvB,MAAA,gBAAA,CAAiB,GAAA,CAAI,MAAA,CAAO,EAAA,EAAI,SAAS,CAAA;AAAA,IAC3C;AAAA,EACF;AAEA,EAAA,MAAM,aAAuB,EAAC;AAC9B,EAAA,MAAM,QAAA,uBAAe,GAAA,EAAY;AACjC,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAEhC,EAAA,SAAS,KAAA,CAAM,QAAA,EAAkB,QAAA,GAAqB,EAAC,EAAS;AAC9D,IAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA,EAAG;AAC3B,IAAA,MAAM,MAAA,GAAS,iBAAA,CAAkB,GAAA,CAAI,QAAQ,CAAA;AAC7C,IAAA,IAAI,CAAC,MAAA,EAAQ;AACb,IAAA,IAAI,QAAA,CAAS,GAAA,CAAI,QAAQ,CAAA,EAAG;AAC1B,MAAA,MAAA,CAAO,KAAK,EAAE,IAAA,EAAM,qBAAA,EAAuB,QAAA,EAAU,SAAS,CAAA,qBAAA,EAAwB,CAAC,GAAG,QAAA,EAAU,QAAQ,CAAA,CAAE,IAAA,CAAK,MAAM,CAAC,KAAK,CAAA;AAC/H,MAAA;AAAA,IACF;AACA,IAAA,QAAA,CAAS,IAAI,QAAQ,CAAA;AACrB,IAAA,KAAA,MAAW,KAAA,IAAS,MAAA,CAAO,YAAA,IAAgB,EAAC,EAAG;AAC7C,MAAA,IAAI,CAAC,iBAAA,CAAkB,GAAA,CAAI,KAAK,CAAA,EAAG;AACjC,QAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,oBAAA,EAAsB,UAAU,YAAA,EAAc,KAAA,EAAO,OAAA,EAAS,CAAA,QAAA,EAAW,MAAA,CAAO,EAAE,CAAA,6BAAA,EAAgC,KAAK,MAAM,CAAA;AACjJ,QAAA;AAAA,MACF;AACA,MAAA,IAAI,SAAA,CAAU,IAAI,QAAQ,CAAA,IAAK,CAAC,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA,EAAG;AACpD,QAAA,SAAA,CAAU,IAAI,KAAK,CAAA;AACnB,QAAA,gBAAA,CAAiB,GAAA,CAAI,OAAO,YAAY,CAAA;AAAA,MAC1C;AACA,MAAA,KAAA,CAAM,KAAA,EAAO,CAAC,GAAG,QAAA,EAAU,QAAQ,CAAC,CAAA;AAAA,IACtC;AACA,IAAA,QAAA,CAAS,OAAO,QAAQ,CAAA;AACxB,IAAA,OAAA,CAAQ,IAAI,QAAQ,CAAA;AACpB,IAAA,UAAA,CAAW,KAAK,QAAQ,CAAA;AAAA,EAC1B;AAEA,EAAA,KAAA,MAAW,EAAA,IAAM,iBAAA,CAAkB,IAAA,EAAK,QAAS,EAAE,CAAA;AAEnD,EAAA,MAAM,YAAA,uBAAmB,GAAA,EAAoC;AAE7D,EAAA,KAAA,MAAW,YAAY,UAAA,EAAY;AACjC,IAAA,MAAM,MAAA,GAAS,iBAAA,CAAkB,GAAA,CAAI,QAAQ,CAAA;AAC7C,IAAA,IAAI,CAAC,MAAA,EAAQ;AACb,IAAA,MAAM,OAAA,GAAU,QAAA,CAAS,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA;AACtC,IAAA,MAAM,OAAA,GAAA,CAAW,MAAA,CAAO,YAAA,IAAgB,EAAC,EAAG,MAAA,CAAO,CAAC,EAAA,KAAO,CAAC,iBAAA,CAAkB,GAAA,CAAI,EAAE,CAAC,CAAA;AACrF,IAAA,MAAM,aAAa,CAAC,MAAA,CAAO,cAAc,MAAA,CAAO,UAAA,KAAe,QAAQ,MAAA,EAAQ,UAAA;AAC/E,IAAA,IAAI,CAAC,UAAA,EAAY;AACf,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,mBAAA,EAAqB,UAAU,MAAA,CAAO,EAAA,EAAI,OAAA,EAAS,CAAA,QAAA,EAAW,OAAO,EAAE,CAAA,qBAAA,EAAwB,MAAA,CAAO,UAAU,MAAM,CAAA;AAAA,IAC5I;AACA,IAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA,IAAK,UAAA;AAClD,IAAA,MAAM,SAAA,GAAA,CAAa,MAAA,CAAO,YAAA,IAAgB,EAAC,EAAG,KAAA,CAAM,CAAC,EAAA,KAAO,YAAA,CAAa,GAAA,CAAI,EAAE,CAAA,EAAG,QAAQ,CAAA;AAC1F,IAAA,MAAM,kBAAA,GAAqB,OAAA,EAAS,MAAA,KAAW,UAAA,IAAc,SAAS,MAAA,KAAW,SAAA;AACjF,IAAA,MAAM,cAAA,GAAiB,WAAW,YAAA,GAAe,IAAA,GAAO,UAAU,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA,IAAK,CAAC,kBAAA;AACrF,IAAA,MAAM,QAAA,GAAW,cAAA,IAAkB,UAAA,IAAc,OAAA,CAAQ,WAAW,CAAA,IAAK,SAAA;AAEzE,IAAA,YAAA,CAAa,GAAA,CAAI,OAAO,EAAA,EAAI;AAAA,MAC1B,GAAG,MAAA;AAAA,MACH,MAAA,EAAQ,QAAA,GAAW,QAAA,GAAY,OAAA,EAAS,MAAA,IAAU,UAAA;AAAA,MAClD,QAAA;AAAA,MACA,gBAAA,EAAkB,WAAW,MAAA,GAAS,UAAA;AAAA,MACtC,MAAA,EAAQ,OAAA,EAAS,MAAA,IAAU,EAAC;AAAA,MAC5B,mBAAA,EAAqB,OAAA;AAAA,MACrB,YAAA,EAAc,sBAAsB,MAAM,CAAA;AAAA,MAC1C,OAAA,EAAS,MAAA,CAAO,OAAA,IAAW,EAAC;AAAA,MAC5B,kBAAA,EAAoB,MAAA,CAAO,UAAA,IAAc,EAAC;AAAA,MAC1C,eAAA,EAAiB,MAAA,CAAO,OAAA,IAAW;AAAC,KACrC,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,eAAA,GAAkB,UAAA,CACrB,GAAA,CAAI,CAAC,OAAO,YAAA,CAAa,GAAA,CAAI,EAAE,CAAC,EAChC,MAAA,CAAO,CAAC,CAAA,KAAmC,OAAA,CAAQ,CAAC,CAAC,CAAA;AAExD,EAAA,MAAM,gBAAgB,eAAA,CAAgB,MAAA,CAAO,CAAC,CAAA,KAAM,EAAE,QAAQ,CAAA;AAC9D,EAAA,MAAM,SAA+B,EAAC;AACtC,EAAA,MAAM,aAAsC,EAAC;AAC7C,EAAA,MAAM,eAAoC,EAAC;AAC3C,EAAA,MAAM,UAAkC,EAAC;AACzC,EAAA,MAAM,mBAA8C,EAAC;AACrD,EAAA,MAAM,eAAmC,EAAC;AAC1C,EAAA,MAAM,UAA0B,EAAC;AACjC,EAAA,MAAM,UAAA,uBAAiB,GAAA,EAAiC;AACxD,EAAA,MAAM,gBAAA,uBAAuB,GAAA,EAAmC;AAChE,EAAA,MAAM,iBAAuC,EAAC;AAE9C,EAAA,KAAA,MAAW,UAAU,aAAA,EAAe;AAClC,IAAA,MAAA,CAAO,IAAA,CAAK,GAAG,MAAA,CAAO,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,MAAA,EAAO,CAAE,CAAC,CAAA;AAC3D,IAAA,UAAA,CAAW,KAAK,GAAG,MAAA,CAAO,WAAW,GAAA,CAAI,CAAC,OAAO,CAAA,MAAO;AAAA,MACtD,GAAG,KAAA;AAAA,MACH,EAAA,EAAI,KAAA,CAAM,EAAA,IAAM,CAAA,EAAG,MAAA,CAAO,EAAE,CAAA,CAAA,EAAI,KAAA,CAAM,KAAK,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA;AAAA,MAChD,IAAA,EAAM,KAAA,CAAM,IAAA,IAAQ,MAAA,CAAO;AAAA,MAC3B,CAAC,CAAA;AACH,IAAA,YAAA,CAAa,IAAA,CAAK,GAAG,MAAA,CAAO,YAAY,CAAA;AACxC,IAAA,YAAA,CAAa,IAAA,CAAK,GAAI,MAAA,CAAO,YAAA,IAAgB,EAAG,CAAA;AAChD,IAAA,OAAA,CAAQ,IAAA,CAAK,GAAG,MAAA,CAAO,eAAe,CAAA;AACtC,IAAA,IAAI,MAAA,CAAO,mBAAmB,MAAA,GAAS,CAAA,aAAc,GAAA,CAAI,MAAA,CAAO,EAAA,EAAI,MAAA,CAAO,kBAAkB,CAAA;AAE7F,IAAA,KAAA,MAAW,SAAA,IAAa,MAAA,CAAO,UAAA,IAAc,EAAC,EAAG;AAC/C,MAAA,MAAM,OAAO,gBAAA,CAAiB,GAAA,CAAI,SAAA,CAAU,YAAY,KAAK,EAAC;AAC9D,MAAA,IAAA,CAAK,KAAK,SAAS,CAAA;AACnB,MAAA,gBAAA,CAAiB,GAAA,CAAI,SAAA,CAAU,YAAA,EAAc,IAAI,CAAA;AAAA,IACnD;AACA,IAAA,IAAI,OAAO,gBAAA,EAAkB,cAAA,CAAe,IAAA,CAAK,GAAG,OAAO,gBAAgB,CAAA;AAC3E,IAAA,OAAA,CAAQ,KAAK,GAAG,MAAA,CAAO,QAAQ,GAAA,CAAI,CAAC,GAAG,CAAA,MAAO;AAAA,MAC5C,GAAG,CAAA;AAAA,MACH,KAAA,EAAO,EAAE,KAAA,IAAS,CAAA;AAAA,MAClB,MAAA,EAAQ,EAAE,GAAG,MAAA,CAAO,QAAQ,GAAI,CAAA,CAAE,KAAA,IAAS,EAAC,EAAG;AAAA,MAC/C;AAAA,MACA,CAAC,CAAA;AACH,IAAA,gBAAA,CAAiB,IAAA,CAAK,IAAI,MAAA,CAAO,gBAAA,IAAoB,EAAC,EAAG,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,MAAO;AAAA,MACtE,GAAG,CAAA;AAAA,MACH,MAAA,EAAQ,CAAA,CAAE,MAAA,IAAU,MAAA,CAAO,EAAA;AAAA,MAC3B,KAAA,EAAO,EAAE,YAAA,IAAgB,CAAA;AAAA,MACzB;AAAA,MACA,CAAC,CAAA;AAAA,EACL;AAEA,EAAA,UAAA,CAAW,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM;AACxB,IAAA,MAAM,QAAQ,EAAE,IAAA,EAAM,GAAG,SAAA,EAAW,CAAA,EAAG,UAAU,CAAA,EAAE;AACnD,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,CAAE,OAAO,CAAA,IAAK,EAAA,KAAO,KAAA,CAAM,CAAA,CAAE,OAAO,CAAA,IAAK,EAAA,CAAA,IAAO,CAAA,CAAE,QAAA,GAAW,CAAA,CAAE,QAAA;AAAA,EAC/E,CAAC,CAAA;AACD,EAAA,YAAA,CAAa,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAA,CAAO,EAAE,KAAA,IAAS,CAAA,KAAM,CAAA,CAAE,KAAA,IAAS,CAAA,CAAE,CAAA;AAC3D,EAAA,OAAA,CAAQ,KAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,SAAS,CAAA,CAAE,IAAA,GAAO,CAAA,CAAE,IAAA,CAAK,cAAc,CAAA,CAAE,IAAI,IAAI,CAAA,CAAE,KAAA,GAAQ,EAAE,KAAK,CAAA;AAC3F,EAAA,gBAAA,CAAiB,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,KAAA,GAAQ,EAAE,KAAK,CAAA;AAEjD,EAAA,OAAO,EAAE,OAAA,EAAS,OAAA,EAAS,eAAA,EAAiB,eAAe,MAAA,EAAQ,UAAA,EAAY,YAAA,EAAc,OAAA,EAAS,kBAAkB,YAAA,EAAc,OAAA,EAAS,MAAA,EAAQ,UAAA,EAAY,kBAAkB,cAAA,EAAe;AACtM;AAEO,SAAS,iBAAA,CACd,OAAA,EACA,IAAA,EACA,gBAAA,EACwB;AACxB,EAAA,MAAM,MAAM,EAAE,GAAG,OAAA,CAAQ,OAAA,EAAS,GAAG,gBAAA,EAAiB;AACtD,EAAA,OAAO,OAAA,CAAQ,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,IAAA,IAAQ,eAAA,CAAgB,CAAA,EAAG,GAAG,CAAC,CAAA;AACjF;AAEO,SAAS,mBAAA,CACd,SACA,OAAA,EAC2B;AAC3B,EAAA,MAAM,MAAM,EAAE,GAAG,QAAQ,OAAA,EAAS,GAAG,QAAQ,gBAAA,EAAiB;AAC9D,EAAA,OAAO,OAAA,CAAQ,gBAAA,CAAiB,MAAA,CAAO,CAAC,CAAA,KAAM;AAC5C,IAAA,MAAM,QAAA,GAAW,CAAA,CAAE,QAAA,IAAY,CAAC,QAAQ,aAAa,CAAA;AACrD,IAAA,IAAI,CAAC,QAAA,CAAS,QAAA,CAAS,OAAA,CAAQ,OAAO,GAAG,OAAO,KAAA;AAChD,IAAA,IAAI,QAAQ,MAAA,IAAU,CAAA,CAAE,MAAA,KAAW,OAAA,CAAQ,QAAQ,OAAO,KAAA;AAC1D,IAAA,IAAI,CAAA,CAAE,UAAA,IAAc,GAAA,CAAI,MAAA,EAAQ,UAAA,IAAc,EAAE,UAAA,KAAe,GAAA,CAAI,MAAA,CAAO,UAAA,EAAY,OAAO,KAAA;AAC7F,IAAA,IAAI,CAAA,CAAE,UAAA,IAAc,GAAA,CAAI,aAAA,IAAiB,CAAC,IAAI,aAAA,CAAc,CAAA,CAAE,UAAU,CAAA,EAAG,OAAO,KAAA;AAClF,IAAA,OAAO,IAAA;AAAA,EACT,CAAC,CAAA;AACH;AAEA,IAAM,oBAAA,GAA6B,oBAAoC,IAAI,CAAA;AACpE,IAAM,wBAAwB,oBAAA,CAAqB;AAEnD,SAAS,gBAAA,GAAkC;AAChD,EAAA,OAAa,KAAA,CAAA,UAAA,CAAW,oBAAoB,CAAA,IAAK,kBAAA,EAAmB;AACtE;AAEO,SAAS,wBAAA,GAAiD;AAC/D,EAAA,OAAa,iBAAW,oBAAoB,CAAA;AAC9C;AAGO,SAAS,uBAAuB,YAAA,EAA6C;AAClF,EAAA,OAAO,kBAAiB,CAAE,gBAAA,CAAiB,GAAA,CAAI,YAAY,KAAK,EAAC;AACnE","file":"chunk-CHGX6UYR.js","sourcesContent":["import type { ComponentType } from 'react'\n\n// ---------------------------------------------------------------------------\n// Uniform registry — the indirection layer that lets a pure-data AppManifest\n// reference code by string id. Generalizes the entity registry pattern to\n// components, blocks, pages, metrics, scaffolds and plugins.\n//\n// Naming convention: SDK/plugin artifacts use a namespaced id\n// (`agenda.week-view`, `crud.detail-header`); app-local custom code uses the\n// reserved `custom:` prefix (`custom:tannat.HarvestBoard`). The platform never\n// generates `custom:` ids — they only come from an app's registry.tsx.\n// ---------------------------------------------------------------------------\n\n/** A JSON Schema object (loosely typed; validated by tooling, not at runtime). */\nexport type JsonSchema = Record<string, unknown>\n\nexport type RegistrySource = 'sdk' | 'plugin' | 'app'\n\nexport interface RegistryMeta {\n /** Human label for the platform editor. */\n label?: string\n description?: string\n /** Where this artifact came from (for introspection / conflict reporting). */\n source?: RegistrySource\n /** Owning plugin id, when source is 'plugin'. */\n pluginId?: string\n /** JSON Schema for this artifact's props/config — drives the visual editor\n * and constrains AI generation. Optional but strongly encouraged. */\n propsSchema?: JsonSchema\n}\n\nexport interface RegistryEntry<T> {\n id: string\n value: T\n meta: RegistryMeta\n}\n\n/** A typed, introspectable id→value map. Last registration wins (so an app's\n * registry.tsx can override an SDK artifact by re-registering its id). */\nexport class Registry<T> {\n private readonly entries = new Map<string, RegistryEntry<T>>()\n\n constructor(readonly kind: string) {}\n\n register(id: string, value: T, meta: RegistryMeta = {}): void {\n this.entries.set(id, { id, value, meta })\n }\n\n get(id: string): T | undefined {\n return this.entries.get(id)?.value\n }\n\n getEntry(id: string): RegistryEntry<T> | undefined {\n return this.entries.get(id)\n }\n\n has(id: string): boolean {\n return this.entries.has(id)\n }\n\n list(): RegistryEntry<T>[] {\n return Array.from(this.entries.values())\n }\n\n ids(): string[] {\n return Array.from(this.entries.keys())\n }\n\n clear(): void {\n this.entries.clear()\n }\n}\n\n/** True for app-local custom artifacts (`custom:*`). */\nexport function isCustomId(id: string): boolean {\n return id.startsWith('custom:')\n}\n\n// ---------------------------------------------------------------------------\n// Metric definitions (consumed by dashboard / reports / KPI panels).\n// ---------------------------------------------------------------------------\n\nexport type MetricFormat = 'number' | 'currency' | 'percent' | 'duration' | 'rating'\n\nexport interface MetricContext {\n tenantId?: string\n /** ISO date range the metric should compute over, when applicable. */\n range?: { from: string; to: string }\n [key: string]: unknown\n}\n\nexport interface MetricValue {\n value: number\n previousValue?: number\n trend?: 'up' | 'down' | 'flat'\n}\n\nexport interface MetricDefinition {\n id: string\n label?: string\n category?: string\n format?: MetricFormat\n compute: (ctx: MetricContext) => Promise<MetricValue> | MetricValue\n}\n\n// ---------------------------------------------------------------------------\n// Concrete registries. Components/blocks/pages/scaffolds hold React component\n// types; metrics hold definitions; plugins hold opaque manifests (typed at the\n// plugin layer to avoid a circular import).\n// ---------------------------------------------------------------------------\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyComponent = ComponentType<any>\n\nexport const componentRegistry = new Registry<AnyComponent>('component')\nexport const blockRegistry = new Registry<AnyComponent>('block')\nexport const pageRegistry = new Registry<AnyComponent>('page')\nexport const scaffoldRegistry = new Registry<AnyComponent>('scaffold')\nexport const metricRegistry = new Registry<MetricDefinition>('metric')\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const pluginRegistry = new Registry<any>('plugin')\n\n// Thin functional facade (the public API surface) -----------------------------\n\nexport const registerComponent = (id: string, c: AnyComponent, meta?: RegistryMeta) =>\n componentRegistry.register(id, c, meta)\nexport const getComponent = (id: string) => componentRegistry.get(id)\n\nexport const registerBlock = (id: string, c: AnyComponent, meta?: RegistryMeta) =>\n blockRegistry.register(id, c, meta)\nexport const getBlock = (id: string) => blockRegistry.get(id)\nexport const listBlocks = () => blockRegistry.list()\n\nexport const registerPage = (id: string, c: AnyComponent, meta?: RegistryMeta) =>\n pageRegistry.register(id, c, meta)\nexport const getPage = (id: string) => pageRegistry.get(id)\n\nexport const registerScaffold = (id: string, c: AnyComponent, meta?: RegistryMeta) =>\n scaffoldRegistry.register(id, c, meta)\nexport const getScaffold = (id: string) => scaffoldRegistry.get(id)\n\nexport const registerMetric = (def: MetricDefinition, meta?: RegistryMeta) =>\n metricRegistry.register(def.id, def, meta)\nexport const getMetric = (id: string) => metricRegistry.get(id)\nexport const listMetrics = () => metricRegistry.list()\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const registerPlugin = (id: string, manifest: any, meta?: RegistryMeta) =>\n pluginRegistry.register(id, manifest, meta)\nexport const getPlugin = (id: string) => pluginRegistry.get(id)\nexport const listPlugins = () => pluginRegistry.list()\n\n// Plugin factories — a generated app registers each installed @fayz-ai/plugin-*\n// factory by id (src/plugins.generated.ts), so a scaffold can resolve a\n// manifest's PluginRef (id + JSON config) to a live PluginManifest:\n// getPluginFactory(ref.id)?.(ref.config)\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type PluginFactory = (config?: Record<string, unknown>) => any\nexport const pluginFactoryRegistry = new Registry<PluginFactory>('plugin-factory')\nexport const registerPluginFactory = (id: string, factory: PluginFactory, meta?: RegistryMeta) =>\n pluginFactoryRegistry.register(id, factory, meta)\nexport const getPluginFactory = (id: string) => pluginFactoryRegistry.get(id)\nexport const listPluginFactories = () => pluginFactoryRegistry.list()\n","import * as React from 'react'\nimport type {\n PluginManifest,\n PluginRuntime,\n PluginRuntimeContext,\n PluginRuntimeIssue,\n PluginRuntimeRoute,\n PluginSettingsTab,\n PluginWidgetDefinition,\n PluginWidgetZone,\n ResolvedPluginManifest,\n ResolvedPluginWidget,\n TenantPluginBinding,\n PluginRegistryDef,\n PluginAITool,\n PluginNavigationEntry,\n PluginCapability,\n PluginWidgetVisibility,\n ResolvedDashboardWidget,\n DashboardSurface,\n} from '../types/plugins'\nimport type { FeatureDeclaration } from '../types/permissions'\nimport type { ConnectorDefinition } from '../integrations'\nimport { getComponent } from '../registry'\n\n/** The plugin contract version this runtime understands. A plugin declaring a\n * higher apiVersion is rejected rather than mis-rendered. */\nexport const PLUGIN_API_VERSION = 1\n\n/** Resolve a plugin route/widget/settings/onboarding target to a component,\n * whether it provided the component directly or a registered component id. */\nexport function resolvePluginComponent(\n def: { component?: React.ComponentType<unknown>; componentId?: string },\n): React.ComponentType<unknown> | undefined {\n if (def.component) return def.component\n if (def.componentId) return getComponent(def.componentId) as React.ComponentType<unknown> | undefined\n return undefined\n}\n\ninterface ResolvePluginRuntimeOptions {\n plugins?: PluginManifest[]\n tenantPlugins?: TenantPluginBinding[]\n hasTenantBindings?: boolean\n context: PluginRuntimeContext\n}\n\nconst EMPTY_CONTEXT: PluginRuntimeContext = {\n tenant: null,\n user: null,\n currentPath: '/',\n matchedPath: '/',\n layout: 'sidebar',\n}\n\nfunction slugify(input: string): string {\n return input.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '')\n}\n\nfunction matchesRoutePattern(pattern: string, currentPath: string): boolean {\n if (pattern === currentPath) return true\n if (pattern.endsWith('/*')) {\n const base = pattern.slice(0, -2)\n return currentPath === base || currentPath.startsWith(`${base}/`)\n }\n if (pattern.endsWith('*')) return currentPath.startsWith(pattern.slice(0, -1))\n return false\n}\n\nfunction isWidgetVisible(widget: ResolvedPluginWidget, context: PluginRuntimeContext): boolean {\n if (widget.permission && context.hasPermission && !context.hasPermission(widget.permission)) return false\n const visibility: PluginWidgetVisibility | undefined = widget.visibility\n if (!visibility) return true\n\n if (visibility.layouts && !visibility.layouts.includes(context.layout)) return false\n if (visibility.roles && context.user?.role && !visibility.roles.includes(context.user.role)) return false\n if (visibility.roles && !context.user?.role) return false\n if (visibility.plans && context.tenant?.plan && !visibility.plans.includes(context.tenant.plan)) return false\n if (visibility.plans && !context.tenant?.plan) return false\n if (visibility.routes && !visibility.routes.some((p) => matchesRoutePattern(p, context.currentPath))) return false\n if (visibility.excludeRoutes?.some((p) => matchesRoutePattern(p, context.currentPath))) return false\n if (visibility.permissions?.length) {\n if (!context.hasPermission) return false\n if (!visibility.permissions.every((req) => context.hasPermission?.(req))) return false\n }\n if (visibility.when && !visibility.when(context)) return false\n return true\n}\n\nfunction normalizeSettingsTabs(plugin: PluginManifest): PluginSettingsTab[] {\n return (plugin.settings ?? []).map((entry, index) => ({\n ...entry,\n pluginId: entry.pluginId ?? plugin.id,\n order: entry.order ?? index,\n id: entry.id ?? `${plugin.id}-${slugify(entry.label)}`,\n }))\n}\n\nfunction createEmptyRuntime(context: PluginRuntimeContext = EMPTY_CONTEXT): PluginRuntime {\n return {\n context,\n plugins: [],\n activePlugins: [],\n routes: [],\n navigation: [],\n settingsTabs: [],\n widgets: [],\n dashboardWidgets: [],\n capabilities: [],\n aiTools: [],\n registries: new Map(),\n connectorsByHost: new Map(),\n pluginFeatures: [],\n issues: [],\n }\n}\n\nexport function definePlugin<T extends PluginManifest>(plugin: T): T {\n return plugin\n}\n\nexport function resolvePluginRuntime({\n plugins = [],\n tenantPlugins = [],\n hasTenantBindings,\n context,\n}: ResolvePluginRuntimeOptions): PluginRuntime {\n if (plugins.length === 0) return createEmptyRuntime(context)\n\n const issues: PluginRuntimeIssue[] = []\n const normalizedPlugins = new Map<string, PluginManifest>()\n\n for (const plugin of plugins) {\n if (normalizedPlugins.has(plugin.id)) {\n issues.push({ type: 'duplicate_plugin', pluginId: plugin.id, message: `Plugin \"${plugin.id}\" registered more than once.` })\n continue\n }\n if (plugin.apiVersion != null && plugin.apiVersion > PLUGIN_API_VERSION) {\n issues.push({\n type: 'incompatible_api_version',\n pluginId: plugin.id,\n message: `Plugin \"${plugin.id}\" requires plugin API v${plugin.apiVersion}, but this runtime supports v${PLUGIN_API_VERSION}. Upgrade @fayz-ai/core.`,\n })\n continue\n }\n normalizedPlugins.set(plugin.id, plugin)\n }\n\n const bindings = new Map<string, TenantPluginBinding>()\n for (const b of tenantPlugins) bindings.set(b.pluginId, b)\n const bindingsAreManaged = hasTenantBindings ?? tenantPlugins.length > 0\n\n const requested = new Set<string>()\n const activationReason = new Map<string, ResolvedPluginManifest['activationReason']>()\n\n for (const plugin of normalizedPlugins.values()) {\n const binding = bindings.get(plugin.id)\n if (binding?.status === 'active') {\n requested.add(plugin.id)\n activationReason.set(plugin.id, 'tenant')\n continue\n }\n if (plugin.defaultEnabled === true || (!bindingsAreManaged && plugin.defaultEnabled !== false)) {\n requested.add(plugin.id)\n activationReason.set(plugin.id, 'default')\n }\n }\n\n const orderedIds: string[] = []\n const visiting = new Set<string>()\n const visited = new Set<string>()\n\n function visit(pluginId: string, ancestry: string[] = []): void {\n if (visited.has(pluginId)) return\n const plugin = normalizedPlugins.get(pluginId)\n if (!plugin) return\n if (visiting.has(pluginId)) {\n issues.push({ type: 'circular_dependency', pluginId, message: `Circular dependency: ${[...ancestry, pluginId].join(' -> ')}.` })\n return\n }\n visiting.add(pluginId)\n for (const depId of plugin.dependencies ?? []) {\n if (!normalizedPlugins.has(depId)) {\n issues.push({ type: 'missing_dependency', pluginId, dependencyId: depId, message: `Plugin \"${plugin.id}\" depends on missing plugin \"${depId}\".` })\n continue\n }\n if (requested.has(pluginId) && !requested.has(depId)) {\n requested.add(depId)\n activationReason.set(depId, 'dependency')\n }\n visit(depId, [...ancestry, pluginId])\n }\n visiting.delete(pluginId)\n visited.add(pluginId)\n orderedIds.push(pluginId)\n }\n\n for (const id of normalizedPlugins.keys()) visit(id)\n\n const resolvedById = new Map<string, ResolvedPluginManifest>()\n\n for (const pluginId of orderedIds) {\n const plugin = normalizedPlugins.get(pluginId)\n if (!plugin) continue\n const binding = bindings.get(plugin.id)\n const missing = (plugin.dependencies ?? []).filter((id) => !normalizedPlugins.has(id))\n const compatible = !plugin.verticalId || plugin.verticalId === context.tenant?.verticalId\n if (!compatible) {\n issues.push({ type: 'vertical_mismatch', pluginId: plugin.id, message: `Plugin \"${plugin.id}\" requires vertical \"${plugin.verticalId}\".` })\n }\n const reason = activationReason.get(plugin.id) ?? 'inactive'\n const depsReady = (plugin.dependencies ?? []).every((id) => resolvedById.get(id)?.isActive)\n const explicitlyDisabled = binding?.status === 'disabled' || binding?.status === 'removed'\n const shouldActivate = reason === 'dependency' ? true : requested.has(plugin.id) && !explicitlyDisabled\n const isActive = shouldActivate && compatible && missing.length === 0 && depsReady\n\n resolvedById.set(plugin.id, {\n ...plugin,\n status: isActive ? 'active' : (binding?.status ?? 'disabled'),\n isActive,\n activationReason: isActive ? reason : 'inactive',\n config: binding?.config ?? {},\n missingDependencies: missing,\n settingsTabs: normalizeSettingsTabs(plugin),\n widgets: plugin.widgets ?? [],\n resolvedRegistries: plugin.registries ?? [],\n resolvedAITools: plugin.aiTools ?? [],\n })\n }\n\n const resolvedPlugins = orderedIds\n .map((id) => resolvedById.get(id))\n .filter((p): p is ResolvedPluginManifest => Boolean(p))\n\n const activePlugins = resolvedPlugins.filter((p) => p.isActive)\n const routes: PluginRuntimeRoute[] = []\n const navigation: PluginNavigationEntry[] = []\n const settingsTabs: PluginSettingsTab[] = []\n const widgets: ResolvedPluginWidget[] = []\n const dashboardWidgets: ResolvedDashboardWidget[] = []\n const capabilities: PluginCapability[] = []\n const aiTools: PluginAITool[] = []\n const registries = new Map<string, PluginRegistryDef[]>()\n const connectorsByHost = new Map<string, ConnectorDefinition[]>()\n const pluginFeatures: FeatureDeclaration[] = []\n\n for (const plugin of activePlugins) {\n routes.push(...plugin.routes.map((r) => ({ ...r, plugin })))\n navigation.push(...plugin.navigation.map((entry, i) => ({\n ...entry,\n id: entry.id ?? `${plugin.id}:${entry.route}:${i}`,\n icon: entry.icon ?? plugin.icon,\n })))\n settingsTabs.push(...plugin.settingsTabs)\n capabilities.push(...(plugin.capabilities ?? []))\n aiTools.push(...plugin.resolvedAITools)\n if (plugin.resolvedRegistries.length > 0) registries.set(plugin.id, plugin.resolvedRegistries)\n // Group each addon's connectors under the host plugin they extend.\n for (const connector of plugin.connectors ?? []) {\n const list = connectorsByHost.get(connector.hostPluginId) ?? []\n list.push(connector)\n connectorsByHost.set(connector.hostPluginId, list)\n }\n if (plugin.declaredFeatures) pluginFeatures.push(...plugin.declaredFeatures)\n widgets.push(...plugin.widgets.map((w, i) => ({\n ...w,\n order: w.order ?? i,\n config: { ...plugin.config, ...(w.props ?? {}) },\n plugin,\n })))\n dashboardWidgets.push(...(plugin.dashboardWidgets ?? []).map((w, i) => ({\n ...w,\n domain: w.domain ?? plugin.id,\n order: w.defaultOrder ?? i,\n plugin,\n })))\n }\n\n navigation.sort((a, b) => {\n const order = { main: 0, secondary: 1, settings: 2 }\n return (order[a.section] ?? 99) - (order[b.section] ?? 99) || a.position - b.position\n })\n settingsTabs.sort((a, b) => (a.order ?? 0) - (b.order ?? 0))\n widgets.sort((a, b) => a.zone !== b.zone ? a.zone.localeCompare(b.zone) : a.order - b.order)\n dashboardWidgets.sort((a, b) => a.order - b.order)\n\n return { context, plugins: resolvedPlugins, activePlugins, routes, navigation, settingsTabs, widgets, dashboardWidgets, capabilities, aiTools, issues, registries, connectorsByHost, pluginFeatures }\n}\n\nexport function getWidgetsForZone(\n runtime: PluginRuntime,\n zone: PluginWidgetZone,\n contextOverrides?: Partial<PluginRuntimeContext>,\n): ResolvedPluginWidget[] {\n const ctx = { ...runtime.context, ...contextOverrides }\n return runtime.widgets.filter((w) => w.zone === zone && isWidgetVisible(w, ctx))\n}\n\nexport function getDashboardWidgets(\n runtime: PluginRuntime,\n options: { surface: DashboardSurface; domain?: string; contextOverrides?: Partial<PluginRuntimeContext> },\n): ResolvedDashboardWidget[] {\n const ctx = { ...runtime.context, ...options.contextOverrides }\n return runtime.dashboardWidgets.filter((w) => {\n const surfaces = w.surfaces ?? ['home', 'plugin-home']\n if (!surfaces.includes(options.surface)) return false\n if (options.domain && w.domain !== options.domain) return false\n if (w.verticalId && ctx.tenant?.verticalId && w.verticalId !== ctx.tenant.verticalId) return false\n if (w.permission && ctx.hasPermission && !ctx.hasPermission(w.permission)) return false\n return true\n })\n}\n\nconst PluginRuntimeContext = React.createContext<PluginRuntime | null>(null)\nexport const PluginRuntimeProvider = PluginRuntimeContext.Provider\n\nexport function usePluginRuntime(): PluginRuntime {\n return React.useContext(PluginRuntimeContext) ?? createEmptyRuntime()\n}\n\nexport function usePluginRuntimeOptional(): PluginRuntime | null {\n return React.useContext(PluginRuntimeContext)\n}\n\n/** Connectors contributed by addon plugins that extend the given host plugin. */\nexport function useConnectorsForPlugin(hostPluginId: string): ConnectorDefinition[] {\n return usePluginRuntime().connectorsByHost.get(hostPluginId) ?? []\n}\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// src/integrations/index.ts
|
|
2
|
+
function withAfterHooks(target, methods) {
|
|
3
|
+
return new Proxy(target, {
|
|
4
|
+
get(obj, prop, receiver) {
|
|
5
|
+
const orig = Reflect.get(obj, prop, receiver);
|
|
6
|
+
const hook = methods[prop];
|
|
7
|
+
if (typeof orig !== "function" || !hook) return orig;
|
|
8
|
+
return (...args) => {
|
|
9
|
+
const result = orig.apply(obj, args);
|
|
10
|
+
if (result instanceof Promise) {
|
|
11
|
+
return result.then((value) => {
|
|
12
|
+
try {
|
|
13
|
+
void Promise.resolve(hook(args, value)).catch(() => {
|
|
14
|
+
});
|
|
15
|
+
} catch {
|
|
16
|
+
}
|
|
17
|
+
return value;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
void Promise.resolve(hook(args, result)).catch(() => {
|
|
22
|
+
});
|
|
23
|
+
} catch {
|
|
24
|
+
}
|
|
25
|
+
return result;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { withAfterHooks };
|
|
32
|
+
//# sourceMappingURL=chunk-EKOH5PRX.js.map
|
|
33
|
+
//# sourceMappingURL=chunk-EKOH5PRX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/integrations/index.ts"],"names":[],"mappings":";AAmJO,SAAS,cAAA,CACd,QACA,OAAA,EACG;AACH,EAAA,OAAO,IAAI,MAAM,MAAA,EAAQ;AAAA,IACvB,GAAA,CAAI,GAAA,EAAK,IAAA,EAAM,QAAA,EAAU;AACvB,MAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,GAAA,CAAI,GAAA,EAAK,MAAM,QAAQ,CAAA;AAC5C,MAAA,MAAM,IAAA,GAAQ,QAA8G,IAAI,CAAA;AAChI,MAAA,IAAI,OAAO,IAAA,KAAS,UAAA,IAAc,CAAC,MAAM,OAAO,IAAA;AAChD,MAAA,OAAO,IAAI,IAAA,KAAoB;AAC7B,QAAA,MAAM,MAAA,GAAU,IAAA,CAAsC,KAAA,CAAM,GAAA,EAAK,IAAI,CAAA;AACrE,QAAA,IAAI,kBAAkB,OAAA,EAAS;AAC7B,UAAA,OAAO,MAAA,CAAO,IAAA,CAAK,CAAC,KAAA,KAAU;AAC5B,YAAA,IAAI;AAAE,cAAA,KAAK,OAAA,CAAQ,QAAQ,IAAA,CAAK,IAAA,EAAM,KAAK,CAAC,CAAA,CAAE,MAAM,MAAM;AAAA,cAAC,CAAC,CAAA;AAAA,YAAE,CAAA,CAAA,MAAQ;AAAA,YAA6B;AACnG,YAAA,OAAO,KAAA;AAAA,UACT,CAAC,CAAA;AAAA,QACH;AACA,QAAA,IAAI;AAAE,UAAA,KAAK,OAAA,CAAQ,QAAQ,IAAA,CAAK,IAAA,EAAM,MAAM,CAAC,CAAA,CAAE,MAAM,MAAM;AAAA,UAAC,CAAC,CAAA;AAAA,QAAE,CAAA,CAAA,MAAQ;AAAA,QAAa;AACpF,QAAA,OAAO,MAAA;AAAA,MACT,CAAA;AAAA,IACF;AAAA,GACD,CAAA;AACH","file":"chunk-EKOH5PRX.js","sourcesContent":["// ---------------------------------------------------------------------------\n// Integration Connector spine\n// ---------------------------------------------------------------------------\n// An integration is a connector that keeps canonical Fayz data in agreement\n// with an external provider (Google Calendar, open banking, Shopify, …). This\n// module is the thin shared contract both native (SDK) and client-built\n// connectors implement. The heavy lifting (auth, fetch/push, idempotent\n// upserts) runs in the data plane — typically a Supabase Edge Function — while\n// the control plane (a settings tab + this contract) lives in the app/plugin.\n//\n// Design notes live in docs/bling-integration-brief.md. Proven precedents:\n// the Fayz runtime OAuth broker (packages/core/src/runtime/oauth.ts) and the\n// bank-statement edge functions in the predecessor app.\nimport type * as React from 'react'\n\n/** How a connector authenticates to its provider. */\nexport type IntegrationAuthKind = 'oauth' | 'api-key' | 'mtls'\n\n/** Which way data flows for a given capability. */\nexport type SyncDirection = 'inbound' | 'outbound' | 'bidirectional'\n\n/** What causes a sync to run. */\nexport type SyncTrigger = 'on-write' | 'scheduled' | 'manual' | 'webhook'\n\n/** One thing a connector can sync (an entity + its direction + triggers). */\nexport interface ConnectorCapability {\n /** Canonical entity synced, e.g. 'booking', 'movement'. */\n entity: string\n direction: SyncDirection\n triggers: SyncTrigger[]\n}\n\n/** The state of a tenant's connection to a provider (one row in a *_integrations table). */\nexport interface ConnectionConfig {\n /** Provider key, e.g. 'google', 'plugbank'. */\n provider: string\n /** Whether the connection is active and should sync. */\n active: boolean\n /** Opaque, provider-specific config (calendar id, account id, cursor, …). Never secrets. */\n settings?: Record<string, unknown>\n /** Last successful sync, ISO timestamp. */\n lastSyncAt?: string\n}\n\n/** Audit record of one sync execution (generalizes *_sync_log / *_sync_runs). */\nexport interface SyncRun {\n id?: string\n provider: string\n direction: SyncDirection\n trigger: SyncTrigger\n status: 'success' | 'partial' | 'error'\n /** Items pulled/pushed and how many were written. */\n fetched?: number\n written?: number\n /** Pagination/incremental cursor advanced by this run. */\n cursor?: string\n error?: string\n startedAt?: string\n finishedAt?: string\n}\n\nexport interface TestConnectionResult {\n ok: boolean\n message?: string\n}\n\n/**\n * A connector's control-plane descriptor. The data-plane verbs (testConnection,\n * sync) are usually thin clients that invoke a Supabase Edge Function — the\n * function holds credentials and does the real work.\n */\nexport interface Connector {\n /** Stable connector id, e.g. 'google-calendar', 'plugbank'. */\n id: string\n /** Provider key matching ConnectionConfig.provider. */\n provider: string\n /** Plugin this connector extends, e.g. 'agenda', 'financial'. */\n pluginId: string\n authKind: IntegrationAuthKind\n capabilities: ConnectorCapability[]\n /** Validate the stored credentials/config without syncing. */\n testConnection?(config: ConnectionConfig): Promise<TestConnectionResult>\n /** Run a sync for the given direction; returns the audit record. */\n sync?(input: { config: ConnectionConfig; direction: SyncDirection; trigger: SyncTrigger }): Promise<SyncRun>\n}\n\n// ---------------------------------------------------------------------------\n// Connector UI contract — how an addon plugin EXTENDS a host plugin's settings\n// ---------------------------------------------------------------------------\n// An addon plugin declares one or more ConnectorDefinitions on its manifest\n// (`connectors: [...]`). The runtime groups them by `hostPluginId`, and the host\n// plugin's settings panel renders them in a unified \"Integrations\" tab — the\n// same connect/credentials experience for every connector. The connector-\n// specific bits (import a statement, sync now, history) live in `ExtraPanel`.\n\n/** A credential input the unified setup form renders for an api-key/mtls connector. */\nexport interface ConnectorField {\n key: string\n label: string\n type: 'text' | 'password'\n placeholder?: string\n}\n\nexport interface ConnectorStatus {\n connected: boolean\n detail?: string\n}\n\n/**\n * UI-facing connector descriptor. Built on the data-plane `Connector` concept\n * (`pluginId` → `hostPluginId`), plus the control-plane hooks the unified\n * Integrations hub calls. Lives in core so `PluginManifest.connectors` can type\n * it; the rendering hub lives in `@fayz-ai/saas`.\n */\nexport interface ConnectorDefinition {\n /** Stable connector id, e.g. 'google-calendar', 'plugbank'. */\n id: string\n /** The plugin this connector extends, e.g. 'financial', 'agenda'. */\n hostPluginId: string\n name: string\n description?: string\n /** Lucide icon name. */\n icon?: string\n authKind: IntegrationAuthKind\n /** Declarative credentials — the unified form renders these (api-key / mtls). */\n fields?: ConnectorField[]\n /** Current connection state for the status badge. */\n getStatus(): Promise<ConnectorStatus>\n /** Validate credentials without persisting (api-key / mtls). */\n testConnection?(values: Record<string, string>): Promise<TestConnectionResult>\n /** Persist the connection (api-key / mtls). */\n saveConnection?(values: Record<string, string>): Promise<void>\n /** Begin an OAuth connect flow — returns the consent URL to redirect to. */\n startOAuth?(redirectTo?: string): Promise<string>\n /** Tear down the connection. */\n disconnect?(): Promise<void>\n /** Optional connector-specific UI below the connect panel (import / sync / history). */\n ExtraPanel?: React.ComponentType\n}\n\n/**\n * Wrap an object's async methods so a handler fires AFTER selected methods\n * resolve — the non-invasive hook for outbound, event-driven sync when there's\n * no app-level event bus. Example: wrap an AgendaDataProvider so that after\n * createBooking/updateBooking/deleteBooking succeed, an external calendar is\n * updated. The handler runs fire-and-forget; its failures never break the call.\n */\nexport function withAfterHooks<T extends object>(\n target: T,\n methods: Partial<Record<keyof T, (args: unknown[], result: unknown) => void | Promise<void>>>,\n): T {\n return new Proxy(target, {\n get(obj, prop, receiver) {\n const orig = Reflect.get(obj, prop, receiver)\n const hook = (methods as Record<string | symbol, ((args: unknown[], result: unknown) => void | Promise<void>) | undefined>)[prop]\n if (typeof orig !== 'function' || !hook) return orig\n return (...args: unknown[]) => {\n const result = (orig as (...a: unknown[]) => unknown).apply(obj, args)\n if (result instanceof Promise) {\n return result.then((value) => {\n try { void Promise.resolve(hook(args, value)).catch(() => {}) } catch { /* never break the call */ }\n return value\n })\n }\n try { void Promise.resolve(hook(args, result)).catch(() => {}) } catch { /* noop */ }\n return result\n }\n },\n })\n}\n"]}
|