@baseplate-dev/utils 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/LICENSE +390 -0
  2. package/README.md +3 -0
  3. package/dist/crypto/hash.d.ts +2 -0
  4. package/dist/crypto/hash.d.ts.map +1 -0
  5. package/dist/crypto/hash.js +14 -0
  6. package/dist/crypto/hash.js.map +1 -0
  7. package/dist/crypto/index.d.ts +2 -0
  8. package/dist/crypto/index.d.ts.map +1 -0
  9. package/dist/crypto/index.js +2 -0
  10. package/dist/crypto/index.js.map +1 -0
  11. package/dist/errors/enhance-error-with-context.d.ts +9 -0
  12. package/dist/errors/enhance-error-with-context.d.ts.map +1 -0
  13. package/dist/errors/enhance-error-with-context.js +19 -0
  14. package/dist/errors/enhance-error-with-context.js.map +1 -0
  15. package/dist/errors/index.d.ts +2 -0
  16. package/dist/errors/index.d.ts.map +1 -0
  17. package/dist/errors/index.js +2 -0
  18. package/dist/errors/index.js.map +1 -0
  19. package/dist/events/index.d.ts +2 -0
  20. package/dist/events/index.d.ts.map +1 -0
  21. package/dist/events/index.js +2 -0
  22. package/dist/events/index.js.map +1 -0
  23. package/dist/events/typed-event-emitter.d.ts +64 -0
  24. package/dist/events/typed-event-emitter.d.ts.map +1 -0
  25. package/dist/events/typed-event-emitter.js +128 -0
  26. package/dist/events/typed-event-emitter.js.map +1 -0
  27. package/dist/field-map/field-map.d.ts +118 -0
  28. package/dist/field-map/field-map.d.ts.map +1 -0
  29. package/dist/field-map/field-map.js +287 -0
  30. package/dist/field-map/field-map.js.map +1 -0
  31. package/dist/field-map/index.d.ts +2 -0
  32. package/dist/field-map/index.d.ts.map +1 -0
  33. package/dist/field-map/index.js +2 -0
  34. package/dist/field-map/index.js.map +1 -0
  35. package/dist/fs/dir-exists.d.ts +7 -0
  36. package/dist/fs/dir-exists.d.ts.map +1 -0
  37. package/dist/fs/dir-exists.js +12 -0
  38. package/dist/fs/dir-exists.js.map +1 -0
  39. package/dist/fs/ensure-dir.d.ts +6 -0
  40. package/dist/fs/ensure-dir.d.ts.map +1 -0
  41. package/dist/fs/ensure-dir.js +9 -0
  42. package/dist/fs/ensure-dir.js.map +1 -0
  43. package/dist/fs/file-exists.d.ts +7 -0
  44. package/dist/fs/file-exists.d.ts.map +1 -0
  45. package/dist/fs/file-exists.js +12 -0
  46. package/dist/fs/file-exists.js.map +1 -0
  47. package/dist/fs/find-nearest-package-json.d.ts +22 -0
  48. package/dist/fs/find-nearest-package-json.d.ts.map +1 -0
  49. package/dist/fs/find-nearest-package-json.js +34 -0
  50. package/dist/fs/find-nearest-package-json.js.map +1 -0
  51. package/dist/fs/handle-not-found-error.d.ts +9 -0
  52. package/dist/fs/handle-not-found-error.d.ts.map +1 -0
  53. package/dist/fs/handle-not-found-error.js +15 -0
  54. package/dist/fs/handle-not-found-error.js.map +1 -0
  55. package/dist/fs/index.d.ts +9 -0
  56. package/dist/fs/index.d.ts.map +1 -0
  57. package/dist/fs/index.js +9 -0
  58. package/dist/fs/index.js.map +1 -0
  59. package/dist/fs/read-json-with-schema.d.ts +10 -0
  60. package/dist/fs/read-json-with-schema.d.ts.map +1 -0
  61. package/dist/fs/read-json-with-schema.js +29 -0
  62. package/dist/fs/read-json-with-schema.js.map +1 -0
  63. package/dist/fs/write-json.d.ts +7 -0
  64. package/dist/fs/write-json.d.ts.map +1 -0
  65. package/dist/fs/write-json.js +10 -0
  66. package/dist/fs/write-json.js.map +1 -0
  67. package/dist/fs/write-stable-pretty-json.d.ts +10 -0
  68. package/dist/fs/write-stable-pretty-json.d.ts.map +1 -0
  69. package/dist/fs/write-stable-pretty-json.js +15 -0
  70. package/dist/fs/write-stable-pretty-json.js.map +1 -0
  71. package/dist/index.d.ts +13 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +13 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/json/index.d.ts +3 -0
  76. package/dist/json/index.d.ts.map +1 -0
  77. package/dist/json/index.js +3 -0
  78. package/dist/json/index.js.map +1 -0
  79. package/dist/json/stringify-pretty-compact.d.ts +11 -0
  80. package/dist/json/stringify-pretty-compact.d.ts.map +1 -0
  81. package/dist/json/stringify-pretty-compact.js +127 -0
  82. package/dist/json/stringify-pretty-compact.js.map +1 -0
  83. package/dist/json/stringify-pretty-stable.d.ts +10 -0
  84. package/dist/json/stringify-pretty-stable.d.ts.map +1 -0
  85. package/dist/json/stringify-pretty-stable.js +17 -0
  86. package/dist/json/stringify-pretty-stable.js.map +1 -0
  87. package/dist/maps/group-by.d.ts +13 -0
  88. package/dist/maps/group-by.d.ts.map +1 -0
  89. package/dist/maps/group-by.js +26 -0
  90. package/dist/maps/group-by.js.map +1 -0
  91. package/dist/maps/index.d.ts +5 -0
  92. package/dist/maps/index.d.ts.map +1 -0
  93. package/dist/maps/index.js +5 -0
  94. package/dist/maps/index.js.map +1 -0
  95. package/dist/maps/key-by.d.ts +14 -0
  96. package/dist/maps/key-by.d.ts.map +1 -0
  97. package/dist/maps/key-by.js +21 -0
  98. package/dist/maps/key-by.js.map +1 -0
  99. package/dist/maps/map-values-of-map.d.ts +12 -0
  100. package/dist/maps/map-values-of-map.d.ts.map +1 -0
  101. package/dist/maps/map-values-of-map.js +18 -0
  102. package/dist/maps/map-values-of-map.js.map +1 -0
  103. package/dist/maps/safe-merge-map.d.ts +33 -0
  104. package/dist/maps/safe-merge-map.d.ts.map +1 -0
  105. package/dist/maps/safe-merge-map.js +45 -0
  106. package/dist/maps/safe-merge-map.js.map +1 -0
  107. package/dist/node.d.ts +3 -0
  108. package/dist/node.d.ts.map +1 -0
  109. package/dist/node.js +4 -0
  110. package/dist/node.js.map +1 -0
  111. package/dist/objects/index.d.ts +3 -0
  112. package/dist/objects/index.d.ts.map +1 -0
  113. package/dist/objects/index.js +3 -0
  114. package/dist/objects/index.js.map +1 -0
  115. package/dist/objects/safe-merge.d.ts +32 -0
  116. package/dist/objects/safe-merge.d.ts.map +1 -0
  117. package/dist/objects/safe-merge.js +46 -0
  118. package/dist/objects/safe-merge.js.map +1 -0
  119. package/dist/objects/sort-object-keys.d.ts +8 -0
  120. package/dist/objects/sort-object-keys.d.ts.map +1 -0
  121. package/dist/objects/sort-object-keys.js +10 -0
  122. package/dist/objects/sort-object-keys.js.map +1 -0
  123. package/dist/paths/get-common-path-prefix.d.ts +10 -0
  124. package/dist/paths/get-common-path-prefix.d.ts.map +1 -0
  125. package/dist/paths/get-common-path-prefix.js +34 -0
  126. package/dist/paths/get-common-path-prefix.js.map +1 -0
  127. package/dist/paths/index.d.ts +3 -0
  128. package/dist/paths/index.d.ts.map +1 -0
  129. package/dist/paths/index.js +3 -0
  130. package/dist/paths/index.js.map +1 -0
  131. package/dist/paths/posix-join.d.ts +9 -0
  132. package/dist/paths/posix-join.d.ts.map +1 -0
  133. package/dist/paths/posix-join.js +12 -0
  134. package/dist/paths/posix-join.js.map +1 -0
  135. package/dist/sets/difference.d.ts +9 -0
  136. package/dist/sets/difference.d.ts.map +1 -0
  137. package/dist/sets/difference.js +17 -0
  138. package/dist/sets/difference.js.map +1 -0
  139. package/dist/sets/index.d.ts +2 -0
  140. package/dist/sets/index.d.ts.map +1 -0
  141. package/dist/sets/index.js +2 -0
  142. package/dist/sets/index.js.map +1 -0
  143. package/dist/string/index.d.ts +3 -0
  144. package/dist/string/index.d.ts.map +1 -0
  145. package/dist/string/index.js +3 -0
  146. package/dist/string/index.js.map +1 -0
  147. package/dist/string/quot.d.ts +13 -0
  148. package/dist/string/quot.d.ts.map +1 -0
  149. package/dist/string/quot.js +17 -0
  150. package/dist/string/quot.js.map +1 -0
  151. package/dist/string/random-uid.d.ts +6 -0
  152. package/dist/string/random-uid.d.ts.map +1 -0
  153. package/dist/string/random-uid.js +16 -0
  154. package/dist/string/random-uid.js.map +1 -0
  155. package/dist/toposort/errors.d.ts +9 -0
  156. package/dist/toposort/errors.d.ts.map +1 -0
  157. package/dist/toposort/errors.js +17 -0
  158. package/dist/toposort/errors.js.map +1 -0
  159. package/dist/toposort/index.d.ts +4 -0
  160. package/dist/toposort/index.d.ts.map +1 -0
  161. package/dist/toposort/index.js +4 -0
  162. package/dist/toposort/index.js.map +1 -0
  163. package/dist/toposort/toposort-local.d.ts +25 -0
  164. package/dist/toposort/toposort-local.d.ts.map +1 -0
  165. package/dist/toposort/toposort-local.js +152 -0
  166. package/dist/toposort/toposort-local.js.map +1 -0
  167. package/dist/toposort/toposort.d.ts +30 -0
  168. package/dist/toposort/toposort.d.ts.map +1 -0
  169. package/dist/toposort/toposort.js +156 -0
  170. package/dist/toposort/toposort.js.map +1 -0
  171. package/dist/type-guards/index.d.ts +2 -0
  172. package/dist/type-guards/index.d.ts.map +1 -0
  173. package/dist/type-guards/index.js +2 -0
  174. package/dist/type-guards/index.js.map +1 -0
  175. package/dist/type-guards/not-empty.d.ts +5 -0
  176. package/dist/type-guards/not-empty.d.ts.map +1 -0
  177. package/dist/type-guards/not-empty.js +7 -0
  178. package/dist/type-guards/not-empty.js.map +1 -0
  179. package/dist/validators/case-validators.d.ts +36 -0
  180. package/dist/validators/case-validators.d.ts.map +1 -0
  181. package/dist/validators/case-validators.js +36 -0
  182. package/dist/validators/case-validators.js.map +1 -0
  183. package/dist/validators/index.d.ts +4 -0
  184. package/dist/validators/index.d.ts.map +1 -0
  185. package/dist/validators/index.js +4 -0
  186. package/dist/validators/index.js.map +1 -0
  187. package/dist/validators/number-validators.d.ts +8 -0
  188. package/dist/validators/number-validators.d.ts.map +1 -0
  189. package/dist/validators/number-validators.js +12 -0
  190. package/dist/validators/number-validators.js.map +1 -0
  191. package/dist/validators/transform-with-dynamic-schema.d.ts +10 -0
  192. package/dist/validators/transform-with-dynamic-schema.d.ts.map +1 -0
  193. package/dist/validators/transform-with-dynamic-schema.js +33 -0
  194. package/dist/validators/transform-with-dynamic-schema.js.map +1 -0
  195. package/package.json +64 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toposort-local.d.ts","sourceRoot":"","sources":["../../src/toposort/toposort-local.ts"],"names":[],"mappings":"AAkHA,UAAU,eAAe,CAAC,CAAC;IACzB;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC;CACtC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAC7B,KAAK,EAAE,CAAC,EAAE,EACV,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EACf,OAAO,GAAE,eAAe,CAAC,CAAC,CAAM,GAC/B,CAAC,EAAE,CA2DL"}
@@ -0,0 +1,152 @@
1
+ import { ToposortCyclicalDependencyError, ToposortUnknownNodeError, } from './errors.js';
2
+ /**
3
+ * Creates a map of inbound edges from node indices to their source indices
4
+ */
5
+ function makeInboundEdges(nodes, edgeArr) {
6
+ const inboundEdgesMap = new Map();
7
+ for (const edge of edgeArr) {
8
+ const [source, target] = edge;
9
+ const sourceIndex = nodes.get(source);
10
+ const targetIndex = nodes.get(target);
11
+ // Check both source and target exist in the provided nodes set
12
+ if (sourceIndex === undefined)
13
+ throw new ToposortUnknownNodeError(source);
14
+ if (targetIndex === undefined)
15
+ throw new ToposortUnknownNodeError(target);
16
+ const targetEdges = inboundEdgesMap.get(targetIndex);
17
+ if (targetEdges) {
18
+ targetEdges.add(sourceIndex);
19
+ }
20
+ else {
21
+ inboundEdgesMap.set(targetIndex, new Set([sourceIndex]));
22
+ }
23
+ }
24
+ return inboundEdgesMap;
25
+ }
26
+ /**
27
+ * Creates a map of node indices to their out-degree
28
+ */
29
+ function makeNodeOutDegrees(inboundEdgesMap, nodeLength) {
30
+ const nodeOutDegrees = Array.from({ length: nodeLength }, () => 0);
31
+ for (const [, sources] of inboundEdgesMap.entries()) {
32
+ for (const source of sources) {
33
+ nodeOutDegrees[source]++;
34
+ }
35
+ }
36
+ return nodeOutDegrees;
37
+ }
38
+ /**
39
+ * Detects cycles in a graph by checking if all nodes are included in the topological sort
40
+ */
41
+ function detectCycle(nodes, visited, edges) {
42
+ // If all nodes were visited, no cycle exists
43
+ if (visited.size === nodes.length) {
44
+ return [];
45
+ }
46
+ // Run DFS from any unvisited node to find a cycle
47
+ const path = [];
48
+ const visitSet = new Set();
49
+ function dfs(node) {
50
+ if (visitSet.has(node)) {
51
+ path.push(node);
52
+ return true;
53
+ }
54
+ if (visited.has(node)) {
55
+ return false;
56
+ }
57
+ visitSet.add(node);
58
+ path.push(node);
59
+ const neighbors = edges.get(node) ?? new Set();
60
+ for (const neighbor of neighbors) {
61
+ if (dfs(neighbor)) {
62
+ return true;
63
+ }
64
+ }
65
+ path.pop();
66
+ visitSet.delete(node);
67
+ return false;
68
+ }
69
+ // For cycle detection, we need to find nodes that weren't visited
70
+ const unvistedNodeIdx = nodes.findIndex((node, idx) => !visited.has(idx));
71
+ if (unvistedNodeIdx === -1) {
72
+ return [];
73
+ }
74
+ // Start DFS from any unvisited node
75
+ dfs(unvistedNodeIdx);
76
+ // Convert path indices to actual nodes
77
+ return path.map((idx) => nodes[idx]);
78
+ }
79
+ /**
80
+ * Default comparison function for stable topological sort
81
+ */
82
+ function defaultCompareFunc(a, b) {
83
+ if (typeof a === 'string' && typeof b === 'string') {
84
+ return a.localeCompare(b);
85
+ }
86
+ if (a === b)
87
+ return 0;
88
+ return a < b ? -1 : 1;
89
+ }
90
+ /**
91
+ * Performs a locality-based topological sort on a directed acyclic graph.
92
+ *
93
+ * This is a variant of Kahn's algorithm that starts from nodes with no outbound edges first,
94
+ * and then works its way back.
95
+ *
96
+ * This is useful for tasks where we want to process nodes in a way that is consistent with their locality in the graph
97
+ * such as sorting fragments of a generated code file that depend on each other.
98
+ *
99
+ * @param nodes - The nodes to sort
100
+ * @param edges - The edges of the graph
101
+ * @param options - Optional options for the topological sort
102
+ * @returns The sorted nodes
103
+ */
104
+ export function toposortLocal(nodes, edges, options = {}) {
105
+ const { compareFunc = defaultCompareFunc } = options;
106
+ const compareIdx = (a, b) => compareFunc(nodes[a], nodes[b]);
107
+ // Map each node to its index
108
+ const nodeIndexMap = new Map(nodes.map((node, index) => [node, index]));
109
+ // Create a map of outgoing edges from each node
110
+ const inboundEdgesMap = makeInboundEdges(nodeIndexMap, edges);
111
+ const nodeOutDegrees = makeNodeOutDegrees(inboundEdgesMap, nodes.length);
112
+ // Create a stack of nodes with no incoming edges (in-degree == 0)
113
+ // We use a stack so that the most recently added nodes are processed first
114
+ const zeroOutDegreeStack = [];
115
+ for (const [i, nodeOutDegree] of nodeOutDegrees.entries()) {
116
+ if (nodeOutDegree === 0) {
117
+ zeroOutDegreeStack.push(i);
118
+ }
119
+ }
120
+ zeroOutDegreeStack.sort(compareIdx);
121
+ const reverseResult = [];
122
+ const visited = new Set();
123
+ // Process nodes in BFS order
124
+ while (zeroOutDegreeStack.length > 0) {
125
+ const current = zeroOutDegreeStack.pop();
126
+ if (current === undefined)
127
+ break;
128
+ visited.add(current);
129
+ reverseResult.push(nodes[current]);
130
+ // Process all outgoing edges from the current node
131
+ const incomingEdges = inboundEdgesMap.get(current);
132
+ const newZeroOutDegreeNodes = [];
133
+ if (incomingEdges) {
134
+ for (const source of incomingEdges) {
135
+ nodeOutDegrees[source]--;
136
+ // If the target node now has no incoming edges, add it to the queue
137
+ if (nodeOutDegrees[source] === 0) {
138
+ newZeroOutDegreeNodes.push(source);
139
+ }
140
+ }
141
+ }
142
+ newZeroOutDegreeNodes.sort(compareIdx);
143
+ zeroOutDegreeStack.push(...newZeroOutDegreeNodes);
144
+ }
145
+ // Check for cycles
146
+ if (reverseResult.length !== nodes.length) {
147
+ const cyclePath = detectCycle(nodes, visited, inboundEdgesMap);
148
+ throw new ToposortCyclicalDependencyError(cyclePath.reverse());
149
+ }
150
+ return reverseResult.reverse();
151
+ }
152
+ //# sourceMappingURL=toposort-local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toposort-local.js","sourceRoot":"","sources":["../../src/toposort/toposort-local.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ interface ToposortOptions<T> {
2
+ /**
3
+ * Optional custom comparison function to break ties between nodes with the same topological level
4
+ *
5
+ * This allows for a stable topological sort that is consistent with the input order of nodes with the same topological level.
6
+ */
7
+ compareFunc?: (a: T, b: T) => number;
8
+ }
9
+ /**
10
+ * Performs a topological sort on a directed acyclic graph.
11
+ *
12
+ * @param nodes - The nodes to sort
13
+ * @param edges - The edges of the graph
14
+ * @param options - Optional options for the topological sort
15
+ * @returns The sorted nodes
16
+ */
17
+ export declare function toposort<T>(nodes: T[], edges: [T, T][], options?: ToposortOptions<T>): T[];
18
+ /**
19
+ * Performs a topological sort on a directed acyclic graph, always selecting
20
+ * the smallest available node according to the provided comparison function,
21
+ * yielding the lexicographically minimal ordering.
22
+ *
23
+ * @param nodes - The nodes to sort
24
+ * @param edges - The edges of the graph
25
+ * @param compareFunc - Optional custom comparison function to break ties between nodes with the same topological level (default is string comparison)
26
+ * @returns The sorted nodes
27
+ */
28
+ export declare function toposortOrdered<T>(nodes: T[], edges: [T, T][], compareFunc?: (a: T, b: T) => number): T[];
29
+ export {};
30
+ //# sourceMappingURL=toposort.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toposort.d.ts","sourceRoot":"","sources":["../../src/toposort/toposort.ts"],"names":[],"mappings":"AAoHA,UAAU,eAAe,CAAC,CAAC;IACzB;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC;CACtC;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EACxB,KAAK,EAAE,CAAC,EAAE,EACV,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EACf,OAAO,GAAE,eAAe,CAAC,CAAC,CAAM,GAC/B,CAAC,EAAE,CAsDL;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAC/B,KAAK,EAAE,CAAC,EAAE,EACV,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EACf,WAAW,GAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,MAA2B,GACvD,CAAC,EAAE,CAEL"}
@@ -0,0 +1,156 @@
1
+ import TinyQueue from 'tinyqueue';
2
+ import { ToposortCyclicalDependencyError, ToposortUnknownNodeError, } from './errors.js';
3
+ /**
4
+ * Creates a map of outgoing edges from node indices to their target indices
5
+ */
6
+ function makeOutgoingEdges(nodes, edgeArr) {
7
+ const outgoingEdgesMap = new Map();
8
+ for (const edge of edgeArr) {
9
+ const [source, target] = edge;
10
+ const sourceIndex = nodes.get(source);
11
+ const targetIndex = nodes.get(target);
12
+ // Check both source and target exist in the provided nodes set
13
+ if (sourceIndex === undefined)
14
+ throw new ToposortUnknownNodeError(source);
15
+ if (targetIndex === undefined)
16
+ throw new ToposortUnknownNodeError(target);
17
+ const sourceEdges = outgoingEdgesMap.get(sourceIndex);
18
+ if (sourceEdges) {
19
+ sourceEdges.add(targetIndex);
20
+ }
21
+ else {
22
+ outgoingEdgesMap.set(sourceIndex, new Set([targetIndex]));
23
+ }
24
+ }
25
+ return outgoingEdgesMap;
26
+ }
27
+ /**
28
+ * Creates a map of node indices to their in-degree
29
+ */
30
+ function makeNodeInDegrees(outgoingEdgesMap, nodeLength) {
31
+ const nodeInDegrees = Array.from({ length: nodeLength }, () => 0);
32
+ for (const [, targets] of outgoingEdgesMap.entries()) {
33
+ for (const target of targets) {
34
+ nodeInDegrees[target]++;
35
+ }
36
+ }
37
+ return nodeInDegrees;
38
+ }
39
+ /**
40
+ * Detects cycles in a graph by checking if all nodes are included in the topological sort
41
+ */
42
+ function detectCycle(nodes, visited, edges) {
43
+ // If all nodes were visited, no cycle exists
44
+ if (visited.size === nodes.length) {
45
+ return [];
46
+ }
47
+ // Run DFS from any unvisited node to find a cycle
48
+ const path = [];
49
+ const visitSet = new Set();
50
+ function dfs(node) {
51
+ if (visitSet.has(node)) {
52
+ path.push(node);
53
+ return true;
54
+ }
55
+ if (visited.has(node)) {
56
+ return false;
57
+ }
58
+ visitSet.add(node);
59
+ path.push(node);
60
+ const neighbors = edges.get(node) ?? new Set();
61
+ for (const neighbor of neighbors) {
62
+ if (dfs(neighbor)) {
63
+ return true;
64
+ }
65
+ }
66
+ path.pop();
67
+ visitSet.delete(node);
68
+ return false;
69
+ }
70
+ // For cycle detection, we need to find nodes that weren't visited
71
+ const unvistedNodeIdx = nodes.findIndex((node, idx) => !visited.has(idx));
72
+ if (unvistedNodeIdx === -1) {
73
+ return [];
74
+ }
75
+ // Start DFS from any unvisited node
76
+ dfs(unvistedNodeIdx);
77
+ // Convert path indices to actual nodes
78
+ return path.map((idx) => nodes[idx]);
79
+ }
80
+ /**
81
+ * Default comparison function for stable topological sort
82
+ */
83
+ function defaultCompareFunc(a, b) {
84
+ if (typeof a === 'string' && typeof b === 'string') {
85
+ return a.localeCompare(b);
86
+ }
87
+ if (a === b)
88
+ return 0;
89
+ return a < b ? -1 : 1;
90
+ }
91
+ /**
92
+ * Performs a topological sort on a directed acyclic graph.
93
+ *
94
+ * @param nodes - The nodes to sort
95
+ * @param edges - The edges of the graph
96
+ * @param options - Optional options for the topological sort
97
+ * @returns The sorted nodes
98
+ */
99
+ export function toposort(nodes, edges, options = {}) {
100
+ const { compareFunc } = options;
101
+ // Map each node to its index
102
+ const nodeIndexMap = new Map(nodes.map((node, index) => [node, index]));
103
+ // Create a map of outgoing edges from each node
104
+ const outgoingEdgesMap = makeOutgoingEdges(nodeIndexMap, edges);
105
+ const nodeInDegrees = makeNodeInDegrees(outgoingEdgesMap, nodes.length);
106
+ // Create a queue of nodes with no incoming edges (in-degree == 0)
107
+ const zeroInDegreeQueue = compareFunc
108
+ ? new TinyQueue([], (a, b) => compareFunc(nodes[a], nodes[b]))
109
+ : [];
110
+ for (const [i, nodeInDegree] of nodeInDegrees.entries()) {
111
+ if (nodeInDegree === 0) {
112
+ zeroInDegreeQueue.push(i);
113
+ }
114
+ }
115
+ const result = [];
116
+ const visited = new Set();
117
+ // Process nodes in BFS order
118
+ while (zeroInDegreeQueue.length > 0) {
119
+ const current = zeroInDegreeQueue.pop();
120
+ if (current === undefined)
121
+ break;
122
+ visited.add(current);
123
+ result.push(nodes[current]);
124
+ // Process all outgoing edges from the current node
125
+ const outgoingEdges = outgoingEdgesMap.get(current);
126
+ if (outgoingEdges) {
127
+ for (const target of outgoingEdges) {
128
+ nodeInDegrees[target]--;
129
+ // If the target node now has no incoming edges, add it to the queue
130
+ if (nodeInDegrees[target] === 0) {
131
+ zeroInDegreeQueue.push(target);
132
+ }
133
+ }
134
+ }
135
+ }
136
+ // Check for cycles
137
+ if (result.length !== nodes.length) {
138
+ const cyclePath = detectCycle(nodes, visited, outgoingEdgesMap);
139
+ throw new ToposortCyclicalDependencyError(cyclePath);
140
+ }
141
+ return result;
142
+ }
143
+ /**
144
+ * Performs a topological sort on a directed acyclic graph, always selecting
145
+ * the smallest available node according to the provided comparison function,
146
+ * yielding the lexicographically minimal ordering.
147
+ *
148
+ * @param nodes - The nodes to sort
149
+ * @param edges - The edges of the graph
150
+ * @param compareFunc - Optional custom comparison function to break ties between nodes with the same topological level (default is string comparison)
151
+ * @returns The sorted nodes
152
+ */
153
+ export function toposortOrdered(nodes, edges, compareFunc = defaultCompareFunc) {
154
+ return toposort(nodes, edges, { compareFunc });
155
+ }
156
+ //# sourceMappingURL=toposort.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toposort.js","sourceRoot":"","sources":["../../src/toposort/toposort.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from './not-empty.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/type-guards/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './not-empty.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/type-guards/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Type guard to check if a value is not null or undefined.
3
+ */
4
+ export declare function notEmpty<TValue>(value: TValue | null | undefined): value is TValue;
5
+ //# sourceMappingURL=not-empty.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"not-empty.d.ts","sourceRoot":"","sources":["../../src/type-guards/not-empty.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAC7B,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC/B,KAAK,IAAI,MAAM,CAEjB"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Type guard to check if a value is not null or undefined.
3
+ */
4
+ export function notEmpty(value) {
5
+ return value !== null && value !== undefined;
6
+ }
7
+ //# sourceMappingURL=not-empty.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"not-empty.js","sourceRoot":"","sources":["../../src/type-guards/not-empty.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,UAAU,QAAQ,CACtB,KAAgC;IAEhC,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Regex for validating kebab case, e.g. "my-project".
4
+ */
5
+ export declare const KEBAB_CASE_REGEX: RegExp;
6
+ /**
7
+ * Regex for validating pascal case, e.g. "MyProject".
8
+ */
9
+ export declare const PASCAL_CASE_REGEX: RegExp;
10
+ /**
11
+ * Regex for validating camel case, e.g. "myProject".
12
+ */
13
+ export declare const CAMEL_CASE_REGEX: RegExp;
14
+ /**
15
+ * Regex for validating constant case, e.g. "MY_PROJECT".
16
+ */
17
+ export declare const CONSTANT_CASE_REGEX: RegExp;
18
+ export declare const CASE_VALIDATORS: {
19
+ /**
20
+ * Zod validator for validating kebab case, e.g. "my-project".
21
+ */
22
+ readonly KEBAB_CASE: z.ZodString;
23
+ /**
24
+ * Zod validator for validating pascal case, e.g. "MyProject".
25
+ */
26
+ readonly PASCAL_CASE: z.ZodString;
27
+ /**
28
+ * Zod validator for validating camel case, e.g. "myProject".
29
+ */
30
+ readonly CAMEL_CASE: z.ZodString;
31
+ /**
32
+ * Zod validator for validating constant case, e.g. "MY_PROJECT".
33
+ */
34
+ readonly CONSTANT_CASE: z.ZodString;
35
+ };
36
+ //# sourceMappingURL=case-validators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"case-validators.d.ts","sourceRoot":"","sources":["../../src/validators/case-validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,eAAO,MAAM,gBAAgB,QAAiB,CAAC;AAE/C;;GAEG;AACH,eAAO,MAAM,iBAAiB,QAAwB,CAAC;AAEvD;;GAEG;AACH,eAAO,MAAM,gBAAgB,QAAwB,CAAC;AAEtD;;GAEG;AACH,eAAO,MAAM,mBAAmB,QAAsB,CAAC;AAEvD,eAAO,MAAM,eAAe;IAC1B;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;CAEK,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Regex for validating kebab case, e.g. "my-project".
4
+ */
5
+ export const KEBAB_CASE_REGEX = /^[a-z0-9-]+$/;
6
+ /**
7
+ * Regex for validating pascal case, e.g. "MyProject".
8
+ */
9
+ export const PASCAL_CASE_REGEX = /^[A-Z][a-zA-Z0-9]*$/;
10
+ /**
11
+ * Regex for validating camel case, e.g. "myProject".
12
+ */
13
+ export const CAMEL_CASE_REGEX = /^[a-z][a-zA-Z0-9]*$/;
14
+ /**
15
+ * Regex for validating constant case, e.g. "MY_PROJECT".
16
+ */
17
+ export const CONSTANT_CASE_REGEX = /^[A-Z][A-Z0-9_]*$/;
18
+ export const CASE_VALIDATORS = {
19
+ /**
20
+ * Zod validator for validating kebab case, e.g. "my-project".
21
+ */
22
+ KEBAB_CASE: z.string().regex(KEBAB_CASE_REGEX),
23
+ /**
24
+ * Zod validator for validating pascal case, e.g. "MyProject".
25
+ */
26
+ PASCAL_CASE: z.string().regex(PASCAL_CASE_REGEX),
27
+ /**
28
+ * Zod validator for validating camel case, e.g. "myProject".
29
+ */
30
+ CAMEL_CASE: z.string().regex(CAMEL_CASE_REGEX),
31
+ /**
32
+ * Zod validator for validating constant case, e.g. "MY_PROJECT".
33
+ */
34
+ CONSTANT_CASE: z.string().regex(CONSTANT_CASE_REGEX),
35
+ };
36
+ //# sourceMappingURL=case-validators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"case-validators.js","sourceRoot":"","sources":["../../src/validators/case-validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,cAAc,CAAC;AAE/C;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,qBAAqB,CAAC;AAEvD;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,qBAAqB,CAAC;AAEtD;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,mBAAmB,CAAC;AAEvD,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B;;OAEG;IACH,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC;IAC9C;;OAEG;IACH,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC;IAChD;;OAEG;IACH,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC;IAC9C;;OAEG;IACH,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,mBAAmB,CAAC;CAC5C,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from './case-validators.js';
2
+ export * from './number-validators.js';
3
+ export * from './transform-with-dynamic-schema.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validators/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oCAAoC,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from './case-validators.js';
2
+ export * from './number-validators.js';
3
+ export * from './transform-with-dynamic-schema.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/validators/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oCAAoC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Zod number validators.
4
+ */
5
+ export declare const NUMBER_VALIDATORS: {
6
+ POSITIVE_INT: z.ZodNumber;
7
+ };
8
+ //# sourceMappingURL=number-validators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"number-validators.d.ts","sourceRoot":"","sources":["../../src/validators/number-validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB;;GAEG;AACH,eAAO,MAAM,iBAAiB;;CAE7B,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Zod validator for a positive integer.
4
+ */
5
+ const POSITIVE_INT = z.number().int().positive();
6
+ /**
7
+ * Zod number validators.
8
+ */
9
+ export const NUMBER_VALIDATORS = {
10
+ POSITIVE_INT,
11
+ };
12
+ //# sourceMappingURL=number-validators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"number-validators.js","sourceRoot":"","sources":["../../src/validators/number-validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;AAEjD;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,YAAY;CACb,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { type RefinementCtx, type ZodTypeAny } from 'zod';
2
+ /**
3
+ * Transforms a value using a dynamic schema and forwards any issues to transform context.
4
+ *
5
+ * Note: This does not change the return type of the schema.
6
+ *
7
+ * @param schemaFn - A function returning a Zod schema based on the current object.
8
+ */
9
+ export declare function transformWithDynamicSchema<TData extends object>(schemaFn: (data: TData) => ZodTypeAny | undefined, valuePath?: keyof TData): (data: TData, ctx: RefinementCtx) => TData;
10
+ //# sourceMappingURL=transform-with-dynamic-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform-with-dynamic-schema.d.ts","sourceRoot":"","sources":["../../src/validators/transform-with-dynamic-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAK,KAAK,UAAU,EAAE,MAAM,KAAK,CAAC;AAE7D;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,SAAS,MAAM,EAC7D,QAAQ,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,UAAU,GAAG,SAAS,EACjD,SAAS,CAAC,EAAE,MAAM,KAAK,GACtB,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,aAAa,KAAK,KAAK,CA6B5C"}
@@ -0,0 +1,33 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Transforms a value using a dynamic schema and forwards any issues to transform context.
4
+ *
5
+ * Note: This does not change the return type of the schema.
6
+ *
7
+ * @param schemaFn - A function returning a Zod schema based on the current object.
8
+ */
9
+ export function transformWithDynamicSchema(schemaFn, valuePath) {
10
+ return (data, ctx) => {
11
+ const schema = schemaFn(data);
12
+ if (!schema) {
13
+ return data;
14
+ }
15
+ const result = schema.safeParse((valuePath ? data[valuePath] : data) ?? undefined);
16
+ if (!result.success) {
17
+ for (const issue of result.error.issues) {
18
+ ctx.addIssue({
19
+ ...issue,
20
+ path: [...(valuePath ? [valuePath] : []), ...issue.path],
21
+ });
22
+ }
23
+ return z.NEVER;
24
+ }
25
+ return valuePath
26
+ ? {
27
+ ...data,
28
+ [valuePath]: result.data,
29
+ }
30
+ : result.data;
31
+ };
32
+ }
33
+ //# sourceMappingURL=transform-with-dynamic-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform-with-dynamic-schema.js","sourceRoot":"","sources":["../../src/validators/transform-with-dynamic-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,CAAC,EAAmB,MAAM,KAAK,CAAC;AAE7D;;;;;;GAMG;AACH,MAAM,UAAU,0BAA0B,CACxC,QAAiD,EACjD,SAAuB;IAEvB,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACnB,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAE9B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAC7B,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,SAAS,CAClD,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACxC,GAAG,CAAC,QAAQ,CAAC;oBACX,GAAG,KAAK;oBACR,IAAI,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAmB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC;iBACnE,CAAC,CAAC;YACL,CAAC;YACD,OAAO,CAAC,CAAC,KAAK,CAAC;QACjB,CAAC;QAED,OAAO,SAAS;YACd,CAAC,CAAC;gBACE,GAAG,IAAI;gBACP,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,IAA+B;aACpD;YACH,CAAC,CAAE,MAAM,CAAC,IAAc,CAAC;IAC7B,CAAC,CAAC;AACJ,CAAC"}