@jaypie/fabric 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/ServiceSuite.d.ts +3 -1
- package/dist/cjs/commander/index.cjs +42 -11
- package/dist/cjs/commander/index.cjs.map +1 -1
- package/dist/cjs/data/index.cjs +40 -11
- package/dist/cjs/data/index.cjs.map +1 -1
- package/dist/cjs/http/index.cjs +43 -13
- package/dist/cjs/http/index.cjs.map +1 -1
- package/dist/cjs/index.cjs +50 -21
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/lambda/index.cjs +42 -11
- package/dist/cjs/lambda/index.cjs.map +1 -1
- package/dist/cjs/llm/index.cjs +42 -11
- package/dist/cjs/llm/index.cjs.map +1 -1
- package/dist/cjs/mcp/FabricMcpServer.d.ts +1 -1
- package/dist/cjs/mcp/index.cjs +43 -12
- package/dist/cjs/mcp/index.cjs.map +1 -1
- package/dist/cjs/models/base.d.ts +6 -6
- package/dist/cjs/resolveService.d.ts +7 -4
- package/dist/cjs/service.d.ts +6 -4
- package/dist/cjs/types.d.ts +9 -3
- package/dist/cjs/websocket/fabricWebSocket.d.ts +120 -0
- package/dist/cjs/websocket/index.d.ts +2 -0
- package/dist/esm/ServiceSuite.d.ts +3 -1
- package/dist/esm/commander/index.js +42 -11
- package/dist/esm/commander/index.js.map +1 -1
- package/dist/esm/data/index.js +40 -11
- package/dist/esm/data/index.js.map +1 -1
- package/dist/esm/http/index.js +43 -13
- package/dist/esm/http/index.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +50 -21
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lambda/index.js +42 -11
- package/dist/esm/lambda/index.js.map +1 -1
- package/dist/esm/llm/index.js +42 -11
- package/dist/esm/llm/index.js.map +1 -1
- package/dist/esm/mcp/FabricMcpServer.d.ts +1 -1
- package/dist/esm/mcp/index.js +43 -12
- package/dist/esm/mcp/index.js.map +1 -1
- package/dist/esm/models/base.d.ts +6 -6
- package/dist/esm/resolveService.d.ts +7 -4
- package/dist/esm/service.d.ts +6 -4
- package/dist/esm/types.d.ts +9 -3
- package/dist/esm/websocket/fabricWebSocket.d.ts +120 -0
- package/dist/esm/websocket/index.d.ts +2 -0
- package/package.json +6 -1
package/dist/esm/index.js
CHANGED
|
@@ -32,7 +32,7 @@ const FABRIC_MODEL_FIELDS = {
|
|
|
32
32
|
// Identity (required)
|
|
33
33
|
ID: "id",
|
|
34
34
|
// Schema
|
|
35
|
-
|
|
35
|
+
CATEGORY: "category",
|
|
36
36
|
MODEL: "model",
|
|
37
37
|
TYPE: "type",
|
|
38
38
|
// Storage
|
|
@@ -797,8 +797,8 @@ const DEFAULT_INDEXES = [
|
|
|
797
797
|
sparse: true,
|
|
798
798
|
},
|
|
799
799
|
{
|
|
800
|
-
name: "
|
|
801
|
-
pk: ["scope", "model", "
|
|
800
|
+
name: "indexCategory",
|
|
801
|
+
pk: ["scope", "model", "category"],
|
|
802
802
|
sk: ["sequence"],
|
|
803
803
|
sparse: true,
|
|
804
804
|
},
|
|
@@ -1457,42 +1457,68 @@ async function processField(fieldName, value, definition) {
|
|
|
1457
1457
|
function isService(value) {
|
|
1458
1458
|
return typeof value === "function" && "$fabric" in value;
|
|
1459
1459
|
}
|
|
1460
|
+
/**
|
|
1461
|
+
* Run serializer hook if provided
|
|
1462
|
+
* Returns transformed output or original if serializer returns undefined/null/void
|
|
1463
|
+
*/
|
|
1464
|
+
async function runSerializer(data, serializer, context) {
|
|
1465
|
+
if (!serializer) {
|
|
1466
|
+
return data.output;
|
|
1467
|
+
}
|
|
1468
|
+
const result = await serializer(data, context);
|
|
1469
|
+
if (result !== undefined && result !== null) {
|
|
1470
|
+
return result;
|
|
1471
|
+
}
|
|
1472
|
+
return data.output;
|
|
1473
|
+
}
|
|
1460
1474
|
/**
|
|
1461
1475
|
* Fabric a service function
|
|
1462
1476
|
*
|
|
1463
|
-
* Service builds a function that
|
|
1477
|
+
* Service builds a function that:
|
|
1464
1478
|
* - Parses the input if it is a string to object
|
|
1465
1479
|
* - Fabrics each input field to its type
|
|
1466
1480
|
* - Calls the validation function or regular expression or checks the array
|
|
1467
|
-
* - Calls the service function
|
|
1481
|
+
* - Calls the service function
|
|
1482
|
+
* - Calls the serializer hook (can transform output)
|
|
1483
|
+
* - Returns the response
|
|
1468
1484
|
*
|
|
1469
1485
|
* The returned function has config properties for introspection.
|
|
1470
1486
|
*/
|
|
1471
1487
|
function fabricService(config) {
|
|
1472
|
-
const { input: inputDefinitions, service } = config;
|
|
1488
|
+
const { input: inputDefinitions, serializer, service } = config;
|
|
1473
1489
|
const handler = async (rawInput, context) => {
|
|
1474
1490
|
// Parse input (handles string JSON)
|
|
1475
1491
|
const parsedInput = parseInput(rawInput);
|
|
1476
1492
|
// If no input definitions, pass through to service or return parsed input
|
|
1477
1493
|
if (!inputDefinitions) {
|
|
1494
|
+
let output;
|
|
1478
1495
|
if (service) {
|
|
1479
|
-
|
|
1496
|
+
output = await service(parsedInput, context);
|
|
1497
|
+
}
|
|
1498
|
+
else {
|
|
1499
|
+
output = parsedInput;
|
|
1480
1500
|
}
|
|
1481
|
-
|
|
1501
|
+
// Run serializer
|
|
1502
|
+
return (await runSerializer({ input: parsedInput, output }, serializer, context));
|
|
1482
1503
|
}
|
|
1483
1504
|
// Process all fields in parallel
|
|
1484
1505
|
const entries = Object.entries(inputDefinitions);
|
|
1485
1506
|
const processedValues = await Promise.all(entries.map(([fieldName, definition]) => processField(fieldName, parsedInput[fieldName], definition)));
|
|
1486
1507
|
// Build processed input object
|
|
1487
|
-
const
|
|
1508
|
+
const processedInputObj = {};
|
|
1488
1509
|
entries.forEach(([fieldName], index) => {
|
|
1489
|
-
|
|
1510
|
+
processedInputObj[fieldName] = processedValues[index];
|
|
1490
1511
|
});
|
|
1491
|
-
//
|
|
1512
|
+
// Call service or return processed input
|
|
1513
|
+
let output;
|
|
1492
1514
|
if (service) {
|
|
1493
|
-
|
|
1515
|
+
output = await service(processedInputObj, context);
|
|
1516
|
+
}
|
|
1517
|
+
else {
|
|
1518
|
+
output = processedInputObj;
|
|
1494
1519
|
}
|
|
1495
|
-
|
|
1520
|
+
// Run serializer hook
|
|
1521
|
+
return (await runSerializer({ input: processedInputObj, output }, serializer, context));
|
|
1496
1522
|
};
|
|
1497
1523
|
// Attach config properties directly to handler for flat access
|
|
1498
1524
|
const typedHandler = handler;
|
|
@@ -1503,6 +1529,8 @@ function fabricService(config) {
|
|
|
1503
1529
|
typedHandler.description = config.description;
|
|
1504
1530
|
if (config.input !== undefined)
|
|
1505
1531
|
typedHandler.input = config.input;
|
|
1532
|
+
if (config.serializer !== undefined)
|
|
1533
|
+
typedHandler.serializer = config.serializer;
|
|
1506
1534
|
if (config.service !== undefined)
|
|
1507
1535
|
typedHandler.service = config.service;
|
|
1508
1536
|
return typedHandler;
|
|
@@ -1521,6 +1549,7 @@ function fabricService(config) {
|
|
|
1521
1549
|
* - `alias` overrides service.alias
|
|
1522
1550
|
* - `description` overrides service.description
|
|
1523
1551
|
* - `input` overrides service.input
|
|
1552
|
+
* - `serializer` overrides service.serializer
|
|
1524
1553
|
*
|
|
1525
1554
|
* The original Service is never mutated - a new Service is created when overrides
|
|
1526
1555
|
* are applied.
|
|
@@ -1544,7 +1573,7 @@ function fabricService(config) {
|
|
|
1544
1573
|
* ```
|
|
1545
1574
|
*/
|
|
1546
1575
|
function resolveService(config) {
|
|
1547
|
-
const { alias, description, input, service } = config;
|
|
1576
|
+
const { alias, description, input, serializer, service } = config;
|
|
1548
1577
|
if (isService(service)) {
|
|
1549
1578
|
// Service is pre-instantiated - config fields act as overrides
|
|
1550
1579
|
// Create new Service with merged properties (config overrides service)
|
|
@@ -1552,6 +1581,7 @@ function resolveService(config) {
|
|
|
1552
1581
|
alias: alias ?? service.alias,
|
|
1553
1582
|
description: description ?? service.description,
|
|
1554
1583
|
input: input ?? service.input,
|
|
1584
|
+
serializer: serializer ?? service.serializer,
|
|
1555
1585
|
service: service.service,
|
|
1556
1586
|
});
|
|
1557
1587
|
}
|
|
@@ -1560,6 +1590,7 @@ function resolveService(config) {
|
|
|
1560
1590
|
alias,
|
|
1561
1591
|
description,
|
|
1562
1592
|
input,
|
|
1593
|
+
serializer,
|
|
1563
1594
|
service,
|
|
1564
1595
|
});
|
|
1565
1596
|
}
|
|
@@ -1626,7 +1657,9 @@ function extractEnumValues(type) {
|
|
|
1626
1657
|
return undefined;
|
|
1627
1658
|
// Check if it's a validated string enum (array of strings, possibly with RegExp)
|
|
1628
1659
|
const stringValues = type.filter((item) => typeof item === "string");
|
|
1629
|
-
if (stringValues.length > 0 &&
|
|
1660
|
+
if (stringValues.length > 0 &&
|
|
1661
|
+
stringValues.length ===
|
|
1662
|
+
type.filter((item) => typeof item === "string").length) {
|
|
1630
1663
|
// All non-RegExp items are strings
|
|
1631
1664
|
return stringValues;
|
|
1632
1665
|
}
|
|
@@ -1665,7 +1698,6 @@ function hasRequiredInputs(inputs) {
|
|
|
1665
1698
|
*/
|
|
1666
1699
|
function createServiceSuite(config) {
|
|
1667
1700
|
const { name, version } = config;
|
|
1668
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1669
1701
|
const serviceRegistry = new Map();
|
|
1670
1702
|
const categorySet = new Set();
|
|
1671
1703
|
const suite = {
|
|
@@ -1692,9 +1724,8 @@ function createServiceSuite(config) {
|
|
|
1692
1724
|
}
|
|
1693
1725
|
return entry.service(inputs);
|
|
1694
1726
|
},
|
|
1695
|
-
register(
|
|
1696
|
-
|
|
1697
|
-
service, category) {
|
|
1727
|
+
register(service, options) {
|
|
1728
|
+
const { category } = options;
|
|
1698
1729
|
const serviceName = service.alias;
|
|
1699
1730
|
if (!serviceName) {
|
|
1700
1731
|
throw new Error("Service must have an alias to be registered");
|
|
@@ -1710,11 +1741,9 @@ function createServiceSuite(config) {
|
|
|
1710
1741
|
serviceRegistry.set(serviceName, { service, meta });
|
|
1711
1742
|
categorySet.add(category);
|
|
1712
1743
|
},
|
|
1713
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1714
1744
|
getServiceFunctions() {
|
|
1715
1745
|
return Array.from(serviceRegistry.values()).map((entry) => entry.service);
|
|
1716
1746
|
},
|
|
1717
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1718
1747
|
getServiceFunction(serviceName) {
|
|
1719
1748
|
return serviceRegistry.get(serviceName)?.service;
|
|
1720
1749
|
},
|