@stndrds/schema 0.1.0-alpha.15 → 0.1.0-alpha.16
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/chunk-BTVPMGYW.mjs +6327 -0
- package/dist/chunk-C7HZ55GJ.mjs +6882 -0
- package/dist/chunk-JDUTFH3J.mjs +6940 -0
- package/dist/chunk-QAGN53HE.mjs +6327 -0
- package/dist/chunk-UUOAVXAI.mjs +6327 -0
- package/dist/chunk-VYZ3BOSB.mjs +6946 -0
- package/dist/chunk-XAX75NSP.mjs +6321 -0
- package/dist/chunk-ZG3PT3RL.mjs +6944 -0
- package/dist/index.d.mts +229 -4
- package/dist/index.d.ts +229 -4
- package/dist/index.js +769 -134
- package/dist/index.mjs +25 -1
- package/dist/runtime-BPYJWZfC.d.mts +5130 -0
- package/dist/runtime-BPYJWZfC.d.ts +5130 -0
- package/dist/runtime-DRc_OhnM.d.mts +5142 -0
- package/dist/runtime-DRc_OhnM.d.ts +5142 -0
- package/dist/runtime-D_S3m9jf.d.mts +5142 -0
- package/dist/runtime-D_S3m9jf.d.ts +5142 -0
- package/dist/runtime-Db3rRxbJ.d.mts +4821 -0
- package/dist/runtime-Db3rRxbJ.d.ts +4821 -0
- package/dist/runtime-DlCiIIfr.d.mts +5130 -0
- package/dist/runtime-DlCiIIfr.d.ts +5130 -0
- package/dist/runtime-WqYxjhjJ.d.mts +5125 -0
- package/dist/runtime-WqYxjhjJ.d.ts +5125 -0
- package/dist/runtime.d.mts +1 -1
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +389 -129
- package/dist/runtime.mjs +3 -1
- package/package.json +2 -2
package/dist/runtime.js
CHANGED
|
@@ -121,6 +121,7 @@ __export(runtime_exports, {
|
|
|
121
121
|
AuditService: () => AuditService,
|
|
122
122
|
DEFAULT_LABEL_FALLBACK: () => DEFAULT_LABEL_FALLBACK,
|
|
123
123
|
FileService: () => FileService,
|
|
124
|
+
FlowService: () => FlowService,
|
|
124
125
|
GeocodingService: () => GeocodingService,
|
|
125
126
|
GlobalSearchService: () => GlobalSearchService,
|
|
126
127
|
NoopGeocodingAdapter: () => NoopGeocodingAdapter,
|
|
@@ -1533,6 +1534,273 @@ var FileService = class {
|
|
|
1533
1534
|
}
|
|
1534
1535
|
};
|
|
1535
1536
|
|
|
1537
|
+
// src/runtime/services/flow.service.ts
|
|
1538
|
+
var FlowService = class {
|
|
1539
|
+
constructor(adapter, systemFlows = []) {
|
|
1540
|
+
this.adapter = adapter;
|
|
1541
|
+
this.systemFlows = new Map(systemFlows.map((f) => [f.name, f]));
|
|
1542
|
+
}
|
|
1543
|
+
/**
|
|
1544
|
+
* Get all flows for a tenant (system + custom)
|
|
1545
|
+
*/
|
|
1546
|
+
async getAllFlows(tenantId) {
|
|
1547
|
+
const systemFlowsList = Array.from(this.systemFlows.values());
|
|
1548
|
+
if (!this.adapter.flows) {
|
|
1549
|
+
return systemFlowsList;
|
|
1550
|
+
}
|
|
1551
|
+
const dbFlows = await this.adapter.flows.findAllForTenant(tenantId);
|
|
1552
|
+
const customFlows = dbFlows.filter((f) => !f.system).map(this.convertDBFlowToDefinition);
|
|
1553
|
+
return [...systemFlowsList, ...customFlows];
|
|
1554
|
+
}
|
|
1555
|
+
/**
|
|
1556
|
+
* Get published flows only
|
|
1557
|
+
*/
|
|
1558
|
+
async getPublishedFlows(tenantId) {
|
|
1559
|
+
const allFlows = await this.getAllFlows(tenantId);
|
|
1560
|
+
return allFlows.filter((f) => f.status === "published");
|
|
1561
|
+
}
|
|
1562
|
+
/**
|
|
1563
|
+
* Get a specific flow by name
|
|
1564
|
+
*/
|
|
1565
|
+
async getFlow(name, tenantId) {
|
|
1566
|
+
const systemFlow = this.systemFlows.get(name);
|
|
1567
|
+
if (systemFlow) {
|
|
1568
|
+
return systemFlow;
|
|
1569
|
+
}
|
|
1570
|
+
if (!this.adapter.flows) {
|
|
1571
|
+
return null;
|
|
1572
|
+
}
|
|
1573
|
+
const dbFlow = await this.adapter.flows.findByName(tenantId, name);
|
|
1574
|
+
if (dbFlow) {
|
|
1575
|
+
return this.convertDBFlowToDefinition(dbFlow);
|
|
1576
|
+
}
|
|
1577
|
+
return null;
|
|
1578
|
+
}
|
|
1579
|
+
/**
|
|
1580
|
+
* Get a flow by ID
|
|
1581
|
+
*/
|
|
1582
|
+
async getFlowById(flowId) {
|
|
1583
|
+
if (!this.adapter.flows) {
|
|
1584
|
+
return null;
|
|
1585
|
+
}
|
|
1586
|
+
const dbFlow = await this.adapter.flows.findById(flowId);
|
|
1587
|
+
if (dbFlow) {
|
|
1588
|
+
return this.convertDBFlowToDefinition(dbFlow);
|
|
1589
|
+
}
|
|
1590
|
+
return null;
|
|
1591
|
+
}
|
|
1592
|
+
/**
|
|
1593
|
+
* Create a new custom flow (as draft)
|
|
1594
|
+
*/
|
|
1595
|
+
async createFlow(input, tenantId) {
|
|
1596
|
+
if (!this.adapter.flows) {
|
|
1597
|
+
throw new Error("Flows feature is not enabled. Database adapter does not support flows.");
|
|
1598
|
+
}
|
|
1599
|
+
this.validateFlowName(input.name);
|
|
1600
|
+
const existing = await this.adapter.flows.findByName(tenantId, input.name);
|
|
1601
|
+
if (existing) {
|
|
1602
|
+
throw new Error(`Flow "${input.name}" already exists`);
|
|
1603
|
+
}
|
|
1604
|
+
if (this.systemFlows.has(input.name)) {
|
|
1605
|
+
throw new Error(
|
|
1606
|
+
`Cannot create flow "${input.name}": a system flow with this name already exists`
|
|
1607
|
+
);
|
|
1608
|
+
}
|
|
1609
|
+
this.validateFlowStructure(input);
|
|
1610
|
+
const dbFlow = await this.adapter.flows.create({
|
|
1611
|
+
tenantId,
|
|
1612
|
+
name: input.name,
|
|
1613
|
+
label: input.label,
|
|
1614
|
+
description: input.description,
|
|
1615
|
+
icon: input.icon,
|
|
1616
|
+
status: "draft",
|
|
1617
|
+
version: 1,
|
|
1618
|
+
slots: input.slots,
|
|
1619
|
+
pages: input.pages,
|
|
1620
|
+
relations: input.relations,
|
|
1621
|
+
system: false,
|
|
1622
|
+
metadata: input.metadata
|
|
1623
|
+
});
|
|
1624
|
+
return this.convertDBFlowToDefinition(dbFlow);
|
|
1625
|
+
}
|
|
1626
|
+
/**
|
|
1627
|
+
* Update a custom flow
|
|
1628
|
+
*/
|
|
1629
|
+
async updateFlow(flowId, input) {
|
|
1630
|
+
if (!this.adapter.flows) {
|
|
1631
|
+
throw new Error("Flows feature is not enabled.");
|
|
1632
|
+
}
|
|
1633
|
+
const dbFlow = await this.adapter.flows.findById(flowId);
|
|
1634
|
+
if (!dbFlow) {
|
|
1635
|
+
throw new Error(`Flow with id "${flowId}" not found`);
|
|
1636
|
+
}
|
|
1637
|
+
if (dbFlow.system) {
|
|
1638
|
+
throw new Error("Cannot modify system flows. System flows are protected.");
|
|
1639
|
+
}
|
|
1640
|
+
if (input.slots || input.pages || input.relations) {
|
|
1641
|
+
this.validateFlowStructure({
|
|
1642
|
+
name: dbFlow.name,
|
|
1643
|
+
label: input.label ?? dbFlow.label,
|
|
1644
|
+
slots: input.slots ?? dbFlow.slots,
|
|
1645
|
+
pages: input.pages ?? dbFlow.pages,
|
|
1646
|
+
relations: input.relations ?? dbFlow.relations
|
|
1647
|
+
});
|
|
1648
|
+
}
|
|
1649
|
+
const updated = await this.adapter.flows.update(flowId, {
|
|
1650
|
+
label: input.label,
|
|
1651
|
+
description: input.description,
|
|
1652
|
+
icon: input.icon,
|
|
1653
|
+
slots: input.slots,
|
|
1654
|
+
pages: input.pages,
|
|
1655
|
+
relations: input.relations,
|
|
1656
|
+
metadata: input.metadata
|
|
1657
|
+
});
|
|
1658
|
+
return this.convertDBFlowToDefinition(updated);
|
|
1659
|
+
}
|
|
1660
|
+
/**
|
|
1661
|
+
* Publish a flow
|
|
1662
|
+
*/
|
|
1663
|
+
async publishFlow(flowId) {
|
|
1664
|
+
if (!this.adapter.flows) {
|
|
1665
|
+
throw new Error("Flows feature is not enabled.");
|
|
1666
|
+
}
|
|
1667
|
+
const dbFlow = await this.adapter.flows.findById(flowId);
|
|
1668
|
+
if (!dbFlow) {
|
|
1669
|
+
throw new Error(`Flow with id "${flowId}" not found`);
|
|
1670
|
+
}
|
|
1671
|
+
if (dbFlow.system) {
|
|
1672
|
+
throw new Error("Cannot publish system flows. They are always published.");
|
|
1673
|
+
}
|
|
1674
|
+
if (dbFlow.status === "published") {
|
|
1675
|
+
return this.convertDBFlowToDefinition(dbFlow);
|
|
1676
|
+
}
|
|
1677
|
+
this.validateFlowStructure({
|
|
1678
|
+
name: dbFlow.name,
|
|
1679
|
+
label: dbFlow.label,
|
|
1680
|
+
slots: dbFlow.slots,
|
|
1681
|
+
pages: dbFlow.pages,
|
|
1682
|
+
relations: dbFlow.relations
|
|
1683
|
+
});
|
|
1684
|
+
const updated = await this.adapter.flows.update(flowId, {
|
|
1685
|
+
status: "published",
|
|
1686
|
+
version: dbFlow.version + 1
|
|
1687
|
+
});
|
|
1688
|
+
return this.convertDBFlowToDefinition(updated);
|
|
1689
|
+
}
|
|
1690
|
+
/**
|
|
1691
|
+
* Archive a flow
|
|
1692
|
+
*/
|
|
1693
|
+
async archiveFlow(flowId) {
|
|
1694
|
+
if (!this.adapter.flows) {
|
|
1695
|
+
throw new Error("Flows feature is not enabled.");
|
|
1696
|
+
}
|
|
1697
|
+
const dbFlow = await this.adapter.flows.findById(flowId);
|
|
1698
|
+
if (!dbFlow) {
|
|
1699
|
+
throw new Error(`Flow with id "${flowId}" not found`);
|
|
1700
|
+
}
|
|
1701
|
+
if (dbFlow.system) {
|
|
1702
|
+
throw new Error("Cannot archive system flows.");
|
|
1703
|
+
}
|
|
1704
|
+
const updated = await this.adapter.flows.update(flowId, {
|
|
1705
|
+
status: "archived"
|
|
1706
|
+
});
|
|
1707
|
+
return this.convertDBFlowToDefinition(updated);
|
|
1708
|
+
}
|
|
1709
|
+
/**
|
|
1710
|
+
* Delete a custom flow
|
|
1711
|
+
*/
|
|
1712
|
+
async deleteFlow(flowId) {
|
|
1713
|
+
if (!this.adapter.flows) {
|
|
1714
|
+
throw new Error("Flows feature is not enabled.");
|
|
1715
|
+
}
|
|
1716
|
+
const dbFlow = await this.adapter.flows.findById(flowId);
|
|
1717
|
+
if (!dbFlow) {
|
|
1718
|
+
throw new Error(`Flow with id "${flowId}" not found`);
|
|
1719
|
+
}
|
|
1720
|
+
if (dbFlow.system) {
|
|
1721
|
+
throw new Error("Cannot delete system flows. System flows are protected.");
|
|
1722
|
+
}
|
|
1723
|
+
await this.adapter.flows.delete(flowId);
|
|
1724
|
+
}
|
|
1725
|
+
// ============================================================================
|
|
1726
|
+
// PRIVATE HELPERS
|
|
1727
|
+
// ============================================================================
|
|
1728
|
+
/**
|
|
1729
|
+
* Validate flow name format (kebab-case)
|
|
1730
|
+
*/
|
|
1731
|
+
validateFlowName(name) {
|
|
1732
|
+
if (!name || name.length === 0) {
|
|
1733
|
+
throw new Error("Flow name cannot be empty");
|
|
1734
|
+
}
|
|
1735
|
+
if (name.length > 63) {
|
|
1736
|
+
throw new Error("Flow name is too long (max 63 characters)");
|
|
1737
|
+
}
|
|
1738
|
+
const kebabCaseRegex = /^[a-z][a-z0-9-]*$/;
|
|
1739
|
+
if (!kebabCaseRegex.test(name)) {
|
|
1740
|
+
throw new Error(
|
|
1741
|
+
"Invalid flow name format. Name must be in kebab-case (e.g., 'couple-creation', 'new-contact')"
|
|
1742
|
+
);
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
/**
|
|
1746
|
+
* Validate flow structure (slots, pages, relations)
|
|
1747
|
+
*/
|
|
1748
|
+
validateFlowStructure(input) {
|
|
1749
|
+
if (!input.slots || input.slots.length === 0) {
|
|
1750
|
+
throw new Error("Flow must have at least one slot");
|
|
1751
|
+
}
|
|
1752
|
+
if (!input.pages || input.pages.length === 0) {
|
|
1753
|
+
throw new Error("Flow must have at least one page");
|
|
1754
|
+
}
|
|
1755
|
+
const slotIds = new Set(input.slots.map((s) => s.id));
|
|
1756
|
+
if (slotIds.size !== input.slots.length) {
|
|
1757
|
+
throw new Error("Duplicate slot IDs detected");
|
|
1758
|
+
}
|
|
1759
|
+
for (const page of input.pages) {
|
|
1760
|
+
for (const row of page.rows) {
|
|
1761
|
+
for (const field of row.fields) {
|
|
1762
|
+
if (!slotIds.has(field.slotId)) {
|
|
1763
|
+
throw new Error(`Field "${field.id}" references unknown slot "${field.slotId}"`);
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
for (const relation of input.relations) {
|
|
1769
|
+
if (!slotIds.has(relation.sourceSlotId)) {
|
|
1770
|
+
throw new Error(`Relation references unknown source slot "${relation.sourceSlotId}"`);
|
|
1771
|
+
}
|
|
1772
|
+
if (!slotIds.has(relation.targetSlotId)) {
|
|
1773
|
+
throw new Error(`Relation references unknown target slot "${relation.targetSlotId}"`);
|
|
1774
|
+
}
|
|
1775
|
+
if (relation.sourceSlotId === relation.targetSlotId) {
|
|
1776
|
+
throw new Error(`Relation cannot link a slot to itself: "${relation.sourceSlotId}"`);
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
}
|
|
1780
|
+
/**
|
|
1781
|
+
* Convert database flow to FlowDefinition
|
|
1782
|
+
*/
|
|
1783
|
+
convertDBFlowToDefinition(dbFlow) {
|
|
1784
|
+
return {
|
|
1785
|
+
id: dbFlow.id,
|
|
1786
|
+
name: dbFlow.name,
|
|
1787
|
+
label: dbFlow.label,
|
|
1788
|
+
description: dbFlow.description,
|
|
1789
|
+
icon: dbFlow.icon,
|
|
1790
|
+
status: dbFlow.status,
|
|
1791
|
+
version: dbFlow.version,
|
|
1792
|
+
slots: dbFlow.slots,
|
|
1793
|
+
pages: dbFlow.pages,
|
|
1794
|
+
relations: dbFlow.relations,
|
|
1795
|
+
system: dbFlow.system,
|
|
1796
|
+
tenantId: dbFlow.tenantId,
|
|
1797
|
+
metadata: dbFlow.metadata,
|
|
1798
|
+
createdAt: dbFlow.createdAt,
|
|
1799
|
+
updatedAt: dbFlow.updatedAt
|
|
1800
|
+
};
|
|
1801
|
+
}
|
|
1802
|
+
};
|
|
1803
|
+
|
|
1536
1804
|
// src/runtime/services/geocoding.service.ts
|
|
1537
1805
|
var GeocodingService = class {
|
|
1538
1806
|
constructor(adapter) {
|
|
@@ -1652,8 +1920,11 @@ var GlobalSearchService = class {
|
|
|
1652
1920
|
var import_constants = require("@stndrds/constants");
|
|
1653
1921
|
var VALID_ICONS = new Set(import_constants.ICONS);
|
|
1654
1922
|
|
|
1923
|
+
// src/builders/flow-builder.ts
|
|
1924
|
+
var import_zod = require("zod");
|
|
1925
|
+
|
|
1655
1926
|
// src/builders/object-builder.ts
|
|
1656
|
-
var
|
|
1927
|
+
var import_zod2 = __toESM(require("zod"));
|
|
1657
1928
|
var ObjectBuilder = class {
|
|
1658
1929
|
constructor(config) {
|
|
1659
1930
|
this.validateName(config.name);
|
|
@@ -1786,14 +2057,14 @@ The labelExpression defines how records are displayed in lists and relations.
|
|
|
1786
2057
|
if (name === void 0) {
|
|
1787
2058
|
return;
|
|
1788
2059
|
}
|
|
1789
|
-
const objectNameSchema =
|
|
2060
|
+
const objectNameSchema = import_zod2.default.string().min(1, "Object name cannot be empty").max(63, "Object name is too long (max 63 characters)").regex(/^[a-z][a-z0-9-]*$/, {
|
|
1790
2061
|
message: "Invalid object name format.\nName must be in kebab-case (slug format):\n \u2705 Valid: 'products', 'user-profiles', 'order-items'\n \u274C Invalid: 'Products', 'userProfiles', 'user_profiles'"
|
|
1791
2062
|
});
|
|
1792
2063
|
try {
|
|
1793
2064
|
objectNameSchema.parse(name);
|
|
1794
2065
|
} catch (error) {
|
|
1795
|
-
if (error instanceof
|
|
1796
|
-
throw new Error(`[ObjectBuilder] ${error.
|
|
2066
|
+
if (error instanceof import_zod2.default.ZodError) {
|
|
2067
|
+
throw new Error(`[ObjectBuilder] ${error.issues[0].message}`);
|
|
1797
2068
|
}
|
|
1798
2069
|
throw error;
|
|
1799
2070
|
}
|
|
@@ -1804,7 +2075,7 @@ function object(config) {
|
|
|
1804
2075
|
}
|
|
1805
2076
|
|
|
1806
2077
|
// src/builders/view-builder.ts
|
|
1807
|
-
var
|
|
2078
|
+
var import_zod3 = require("zod");
|
|
1808
2079
|
|
|
1809
2080
|
// src/types/errors.ts
|
|
1810
2081
|
var RecordReferencedError = class extends Error {
|
|
@@ -1839,35 +2110,35 @@ var ObjectReferencedError = class extends Error {
|
|
|
1839
2110
|
};
|
|
1840
2111
|
|
|
1841
2112
|
// src/validation/validators.ts
|
|
1842
|
-
var
|
|
1843
|
-
var baseConfigSchema =
|
|
1844
|
-
disabled:
|
|
1845
|
-
placeholder:
|
|
1846
|
-
description:
|
|
1847
|
-
defaultValue:
|
|
1848
|
-
icon:
|
|
1849
|
-
order:
|
|
1850
|
-
hidden:
|
|
1851
|
-
archived:
|
|
1852
|
-
deprecated:
|
|
1853
|
-
metadata:
|
|
2113
|
+
var import_zod4 = require("zod");
|
|
2114
|
+
var baseConfigSchema = import_zod4.z.object({
|
|
2115
|
+
disabled: import_zod4.z.boolean().optional(),
|
|
2116
|
+
placeholder: import_zod4.z.string().optional(),
|
|
2117
|
+
description: import_zod4.z.string().optional(),
|
|
2118
|
+
defaultValue: import_zod4.z.unknown().optional(),
|
|
2119
|
+
icon: import_zod4.z.string().optional(),
|
|
2120
|
+
order: import_zod4.z.number().int().optional(),
|
|
2121
|
+
hidden: import_zod4.z.boolean().optional(),
|
|
2122
|
+
archived: import_zod4.z.boolean().optional(),
|
|
2123
|
+
deprecated: import_zod4.z.boolean().optional(),
|
|
2124
|
+
metadata: import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()).optional()
|
|
1854
2125
|
});
|
|
1855
|
-
var optionSchema =
|
|
1856
|
-
id:
|
|
1857
|
-
label:
|
|
1858
|
-
value:
|
|
1859
|
-
color:
|
|
1860
|
-
icon:
|
|
1861
|
-
description:
|
|
1862
|
-
group:
|
|
2126
|
+
var optionSchema = import_zod4.z.object({
|
|
2127
|
+
id: import_zod4.z.string().min(1),
|
|
2128
|
+
label: import_zod4.z.string().min(1),
|
|
2129
|
+
value: import_zod4.z.string().min(1),
|
|
2130
|
+
color: import_zod4.z.string().optional(),
|
|
2131
|
+
icon: import_zod4.z.string().optional(),
|
|
2132
|
+
description: import_zod4.z.string().optional(),
|
|
2133
|
+
group: import_zod4.z.enum(["idle", "in_progress", "finished"]).optional()
|
|
1863
2134
|
});
|
|
1864
|
-
var relationTargetSchema =
|
|
1865
|
-
object:
|
|
1866
|
-
displayTemplate:
|
|
1867
|
-
filter:
|
|
2135
|
+
var relationTargetSchema = import_zod4.z.object({
|
|
2136
|
+
object: import_zod4.z.string().min(1),
|
|
2137
|
+
displayTemplate: import_zod4.z.string().optional(),
|
|
2138
|
+
filter: import_zod4.z.record(import_zod4.z.string(), import_zod4.z.unknown()).optional()
|
|
1868
2139
|
});
|
|
1869
|
-
var documentTypeConfigSchema =
|
|
1870
|
-
type:
|
|
2140
|
+
var documentTypeConfigSchema = import_zod4.z.object({
|
|
2141
|
+
type: import_zod4.z.enum([
|
|
1871
2142
|
"id_card",
|
|
1872
2143
|
"passport",
|
|
1873
2144
|
"incorporation_certificate",
|
|
@@ -1878,86 +2149,86 @@ var documentTypeConfigSchema = import_zod3.z.object({
|
|
|
1878
2149
|
"proof_of_address",
|
|
1879
2150
|
"custom"
|
|
1880
2151
|
]),
|
|
1881
|
-
label:
|
|
1882
|
-
faces:
|
|
1883
|
-
attributeMapping:
|
|
1884
|
-
|
|
1885
|
-
attributeId:
|
|
1886
|
-
extractedKey:
|
|
1887
|
-
face:
|
|
1888
|
-
required:
|
|
2152
|
+
label: import_zod4.z.string(),
|
|
2153
|
+
faces: import_zod4.z.array(import_zod4.z.enum(["front", "back", "single"])),
|
|
2154
|
+
attributeMapping: import_zod4.z.array(
|
|
2155
|
+
import_zod4.z.object({
|
|
2156
|
+
attributeId: import_zod4.z.string(),
|
|
2157
|
+
extractedKey: import_zod4.z.string(),
|
|
2158
|
+
face: import_zod4.z.enum(["front", "back", "single"]).optional(),
|
|
2159
|
+
required: import_zod4.z.boolean().optional()
|
|
1889
2160
|
})
|
|
1890
2161
|
).optional()
|
|
1891
2162
|
});
|
|
1892
|
-
var fileVerificationConfigSchema =
|
|
1893
|
-
enabled:
|
|
1894
|
-
documentTypes:
|
|
1895
|
-
autoExtract:
|
|
1896
|
-
autoValidate:
|
|
2163
|
+
var fileVerificationConfigSchema = import_zod4.z.object({
|
|
2164
|
+
enabled: import_zod4.z.boolean(),
|
|
2165
|
+
documentTypes: import_zod4.z.array(documentTypeConfigSchema),
|
|
2166
|
+
autoExtract: import_zod4.z.boolean().optional(),
|
|
2167
|
+
autoValidate: import_zod4.z.boolean().optional()
|
|
1897
2168
|
});
|
|
1898
2169
|
var textConfigSchema = baseConfigSchema.extend({
|
|
1899
|
-
minLength:
|
|
1900
|
-
maxLength:
|
|
1901
|
-
pattern:
|
|
2170
|
+
minLength: import_zod4.z.number().int().min(0).optional(),
|
|
2171
|
+
maxLength: import_zod4.z.number().int().min(1).optional(),
|
|
2172
|
+
pattern: import_zod4.z.string().optional()
|
|
1902
2173
|
});
|
|
1903
2174
|
var textareaConfigSchema = baseConfigSchema;
|
|
1904
2175
|
var numberConfigSchema = baseConfigSchema.extend({
|
|
1905
|
-
min:
|
|
1906
|
-
max:
|
|
1907
|
-
unit:
|
|
1908
|
-
decimals:
|
|
2176
|
+
min: import_zod4.z.number().optional(),
|
|
2177
|
+
max: import_zod4.z.number().optional(),
|
|
2178
|
+
unit: import_zod4.z.enum(["integer", "decimal", "percentage"]).optional(),
|
|
2179
|
+
decimals: import_zod4.z.number().int().min(0).optional()
|
|
1909
2180
|
});
|
|
1910
2181
|
var checkboxConfigSchema = baseConfigSchema;
|
|
1911
2182
|
var dateConfigSchema = baseConfigSchema.extend({
|
|
1912
|
-
dateFormat:
|
|
1913
|
-
minDate:
|
|
1914
|
-
maxDate:
|
|
2183
|
+
dateFormat: import_zod4.z.enum(["short", "long", "full", "relative"]).optional(),
|
|
2184
|
+
minDate: import_zod4.z.string().optional(),
|
|
2185
|
+
maxDate: import_zod4.z.string().optional()
|
|
1915
2186
|
});
|
|
1916
2187
|
var phoneConfigSchema = baseConfigSchema.extend({
|
|
1917
|
-
defaultCountryCode:
|
|
2188
|
+
defaultCountryCode: import_zod4.z.string().length(3).optional()
|
|
1918
2189
|
});
|
|
1919
2190
|
var currencyConfigSchema = baseConfigSchema.extend({
|
|
1920
|
-
defaultCurrency:
|
|
1921
|
-
allowedCurrencies:
|
|
2191
|
+
defaultCurrency: import_zod4.z.string().length(3).optional(),
|
|
2192
|
+
allowedCurrencies: import_zod4.z.array(import_zod4.z.string().length(3)).optional()
|
|
1922
2193
|
});
|
|
1923
2194
|
var statusConfigSchema = baseConfigSchema.extend({
|
|
1924
|
-
options:
|
|
2195
|
+
options: import_zod4.z.array(optionSchema).min(1)
|
|
1925
2196
|
});
|
|
1926
2197
|
var locationConfigSchema = baseConfigSchema.extend({
|
|
1927
|
-
granularity:
|
|
1928
|
-
enableAutocomplete:
|
|
1929
|
-
enableMap:
|
|
1930
|
-
defaultCountry:
|
|
1931
|
-
allowedCountries:
|
|
1932
|
-
displayFormat:
|
|
2198
|
+
granularity: import_zod4.z.enum(["full", "address", "city", "state", "country", "coordinates"]),
|
|
2199
|
+
enableAutocomplete: import_zod4.z.boolean().optional(),
|
|
2200
|
+
enableMap: import_zod4.z.boolean().optional(),
|
|
2201
|
+
defaultCountry: import_zod4.z.string().length(3).optional(),
|
|
2202
|
+
allowedCountries: import_zod4.z.array(import_zod4.z.string().length(3)).optional(),
|
|
2203
|
+
displayFormat: import_zod4.z.enum(["single_line", "multi_line", "compact"]).optional()
|
|
1933
2204
|
});
|
|
1934
2205
|
var timestampConfigSchema = baseConfigSchema.extend({
|
|
1935
|
-
autoUpdate:
|
|
2206
|
+
autoUpdate: import_zod4.z.boolean().optional()
|
|
1936
2207
|
});
|
|
1937
2208
|
var selectConfigSchema = baseConfigSchema.extend({
|
|
1938
|
-
options:
|
|
2209
|
+
options: import_zod4.z.array(optionSchema).min(1)
|
|
1939
2210
|
});
|
|
1940
2211
|
var multiselectConfigSchema = baseConfigSchema.extend({
|
|
1941
|
-
options:
|
|
2212
|
+
options: import_zod4.z.array(optionSchema).min(1)
|
|
1942
2213
|
});
|
|
1943
2214
|
var fileConfigSchema = baseConfigSchema.extend({
|
|
1944
|
-
maxFiles:
|
|
1945
|
-
maxSize:
|
|
1946
|
-
allowedTypes:
|
|
2215
|
+
maxFiles: import_zod4.z.number().int().min(1).optional(),
|
|
2216
|
+
maxSize: import_zod4.z.number().int().min(1).optional(),
|
|
2217
|
+
allowedTypes: import_zod4.z.array(import_zod4.z.string()).optional(),
|
|
1947
2218
|
verification: fileVerificationConfigSchema.optional()
|
|
1948
2219
|
});
|
|
1949
2220
|
var userConfigSchema = baseConfigSchema.extend({
|
|
1950
|
-
allowedRoles:
|
|
2221
|
+
allowedRoles: import_zod4.z.array(import_zod4.z.string()).optional()
|
|
1951
2222
|
});
|
|
1952
2223
|
var relationConfigSchema = baseConfigSchema.extend({
|
|
1953
|
-
targets:
|
|
1954
|
-
cardinality:
|
|
1955
|
-
minItems:
|
|
1956
|
-
maxItems:
|
|
2224
|
+
targets: import_zod4.z.array(relationTargetSchema).min(1),
|
|
2225
|
+
cardinality: import_zod4.z.enum(["one", "many"]),
|
|
2226
|
+
minItems: import_zod4.z.number().int().min(0).optional(),
|
|
2227
|
+
maxItems: import_zod4.z.number().int().min(1).optional()
|
|
1957
2228
|
});
|
|
1958
2229
|
var ratingConfigSchema = baseConfigSchema.extend({
|
|
1959
|
-
max:
|
|
1960
|
-
iconType:
|
|
2230
|
+
max: import_zod4.z.number().int().min(1).optional(),
|
|
2231
|
+
iconType: import_zod4.z.enum(["star", "heart", "thumbs", "number"]).optional()
|
|
1961
2232
|
});
|
|
1962
2233
|
var attributeConfigSchemas = {
|
|
1963
2234
|
text: textConfigSchema,
|
|
@@ -1985,7 +2256,7 @@ function parseAttributeConfig(type, config) {
|
|
|
1985
2256
|
return schema.strip().parse(config);
|
|
1986
2257
|
}
|
|
1987
2258
|
function createTextValidator(attr) {
|
|
1988
|
-
let schema =
|
|
2259
|
+
let schema = import_zod4.z.string();
|
|
1989
2260
|
if (attr.minLength !== void 0) {
|
|
1990
2261
|
schema = schema.min(
|
|
1991
2262
|
attr.minLength,
|
|
@@ -2004,7 +2275,7 @@ function createTextValidator(attr) {
|
|
|
2004
2275
|
return schema;
|
|
2005
2276
|
}
|
|
2006
2277
|
function createNumberValidator(attr) {
|
|
2007
|
-
let schema =
|
|
2278
|
+
let schema = import_zod4.z.number();
|
|
2008
2279
|
if (attr.min !== void 0) {
|
|
2009
2280
|
schema = schema.min(attr.min, `${attr.label} must be at least ${attr.min}`);
|
|
2010
2281
|
}
|
|
@@ -2017,81 +2288,75 @@ function createNumberValidator(attr) {
|
|
|
2017
2288
|
return schema;
|
|
2018
2289
|
}
|
|
2019
2290
|
function createCheckboxValidator(_attr) {
|
|
2020
|
-
return
|
|
2291
|
+
return import_zod4.z.boolean();
|
|
2021
2292
|
}
|
|
2022
2293
|
function createDateValidator(attr) {
|
|
2023
|
-
return
|
|
2294
|
+
return import_zod4.z.string().datetime({ message: `${attr.label} must be a valid ISO date` });
|
|
2024
2295
|
}
|
|
2025
2296
|
function createPhoneValidator(_attr) {
|
|
2026
|
-
return
|
|
2027
|
-
countryCode:
|
|
2028
|
-
phoneNumber:
|
|
2297
|
+
return import_zod4.z.object({
|
|
2298
|
+
countryCode: import_zod4.z.string().length(3),
|
|
2299
|
+
phoneNumber: import_zod4.z.string().min(1)
|
|
2029
2300
|
});
|
|
2030
2301
|
}
|
|
2031
2302
|
function createCurrencyValidator(_attr) {
|
|
2032
|
-
return
|
|
2033
|
-
code:
|
|
2034
|
-
value:
|
|
2303
|
+
return import_zod4.z.object({
|
|
2304
|
+
code: import_zod4.z.string().length(3),
|
|
2305
|
+
value: import_zod4.z.number().min(0)
|
|
2035
2306
|
});
|
|
2036
2307
|
}
|
|
2037
2308
|
function createStatusValidator(attr) {
|
|
2038
2309
|
const validValues = attr.options.map((opt) => opt.value);
|
|
2039
|
-
return
|
|
2040
|
-
|
|
2041
|
-
message: `${attr.label} must be one of: ${validValues.join(", ")}`
|
|
2042
|
-
})
|
|
2310
|
+
return import_zod4.z.enum(validValues, {
|
|
2311
|
+
error: `${attr.label} must be one of: ${validValues.join(", ")}`
|
|
2043
2312
|
});
|
|
2044
2313
|
}
|
|
2045
2314
|
function createSelectValidator(attr) {
|
|
2046
2315
|
const validValues = attr.options.map((opt) => opt.value);
|
|
2047
|
-
return
|
|
2048
|
-
|
|
2049
|
-
message: `${attr.label} must be one of: ${validValues.join(", ")}`
|
|
2050
|
-
})
|
|
2316
|
+
return import_zod4.z.enum(validValues, {
|
|
2317
|
+
error: `${attr.label} must be one of: ${validValues.join(", ")}`
|
|
2051
2318
|
});
|
|
2052
2319
|
}
|
|
2053
2320
|
function createMultiselectValidator(attr) {
|
|
2054
2321
|
const validValues = attr.options.map((opt) => opt.value);
|
|
2055
|
-
return
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
message: `Each value must be one of: ${validValues.join(", ")}`
|
|
2059
|
-
})
|
|
2322
|
+
return import_zod4.z.array(
|
|
2323
|
+
import_zod4.z.enum(validValues, {
|
|
2324
|
+
error: `Each value must be one of: ${validValues.join(", ")}`
|
|
2060
2325
|
})
|
|
2061
2326
|
);
|
|
2062
2327
|
}
|
|
2063
2328
|
function createLocationValidator(_attr) {
|
|
2064
|
-
return
|
|
2065
|
-
address:
|
|
2066
|
-
address2:
|
|
2067
|
-
city:
|
|
2068
|
-
state:
|
|
2069
|
-
postalCode:
|
|
2070
|
-
country:
|
|
2071
|
-
latitude:
|
|
2072
|
-
longitude:
|
|
2329
|
+
return import_zod4.z.object({
|
|
2330
|
+
address: import_zod4.z.string().optional(),
|
|
2331
|
+
address2: import_zod4.z.string().optional(),
|
|
2332
|
+
city: import_zod4.z.string().optional(),
|
|
2333
|
+
state: import_zod4.z.string().optional(),
|
|
2334
|
+
postalCode: import_zod4.z.string().optional(),
|
|
2335
|
+
country: import_zod4.z.string().length(3).optional(),
|
|
2336
|
+
latitude: import_zod4.z.number().optional(),
|
|
2337
|
+
longitude: import_zod4.z.number().optional()
|
|
2073
2338
|
});
|
|
2074
2339
|
}
|
|
2075
2340
|
function createTimestampValidator(_attr) {
|
|
2076
|
-
return
|
|
2341
|
+
return import_zod4.z.number().int().positive();
|
|
2077
2342
|
}
|
|
2078
2343
|
function createFileValidator(_attr) {
|
|
2079
|
-
return
|
|
2344
|
+
return import_zod4.z.string().uuid();
|
|
2080
2345
|
}
|
|
2081
2346
|
function createUserValidator(_attr) {
|
|
2082
|
-
return
|
|
2347
|
+
return import_zod4.z.string().uuid();
|
|
2083
2348
|
}
|
|
2084
2349
|
function createSingleRelationValidator(attr) {
|
|
2085
|
-
const uuidSchema =
|
|
2350
|
+
const uuidSchema = import_zod4.z.string().uuid({
|
|
2086
2351
|
message: `${attr.label} must be a valid record ID`
|
|
2087
2352
|
});
|
|
2088
|
-
return
|
|
2353
|
+
return import_zod4.z.union([uuidSchema, import_zod4.z.null()]);
|
|
2089
2354
|
}
|
|
2090
2355
|
function createMultiRelationValidator(attr) {
|
|
2091
|
-
const uuidSchema =
|
|
2356
|
+
const uuidSchema = import_zod4.z.string().uuid({
|
|
2092
2357
|
message: `Each ${attr.label} item must be a valid record ID`
|
|
2093
2358
|
});
|
|
2094
|
-
let arraySchema =
|
|
2359
|
+
let arraySchema = import_zod4.z.array(uuidSchema);
|
|
2095
2360
|
if (attr.minItems !== void 0) {
|
|
2096
2361
|
arraySchema = arraySchema.min(
|
|
2097
2362
|
attr.minItems,
|
|
@@ -2113,7 +2378,7 @@ function createRelationValidator(attr) {
|
|
|
2113
2378
|
return createSingleRelationValidator(attr);
|
|
2114
2379
|
}
|
|
2115
2380
|
function createRatingValidator(attr) {
|
|
2116
|
-
let schema =
|
|
2381
|
+
let schema = import_zod4.z.number().int().min(0);
|
|
2117
2382
|
if (attr.max !== void 0) {
|
|
2118
2383
|
schema = schema.max(attr.max, `${attr.label} must be at most ${attr.max}`);
|
|
2119
2384
|
}
|
|
@@ -2152,7 +2417,7 @@ function createAttributeValidator(attr) {
|
|
|
2152
2417
|
case "rating":
|
|
2153
2418
|
return createRatingValidator(attr);
|
|
2154
2419
|
default:
|
|
2155
|
-
return
|
|
2420
|
+
return import_zod4.z.unknown();
|
|
2156
2421
|
}
|
|
2157
2422
|
}
|
|
2158
2423
|
function createObjectValidator(objectDef) {
|
|
@@ -2164,7 +2429,7 @@ function createObjectValidator(objectDef) {
|
|
|
2164
2429
|
}
|
|
2165
2430
|
shape[attr.name] = validator;
|
|
2166
2431
|
}
|
|
2167
|
-
return
|
|
2432
|
+
return import_zod4.z.object(shape);
|
|
2168
2433
|
}
|
|
2169
2434
|
function validateObject(objectDef, data) {
|
|
2170
2435
|
const validator = createObjectValidator(objectDef);
|
|
@@ -2177,7 +2442,7 @@ function validateObject(objectDef, data) {
|
|
|
2177
2442
|
}
|
|
2178
2443
|
return {
|
|
2179
2444
|
success: false,
|
|
2180
|
-
errors: result.error.
|
|
2445
|
+
errors: result.error.issues.map((err) => ({
|
|
2181
2446
|
path: err.path.map(String),
|
|
2182
2447
|
message: err.message
|
|
2183
2448
|
}))
|
|
@@ -2198,7 +2463,7 @@ function createDraftValidator(objectDef) {
|
|
|
2198
2463
|
const validator = createAttributeValidator(attr).optional();
|
|
2199
2464
|
shape[attr.name] = validator;
|
|
2200
2465
|
}
|
|
2201
|
-
return
|
|
2466
|
+
return import_zod4.z.object(shape);
|
|
2202
2467
|
}
|
|
2203
2468
|
function validateDraft(objectDef, data) {
|
|
2204
2469
|
const validator = createDraftValidator(objectDef);
|
|
@@ -2211,7 +2476,7 @@ function validateDraft(objectDef, data) {
|
|
|
2211
2476
|
}
|
|
2212
2477
|
return {
|
|
2213
2478
|
success: false,
|
|
2214
|
-
errors: result.error.
|
|
2479
|
+
errors: result.error.issues.map((err) => ({
|
|
2215
2480
|
path: err.path.map(String),
|
|
2216
2481
|
message: err.message
|
|
2217
2482
|
}))
|
|
@@ -4683,9 +4948,6 @@ var ViewService = class {
|
|
|
4683
4948
|
`Cannot create view "${input.name}": a system view with this name already exists`
|
|
4684
4949
|
);
|
|
4685
4950
|
}
|
|
4686
|
-
if (!input.tabs || input.tabs.length === 0) {
|
|
4687
|
-
throw new Error("View must have at least one tab");
|
|
4688
|
-
}
|
|
4689
4951
|
const dbView = await this.adapter.views.create({
|
|
4690
4952
|
tenantId,
|
|
4691
4953
|
objectName: input.objectName,
|
|
@@ -4693,7 +4955,7 @@ var ViewService = class {
|
|
|
4693
4955
|
label: input.label,
|
|
4694
4956
|
description: input.description,
|
|
4695
4957
|
icon: input.icon,
|
|
4696
|
-
tabs: input.tabs,
|
|
4958
|
+
tabs: input.tabs ?? [],
|
|
4697
4959
|
default: input.default ?? false,
|
|
4698
4960
|
system: false,
|
|
4699
4961
|
// Custom views are never system
|
|
@@ -4716,9 +4978,6 @@ var ViewService = class {
|
|
|
4716
4978
|
if (dbView.system) {
|
|
4717
4979
|
throw new Error("Cannot modify system views. System views are protected.");
|
|
4718
4980
|
}
|
|
4719
|
-
if (input.tabs && input.tabs.length === 0) {
|
|
4720
|
-
throw new Error("View must have at least one tab");
|
|
4721
|
-
}
|
|
4722
4981
|
const updated = await this.adapter.views.update(viewId, {
|
|
4723
4982
|
label: input.label,
|
|
4724
4983
|
description: input.description,
|
|
@@ -5149,6 +5408,7 @@ var NoopGeocodingAdapter = class {
|
|
|
5149
5408
|
AuditService,
|
|
5150
5409
|
DEFAULT_LABEL_FALLBACK,
|
|
5151
5410
|
FileService,
|
|
5411
|
+
FlowService,
|
|
5152
5412
|
GeocodingService,
|
|
5153
5413
|
GlobalSearchService,
|
|
5154
5414
|
NoopGeocodingAdapter,
|