semola 0.5.0 → 0.5.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.
Files changed (273) hide show
  1. package/README.md +75 -20
  2. package/dist/api/core/index.cjs +206 -0
  3. package/dist/api/core/index.d.cts +21 -0
  4. package/dist/api/core/index.d.cts.map +1 -0
  5. package/dist/api/core/index.d.mts +21 -0
  6. package/dist/api/core/index.d.mts.map +1 -0
  7. package/dist/api/core/index.mjs +208 -0
  8. package/dist/api/core/index.mjs.map +1 -0
  9. package/dist/api/core/types.d.cts +107 -0
  10. package/dist/api/core/types.d.cts.map +1 -0
  11. package/dist/api/core/types.d.mts +107 -0
  12. package/dist/api/core/types.d.mts.map +1 -0
  13. package/dist/api/middleware/index.cjs +8 -0
  14. package/dist/api/middleware/index.d.cts +11 -0
  15. package/dist/api/middleware/index.d.cts.map +1 -0
  16. package/dist/api/middleware/index.d.mts +11 -0
  17. package/dist/api/middleware/index.d.mts.map +1 -0
  18. package/dist/api/middleware/index.mjs +10 -0
  19. package/dist/api/middleware/index.mjs.map +1 -0
  20. package/dist/api/middleware/types.d.cts +16 -0
  21. package/dist/api/middleware/types.d.cts.map +1 -0
  22. package/dist/api/middleware/types.d.mts +16 -0
  23. package/dist/api/middleware/types.d.mts.map +1 -0
  24. package/dist/api/openapi/index.cjs +254 -0
  25. package/dist/api/openapi/index.mjs +256 -0
  26. package/dist/api/openapi/index.mjs.map +1 -0
  27. package/dist/api/openapi/types.d.cts +60 -0
  28. package/dist/api/openapi/types.d.cts.map +1 -0
  29. package/dist/api/openapi/types.d.mts +60 -0
  30. package/dist/api/openapi/types.d.mts.map +1 -0
  31. package/dist/api/validation/index.cjs +64 -0
  32. package/dist/api/validation/index.mjs +61 -0
  33. package/dist/api/validation/index.mjs.map +1 -0
  34. package/dist/cache/types.d.cts +17 -0
  35. package/dist/cache/types.d.cts.map +1 -0
  36. package/dist/cache/types.d.mts +17 -0
  37. package/dist/cache/types.d.mts.map +1 -0
  38. package/dist/cron/scanner.cjs +237 -0
  39. package/dist/cron/scanner.mjs +238 -0
  40. package/dist/cron/scanner.mjs.map +1 -0
  41. package/dist/cron/types.d.cts +11 -0
  42. package/dist/cron/types.d.cts.map +1 -0
  43. package/dist/cron/types.d.mts +11 -0
  44. package/dist/cron/types.d.mts.map +1 -0
  45. package/dist/errors/types.d.cts +5 -0
  46. package/dist/errors/types.d.cts.map +1 -0
  47. package/dist/errors/types.d.mts +5 -0
  48. package/dist/errors/types.d.mts.map +1 -0
  49. package/dist/i18n/types.d.cts +13 -0
  50. package/dist/i18n/types.d.cts.map +1 -0
  51. package/dist/i18n/types.d.mts +13 -0
  52. package/dist/i18n/types.d.mts.map +1 -0
  53. package/dist/lib/api/index.cjs +5 -0
  54. package/dist/lib/api/index.d.cts +5 -0
  55. package/dist/lib/api/index.d.mts +5 -0
  56. package/dist/lib/api/index.mjs +3 -0
  57. package/dist/lib/cache/index.cjs +74 -0
  58. package/dist/lib/cache/index.d.cts +36 -0
  59. package/dist/lib/cache/index.d.cts.map +1 -0
  60. package/dist/lib/cache/index.d.mts +36 -0
  61. package/dist/lib/cache/index.d.mts.map +1 -0
  62. package/dist/lib/cache/index.mjs +75 -0
  63. package/dist/lib/cache/index.mjs.map +1 -0
  64. package/dist/lib/cron/index.cjs +276 -0
  65. package/dist/lib/cron/index.d.cts +39 -0
  66. package/dist/lib/cron/index.d.cts.map +1 -0
  67. package/dist/lib/cron/index.d.mts +39 -0
  68. package/dist/lib/cron/index.d.mts.map +1 -0
  69. package/dist/lib/cron/index.mjs +277 -0
  70. package/dist/lib/cron/index.mjs.map +1 -0
  71. package/dist/lib/errors/index.cjs +30 -0
  72. package/dist/lib/errors/index.d.cts +13 -0
  73. package/dist/lib/errors/index.d.cts.map +1 -0
  74. package/dist/lib/errors/index.d.mts +13 -0
  75. package/dist/lib/errors/index.d.mts.map +1 -0
  76. package/dist/lib/errors/index.mjs +28 -0
  77. package/dist/lib/errors/index.mjs.map +1 -0
  78. package/dist/lib/i18n/index.cjs +37 -0
  79. package/dist/lib/i18n/index.d.cts +20 -0
  80. package/dist/lib/i18n/index.d.cts.map +1 -0
  81. package/dist/lib/i18n/index.d.mts +20 -0
  82. package/dist/lib/i18n/index.d.mts.map +1 -0
  83. package/dist/lib/i18n/index.mjs +38 -0
  84. package/dist/lib/i18n/index.mjs.map +1 -0
  85. package/dist/lib/policy/index.cjs +99 -0
  86. package/dist/lib/policy/index.d.cts +21 -0
  87. package/dist/lib/policy/index.d.cts.map +1 -0
  88. package/dist/lib/policy/index.d.mts +21 -0
  89. package/dist/lib/policy/index.d.mts.map +1 -0
  90. package/dist/lib/policy/index.mjs +81 -0
  91. package/dist/lib/policy/index.mjs.map +1 -0
  92. package/dist/lib/prompts/index.cjs +409 -0
  93. package/dist/lib/prompts/index.d.cts +31 -0
  94. package/dist/lib/prompts/index.d.cts.map +1 -0
  95. package/dist/lib/prompts/index.d.mts +31 -0
  96. package/dist/lib/prompts/index.d.mts.map +1 -0
  97. package/dist/lib/prompts/index.mjs +405 -0
  98. package/dist/lib/prompts/index.mjs.map +1 -0
  99. package/dist/lib/pubsub/index.cjs +48 -0
  100. package/dist/lib/pubsub/index.d.cts +27 -0
  101. package/dist/lib/pubsub/index.d.cts.map +1 -0
  102. package/dist/lib/pubsub/index.d.mts +27 -0
  103. package/dist/lib/pubsub/index.d.mts.map +1 -0
  104. package/dist/lib/pubsub/index.mjs +49 -0
  105. package/dist/lib/pubsub/index.mjs.map +1 -0
  106. package/dist/lib/queue/index.cjs +182 -0
  107. package/dist/lib/queue/index.d.cts +32 -0
  108. package/dist/lib/queue/index.d.cts.map +1 -0
  109. package/dist/lib/queue/index.d.mts +32 -0
  110. package/dist/lib/queue/index.d.mts.map +1 -0
  111. package/dist/lib/queue/index.mjs +183 -0
  112. package/dist/lib/queue/index.mjs.map +1 -0
  113. package/dist/node_modules/@standard-schema/spec/dist/index.d.cts +80 -0
  114. package/dist/node_modules/@standard-schema/spec/dist/index.d.cts.map +1 -0
  115. package/dist/node_modules/@standard-schema/spec/dist/index.d.mts +80 -0
  116. package/dist/node_modules/@standard-schema/spec/dist/index.d.mts.map +1 -0
  117. package/dist/policy/helpers.cjs +206 -0
  118. package/dist/policy/helpers.d.cts +50 -0
  119. package/dist/policy/helpers.d.cts.map +1 -0
  120. package/dist/policy/helpers.d.mts +50 -0
  121. package/dist/policy/helpers.d.mts.map +1 -0
  122. package/dist/policy/helpers.mjs +190 -0
  123. package/dist/policy/helpers.mjs.map +1 -0
  124. package/dist/policy/types.d.cts +16 -0
  125. package/dist/policy/types.d.cts.map +1 -0
  126. package/dist/policy/types.d.mts +16 -0
  127. package/dist/policy/types.d.mts.map +1 -0
  128. package/dist/prompts/core/keys.cjs +165 -0
  129. package/dist/prompts/core/keys.mjs +167 -0
  130. package/dist/prompts/core/keys.mjs.map +1 -0
  131. package/dist/prompts/core/runtime.cjs +104 -0
  132. package/dist/prompts/core/runtime.mjs +106 -0
  133. package/dist/prompts/core/runtime.mjs.map +1 -0
  134. package/dist/prompts/core/session.cjs +98 -0
  135. package/dist/prompts/core/session.mjs +100 -0
  136. package/dist/prompts/core/session.mjs.map +1 -0
  137. package/dist/prompts/core/types.d.cts +21 -0
  138. package/dist/prompts/core/types.d.cts.map +1 -0
  139. package/dist/prompts/core/types.d.mts +21 -0
  140. package/dist/prompts/core/types.d.mts.map +1 -0
  141. package/dist/prompts/types.d.cts +52 -0
  142. package/dist/prompts/types.d.cts.map +1 -0
  143. package/dist/prompts/types.d.mts +52 -0
  144. package/dist/prompts/types.d.mts.map +1 -0
  145. package/dist/pubsub/types.d.cts +10 -0
  146. package/dist/pubsub/types.d.cts.map +1 -0
  147. package/dist/pubsub/types.d.mts +10 -0
  148. package/dist/pubsub/types.d.mts.map +1 -0
  149. package/dist/queue/types.d.cts +47 -0
  150. package/dist/queue/types.d.cts.map +1 -0
  151. package/dist/queue/types.d.mts +47 -0
  152. package/dist/queue/types.d.mts.map +1 -0
  153. package/package.json +86 -16
  154. package/dist/lib/api/core/index.d.ts +0 -15
  155. package/dist/lib/api/core/index.d.ts.map +0 -1
  156. package/dist/lib/api/core/index.js +0 -166
  157. package/dist/lib/api/core/index.js.map +0 -1
  158. package/dist/lib/api/core/index.test.d.ts +0 -2
  159. package/dist/lib/api/core/index.test.d.ts.map +0 -1
  160. package/dist/lib/api/core/index.test.js +0 -219
  161. package/dist/lib/api/core/index.test.js.map +0 -1
  162. package/dist/lib/api/core/types.d.ts +0 -102
  163. package/dist/lib/api/core/types.d.ts.map +0 -1
  164. package/dist/lib/api/core/types.js +0 -2
  165. package/dist/lib/api/core/types.js.map +0 -1
  166. package/dist/lib/api/index.d.ts +0 -5
  167. package/dist/lib/api/index.d.ts.map +0 -1
  168. package/dist/lib/api/index.js +0 -3
  169. package/dist/lib/api/index.js.map +0 -1
  170. package/dist/lib/api/middleware/index.d.ts +0 -7
  171. package/dist/lib/api/middleware/index.d.ts.map +0 -1
  172. package/dist/lib/api/middleware/index.js +0 -7
  173. package/dist/lib/api/middleware/index.js.map +0 -1
  174. package/dist/lib/api/middleware/index.test.d.ts +0 -2
  175. package/dist/lib/api/middleware/index.test.d.ts.map +0 -1
  176. package/dist/lib/api/middleware/index.test.js +0 -67
  177. package/dist/lib/api/middleware/index.test.js.map +0 -1
  178. package/dist/lib/api/middleware/types.d.ts +0 -12
  179. package/dist/lib/api/middleware/types.d.ts.map +0 -1
  180. package/dist/lib/api/middleware/types.js +0 -2
  181. package/dist/lib/api/middleware/types.js.map +0 -1
  182. package/dist/lib/api/openapi/index.d.ts +0 -31
  183. package/dist/lib/api/openapi/index.d.ts.map +0 -1
  184. package/dist/lib/api/openapi/index.js +0 -328
  185. package/dist/lib/api/openapi/index.js.map +0 -1
  186. package/dist/lib/api/openapi/index.test.d.ts +0 -2
  187. package/dist/lib/api/openapi/index.test.d.ts.map +0 -1
  188. package/dist/lib/api/openapi/index.test.js +0 -359
  189. package/dist/lib/api/openapi/index.test.js.map +0 -1
  190. package/dist/lib/api/openapi/types.d.ts +0 -57
  191. package/dist/lib/api/openapi/types.d.ts.map +0 -1
  192. package/dist/lib/api/openapi/types.js +0 -5
  193. package/dist/lib/api/openapi/types.js.map +0 -1
  194. package/dist/lib/api/validation/index.d.ts +0 -33
  195. package/dist/lib/api/validation/index.d.ts.map +0 -1
  196. package/dist/lib/api/validation/index.js +0 -81
  197. package/dist/lib/api/validation/index.js.map +0 -1
  198. package/dist/lib/api/validation/index.test.d.ts +0 -2
  199. package/dist/lib/api/validation/index.test.d.ts.map +0 -1
  200. package/dist/lib/api/validation/index.test.js +0 -135
  201. package/dist/lib/api/validation/index.test.js.map +0 -1
  202. package/dist/lib/cache/index.d.ts +0 -25
  203. package/dist/lib/cache/index.d.ts.map +0 -1
  204. package/dist/lib/cache/index.js +0 -62
  205. package/dist/lib/cache/index.js.map +0 -1
  206. package/dist/lib/cache/index.test.d.ts +0 -2
  207. package/dist/lib/cache/index.test.d.ts.map +0 -1
  208. package/dist/lib/cache/index.test.js +0 -314
  209. package/dist/lib/cache/index.test.js.map +0 -1
  210. package/dist/lib/cache/types.d.ts +0 -5
  211. package/dist/lib/cache/types.d.ts.map +0 -1
  212. package/dist/lib/cache/types.js +0 -2
  213. package/dist/lib/cache/types.js.map +0 -1
  214. package/dist/lib/errors/index.d.ts +0 -9
  215. package/dist/lib/errors/index.d.ts.map +0 -1
  216. package/dist/lib/errors/index.js +0 -25
  217. package/dist/lib/errors/index.js.map +0 -1
  218. package/dist/lib/errors/index.test.d.ts +0 -2
  219. package/dist/lib/errors/index.test.d.ts.map +0 -1
  220. package/dist/lib/errors/index.test.js +0 -197
  221. package/dist/lib/errors/index.test.js.map +0 -1
  222. package/dist/lib/errors/types.d.ts +0 -2
  223. package/dist/lib/errors/types.d.ts.map +0 -1
  224. package/dist/lib/errors/types.js +0 -2
  225. package/dist/lib/errors/types.js.map +0 -1
  226. package/dist/lib/i18n/index.d.ts +0 -18
  227. package/dist/lib/i18n/index.d.ts.map +0 -1
  228. package/dist/lib/i18n/index.js +0 -38
  229. package/dist/lib/i18n/index.js.map +0 -1
  230. package/dist/lib/i18n/index.test.d.ts +0 -2
  231. package/dist/lib/i18n/index.test.d.ts.map +0 -1
  232. package/dist/lib/i18n/index.test.js +0 -402
  233. package/dist/lib/i18n/index.test.js.map +0 -1
  234. package/dist/lib/i18n/types.d.ts +0 -15
  235. package/dist/lib/i18n/types.d.ts.map +0 -1
  236. package/dist/lib/i18n/types.js +0 -2
  237. package/dist/lib/i18n/types.js.map +0 -1
  238. package/dist/lib/policy/index.d.ts +0 -9
  239. package/dist/lib/policy/index.d.ts.map +0 -1
  240. package/dist/lib/policy/index.js +0 -51
  241. package/dist/lib/policy/index.js.map +0 -1
  242. package/dist/lib/policy/index.test.d.ts +0 -2
  243. package/dist/lib/policy/index.test.d.ts.map +0 -1
  244. package/dist/lib/policy/index.test.js +0 -328
  245. package/dist/lib/policy/index.test.js.map +0 -1
  246. package/dist/lib/policy/types.d.ts +0 -27
  247. package/dist/lib/policy/types.d.ts.map +0 -1
  248. package/dist/lib/policy/types.js +0 -2
  249. package/dist/lib/policy/types.js.map +0 -1
  250. package/dist/lib/pubsub/index.d.ts +0 -23
  251. package/dist/lib/pubsub/index.d.ts.map +0 -1
  252. package/dist/lib/pubsub/index.js +0 -55
  253. package/dist/lib/pubsub/index.js.map +0 -1
  254. package/dist/lib/pubsub/index.test.d.ts +0 -2
  255. package/dist/lib/pubsub/index.test.d.ts.map +0 -1
  256. package/dist/lib/pubsub/index.test.js +0 -550
  257. package/dist/lib/pubsub/index.test.js.map +0 -1
  258. package/dist/lib/pubsub/types.d.ts +0 -7
  259. package/dist/lib/pubsub/types.d.ts.map +0 -1
  260. package/dist/lib/pubsub/types.js +0 -2
  261. package/dist/lib/pubsub/types.js.map +0 -1
  262. package/dist/lib/queue/index.d.ts +0 -28
  263. package/dist/lib/queue/index.d.ts.map +0 -1
  264. package/dist/lib/queue/index.js +0 -211
  265. package/dist/lib/queue/index.js.map +0 -1
  266. package/dist/lib/queue/index.test.d.ts +0 -2
  267. package/dist/lib/queue/index.test.d.ts.map +0 -1
  268. package/dist/lib/queue/index.test.js +0 -740
  269. package/dist/lib/queue/index.test.js.map +0 -1
  270. package/dist/lib/queue/types.d.ts +0 -52
  271. package/dist/lib/queue/types.d.ts.map +0 -1
  272. package/dist/lib/queue/types.js +0 -2
  273. package/dist/lib/queue/types.js.map +0 -1
@@ -0,0 +1,165 @@
1
+ //#region src/lib/prompts/core/keys.ts
2
+ const ESC = "\x1B";
3
+ const CSI = "\x1B[";
4
+ const ESC_BACKSPACE = `${ESC}\u007F`;
5
+ const CHAR_KEY_MAP = new Map(Object.values({
6
+ enterCr: {
7
+ value: "\r",
8
+ name: "enter"
9
+ },
10
+ enterLf: {
11
+ value: "\n",
12
+ name: "enter"
13
+ },
14
+ ctrlA: {
15
+ value: "",
16
+ name: "ctrl_a"
17
+ },
18
+ ctrlC: {
19
+ value: "",
20
+ name: "ctrl_c"
21
+ },
22
+ ctrlBackspace: {
23
+ value: "",
24
+ name: "ctrl_backspace"
25
+ },
26
+ backspace: {
27
+ value: "",
28
+ name: "backspace"
29
+ },
30
+ tab: {
31
+ value: " ",
32
+ name: "tab"
33
+ },
34
+ space: {
35
+ value: " ",
36
+ name: "space"
37
+ }
38
+ }).map((entry) => [entry.value, { name: entry.name }]));
39
+ const KNOWN_SEQUENCES = [
40
+ {
41
+ sequence: "\x1B[1;2D",
42
+ key: { name: "shift_left" }
43
+ },
44
+ {
45
+ sequence: "\x1B[1;2C",
46
+ key: { name: "shift_right" }
47
+ },
48
+ {
49
+ sequence: "\x1B[1;5D",
50
+ key: { name: "ctrl_left" }
51
+ },
52
+ {
53
+ sequence: "\x1B[1;5C",
54
+ key: { name: "ctrl_right" }
55
+ },
56
+ {
57
+ sequence: "\x1B[1;6D",
58
+ key: { name: "shift_ctrl_left" }
59
+ },
60
+ {
61
+ sequence: "\x1B[1;6C",
62
+ key: { name: "shift_ctrl_right" }
63
+ },
64
+ {
65
+ sequence: "\x1B[3~",
66
+ key: { name: "delete" }
67
+ },
68
+ {
69
+ sequence: "\x1B[H",
70
+ key: { name: "home" }
71
+ },
72
+ {
73
+ sequence: "\x1B[F",
74
+ key: { name: "end" }
75
+ },
76
+ {
77
+ sequence: "\x1B[A",
78
+ key: { name: "up" }
79
+ },
80
+ {
81
+ sequence: "\x1B[B",
82
+ key: { name: "down" }
83
+ },
84
+ {
85
+ sequence: "\x1B[C",
86
+ key: { name: "right" }
87
+ },
88
+ {
89
+ sequence: "\x1B[D",
90
+ key: { name: "left" }
91
+ }
92
+ ];
93
+ const isControlChar = (char) => {
94
+ return char <= "" || char === "";
95
+ };
96
+ const isCsiFinalByte = (char) => {
97
+ if (!char) return false;
98
+ if (char >= "A" && char <= "Z") return true;
99
+ if (char >= "a" && char <= "z") return true;
100
+ if (char === "~") return true;
101
+ return false;
102
+ };
103
+ const readCsiLength = (remaining) => {
104
+ if (!remaining.startsWith(CSI)) return null;
105
+ let index = 2;
106
+ while (index < remaining.length) {
107
+ if (isCsiFinalByte(remaining[index] ?? "")) return {
108
+ length: index + 1,
109
+ incomplete: false
110
+ };
111
+ index += 1;
112
+ }
113
+ return {
114
+ length: 0,
115
+ incomplete: true
116
+ };
117
+ };
118
+ const parseKeys = (chunk) => {
119
+ const keys = [];
120
+ let cursor = 0;
121
+ while (cursor < chunk.length) {
122
+ const remaining = chunk.slice(cursor);
123
+ if (remaining.startsWith(ESC_BACKSPACE)) {
124
+ keys.push({ name: "ctrl_backspace" });
125
+ cursor += 2;
126
+ continue;
127
+ }
128
+ const knownSequence = KNOWN_SEQUENCES.find((entry) => remaining.startsWith(entry.sequence));
129
+ if (knownSequence) {
130
+ keys.push(knownSequence.key);
131
+ cursor += knownSequence.sequence.length;
132
+ continue;
133
+ }
134
+ const csiLength = readCsiLength(remaining);
135
+ if (csiLength) {
136
+ if (csiLength.incomplete) return {
137
+ keys,
138
+ remaining: chunk.slice(cursor)
139
+ };
140
+ cursor += csiLength.length;
141
+ continue;
142
+ }
143
+ const char = chunk[cursor] ?? "";
144
+ switch (char) {
145
+ case ESC:
146
+ if (cursor === chunk.length - 1) keys.push({ name: "escape" });
147
+ break;
148
+ default: {
149
+ const key = CHAR_KEY_MAP.get(char);
150
+ if (key) keys.push(key);
151
+ else if (!isControlChar(char)) keys.push({
152
+ name: "character",
153
+ value: char
154
+ });
155
+ }
156
+ }
157
+ cursor += 1;
158
+ }
159
+ return {
160
+ keys,
161
+ remaining: ""
162
+ };
163
+ };
164
+ //#endregion
165
+ exports.parseKeys = parseKeys;
@@ -0,0 +1,167 @@
1
+ //#region src/lib/prompts/core/keys.ts
2
+ const ESC = "\x1B";
3
+ const CSI = "\x1B[";
4
+ const ESC_BACKSPACE = `${ESC}\u007F`;
5
+ const CHAR_KEY_MAP = new Map(Object.values({
6
+ enterCr: {
7
+ value: "\r",
8
+ name: "enter"
9
+ },
10
+ enterLf: {
11
+ value: "\n",
12
+ name: "enter"
13
+ },
14
+ ctrlA: {
15
+ value: "",
16
+ name: "ctrl_a"
17
+ },
18
+ ctrlC: {
19
+ value: "",
20
+ name: "ctrl_c"
21
+ },
22
+ ctrlBackspace: {
23
+ value: "",
24
+ name: "ctrl_backspace"
25
+ },
26
+ backspace: {
27
+ value: "",
28
+ name: "backspace"
29
+ },
30
+ tab: {
31
+ value: " ",
32
+ name: "tab"
33
+ },
34
+ space: {
35
+ value: " ",
36
+ name: "space"
37
+ }
38
+ }).map((entry) => [entry.value, { name: entry.name }]));
39
+ const KNOWN_SEQUENCES = [
40
+ {
41
+ sequence: "\x1B[1;2D",
42
+ key: { name: "shift_left" }
43
+ },
44
+ {
45
+ sequence: "\x1B[1;2C",
46
+ key: { name: "shift_right" }
47
+ },
48
+ {
49
+ sequence: "\x1B[1;5D",
50
+ key: { name: "ctrl_left" }
51
+ },
52
+ {
53
+ sequence: "\x1B[1;5C",
54
+ key: { name: "ctrl_right" }
55
+ },
56
+ {
57
+ sequence: "\x1B[1;6D",
58
+ key: { name: "shift_ctrl_left" }
59
+ },
60
+ {
61
+ sequence: "\x1B[1;6C",
62
+ key: { name: "shift_ctrl_right" }
63
+ },
64
+ {
65
+ sequence: "\x1B[3~",
66
+ key: { name: "delete" }
67
+ },
68
+ {
69
+ sequence: "\x1B[H",
70
+ key: { name: "home" }
71
+ },
72
+ {
73
+ sequence: "\x1B[F",
74
+ key: { name: "end" }
75
+ },
76
+ {
77
+ sequence: "\x1B[A",
78
+ key: { name: "up" }
79
+ },
80
+ {
81
+ sequence: "\x1B[B",
82
+ key: { name: "down" }
83
+ },
84
+ {
85
+ sequence: "\x1B[C",
86
+ key: { name: "right" }
87
+ },
88
+ {
89
+ sequence: "\x1B[D",
90
+ key: { name: "left" }
91
+ }
92
+ ];
93
+ const isControlChar = (char) => {
94
+ return char <= "" || char === "";
95
+ };
96
+ const isCsiFinalByte = (char) => {
97
+ if (!char) return false;
98
+ if (char >= "A" && char <= "Z") return true;
99
+ if (char >= "a" && char <= "z") return true;
100
+ if (char === "~") return true;
101
+ return false;
102
+ };
103
+ const readCsiLength = (remaining) => {
104
+ if (!remaining.startsWith(CSI)) return null;
105
+ let index = 2;
106
+ while (index < remaining.length) {
107
+ if (isCsiFinalByte(remaining[index] ?? "")) return {
108
+ length: index + 1,
109
+ incomplete: false
110
+ };
111
+ index += 1;
112
+ }
113
+ return {
114
+ length: 0,
115
+ incomplete: true
116
+ };
117
+ };
118
+ const parseKeys = (chunk) => {
119
+ const keys = [];
120
+ let cursor = 0;
121
+ while (cursor < chunk.length) {
122
+ const remaining = chunk.slice(cursor);
123
+ if (remaining.startsWith(ESC_BACKSPACE)) {
124
+ keys.push({ name: "ctrl_backspace" });
125
+ cursor += 2;
126
+ continue;
127
+ }
128
+ const knownSequence = KNOWN_SEQUENCES.find((entry) => remaining.startsWith(entry.sequence));
129
+ if (knownSequence) {
130
+ keys.push(knownSequence.key);
131
+ cursor += knownSequence.sequence.length;
132
+ continue;
133
+ }
134
+ const csiLength = readCsiLength(remaining);
135
+ if (csiLength) {
136
+ if (csiLength.incomplete) return {
137
+ keys,
138
+ remaining: chunk.slice(cursor)
139
+ };
140
+ cursor += csiLength.length;
141
+ continue;
142
+ }
143
+ const char = chunk[cursor] ?? "";
144
+ switch (char) {
145
+ case ESC:
146
+ if (cursor === chunk.length - 1) keys.push({ name: "escape" });
147
+ break;
148
+ default: {
149
+ const key = CHAR_KEY_MAP.get(char);
150
+ if (key) keys.push(key);
151
+ else if (!isControlChar(char)) keys.push({
152
+ name: "character",
153
+ value: char
154
+ });
155
+ }
156
+ }
157
+ cursor += 1;
158
+ }
159
+ return {
160
+ keys,
161
+ remaining: ""
162
+ };
163
+ };
164
+ //#endregion
165
+ export { parseKeys };
166
+
167
+ //# sourceMappingURL=keys.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.mjs","names":[],"sources":["../../../src/lib/prompts/core/keys.ts"],"sourcesContent":["import type { Key, KeyName } from \"./types.js\";\n\nconst ESC = \"\\u001B\";\nconst CSI = \"\\u001B[\";\nconst ESC_BACKSPACE = `${ESC}\\u007F`;\n\nconst CHAR_KEYS = {\n enterCr: { value: \"\\r\", name: \"enter\" },\n enterLf: { value: \"\\n\", name: \"enter\" },\n ctrlA: { value: \"\\u0001\", name: \"ctrl_a\" },\n ctrlC: { value: \"\\u0003\", name: \"ctrl_c\" },\n ctrlBackspace: { value: \"\\u0017\", name: \"ctrl_backspace\" },\n backspace: { value: \"\\u007F\", name: \"backspace\" },\n tab: { value: \"\\t\", name: \"tab\" },\n space: { value: \" \", name: \"space\" },\n} satisfies Record<string, { value: string; name: KeyName }>;\n\nconst CHAR_KEY_MAP = new Map<string, Key>(\n Object.values(CHAR_KEYS).map((entry) => [entry.value, { name: entry.name }]),\n);\n\nconst KNOWN_SEQUENCES = [\n { sequence: \"\\u001B[1;2D\", key: { name: \"shift_left\" } },\n { sequence: \"\\u001B[1;2C\", key: { name: \"shift_right\" } },\n { sequence: \"\\u001B[1;5D\", key: { name: \"ctrl_left\" } },\n { sequence: \"\\u001B[1;5C\", key: { name: \"ctrl_right\" } },\n { sequence: \"\\u001B[1;6D\", key: { name: \"shift_ctrl_left\" } },\n { sequence: \"\\u001B[1;6C\", key: { name: \"shift_ctrl_right\" } },\n { sequence: \"\\u001B[3~\", key: { name: \"delete\" } },\n { sequence: \"\\u001B[H\", key: { name: \"home\" } },\n { sequence: \"\\u001B[F\", key: { name: \"end\" } },\n { sequence: \"\\u001B[A\", key: { name: \"up\" } },\n { sequence: \"\\u001B[B\", key: { name: \"down\" } },\n { sequence: \"\\u001B[C\", key: { name: \"right\" } },\n { sequence: \"\\u001B[D\", key: { name: \"left\" } },\n] as const;\n\nconst isControlChar = (char: string) => {\n return char <= \"\\u001F\" || char === \"\\u007F\";\n};\n\nconst isCsiFinalByte = (char: string) => {\n if (!char) {\n return false;\n }\n\n if (char >= \"A\" && char <= \"Z\") {\n return true;\n }\n\n if (char >= \"a\" && char <= \"z\") {\n return true;\n }\n\n if (char === \"~\") {\n return true;\n }\n\n return false;\n};\n\nconst readCsiLength = (remaining: string) => {\n if (!remaining.startsWith(CSI)) {\n return null;\n }\n\n let index = CSI.length;\n\n while (index < remaining.length) {\n const char = remaining[index] ?? \"\";\n\n if (isCsiFinalByte(char)) {\n return { length: index + 1, incomplete: false };\n }\n\n index += 1;\n }\n\n return { length: 0, incomplete: true };\n};\n\nexport const parseKeys = (chunk: string) => {\n const keys: Key[] = [];\n\n let cursor = 0;\n\n while (cursor < chunk.length) {\n const remaining = chunk.slice(cursor);\n\n if (remaining.startsWith(ESC_BACKSPACE)) {\n keys.push({ name: \"ctrl_backspace\" });\n cursor += 2;\n continue;\n }\n\n const knownSequence = KNOWN_SEQUENCES.find((entry) =>\n remaining.startsWith(entry.sequence),\n );\n\n if (knownSequence) {\n keys.push(knownSequence.key);\n cursor += knownSequence.sequence.length;\n continue;\n }\n\n const csiLength = readCsiLength(remaining);\n\n if (csiLength) {\n if (csiLength.incomplete) {\n return { keys, remaining: chunk.slice(cursor) };\n }\n\n cursor += csiLength.length;\n continue;\n }\n\n const char = chunk[cursor] ?? \"\";\n\n switch (char) {\n case ESC: {\n if (cursor === chunk.length - 1) {\n keys.push({ name: \"escape\" });\n }\n break;\n }\n default: {\n const key = CHAR_KEY_MAP.get(char);\n\n if (key) {\n keys.push(key);\n } else if (!isControlChar(char)) {\n keys.push({ name: \"character\", value: char });\n }\n }\n }\n\n cursor += 1;\n }\n\n return { keys, remaining: \"\" };\n};\n"],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ const require_lib_errors_index = require("../../lib/errors/index.cjs");
2
+ const require_keys = require("./keys.cjs");
3
+ //#region src/lib/prompts/core/runtime.ts
4
+ const HIDE_CURSOR = "\x1B[?25l";
5
+ const SHOW_CURSOR = "\x1B[?25h";
6
+ const countLines = (text) => {
7
+ let count = 1;
8
+ for (let i = 0; i < text.length; i++) if (text[i] === "\n") count += 1;
9
+ return count;
10
+ };
11
+ var NodePromptRuntime = class {
12
+ stdin;
13
+ stdout;
14
+ queue = [];
15
+ waiters = [];
16
+ initialized = false;
17
+ previousLines = 0;
18
+ buffer = "";
19
+ constructor(stdin = process.stdin, stdout = process.stdout) {
20
+ this.stdin = stdin;
21
+ this.stdout = stdout;
22
+ }
23
+ isInteractive() {
24
+ return Boolean(this.stdin.isTTY && this.stdout.isTTY && typeof this.stdin.setRawMode === "function");
25
+ }
26
+ init() {
27
+ if (!this.isInteractive()) return require_lib_errors_index.err("PromptEnvironmentError", "Interactive prompts require a TTY with raw mode support");
28
+ if (this.initialized) return require_lib_errors_index.ok(void 0);
29
+ const [initError] = require_lib_errors_index.mightThrowSync(() => {
30
+ this.stdin.setRawMode(true);
31
+ this.stdin.setEncoding("utf8");
32
+ this.stdin.resume();
33
+ this.stdin.on("data", this.onData);
34
+ this.stdout.write(HIDE_CURSOR);
35
+ });
36
+ if (initError) return require_lib_errors_index.err("PromptIOError", "Unable to initialize prompt runtime");
37
+ this.initialized = true;
38
+ return require_lib_errors_index.ok(void 0);
39
+ }
40
+ readKey() {
41
+ const queued = this.queue.shift();
42
+ if (queued) return Promise.resolve(require_lib_errors_index.ok(queued));
43
+ return new Promise((resolve) => {
44
+ this.waiters.push(resolve);
45
+ });
46
+ }
47
+ render(frame) {
48
+ const [renderError] = require_lib_errors_index.mightThrowSync(() => {
49
+ if (this.previousLines > 1) this.stdout.write(`\u001B[${this.previousLines - 1}A`);
50
+ this.stdout.write("\r\x1B[J");
51
+ this.stdout.write(frame);
52
+ this.previousLines = countLines(frame);
53
+ });
54
+ if (renderError) return require_lib_errors_index.err("PromptIOError", "Unable to render prompt frame");
55
+ return require_lib_errors_index.ok(void 0);
56
+ }
57
+ done(frame) {
58
+ const [doneError] = require_lib_errors_index.mightThrowSync(() => {
59
+ if (this.previousLines > 1) this.stdout.write(`\u001B[${this.previousLines - 1}A`);
60
+ this.stdout.write("\r\x1B[J");
61
+ this.stdout.write(`${frame}\n`);
62
+ this.previousLines = 0;
63
+ });
64
+ if (doneError) return require_lib_errors_index.err("PromptIOError", "Unable to finalize prompt frame");
65
+ return require_lib_errors_index.ok(void 0);
66
+ }
67
+ close() {
68
+ if (!this.initialized) return require_lib_errors_index.ok(void 0);
69
+ this.initialized = false;
70
+ const [closeError] = require_lib_errors_index.mightThrowSync(() => {
71
+ this.stdin.off("data", this.onData);
72
+ this.stdin.setRawMode(false);
73
+ this.stdin.pause?.();
74
+ this.stdout.write(SHOW_CURSOR);
75
+ });
76
+ if (closeError) return require_lib_errors_index.err("PromptIOError", "Unable to close prompt runtime");
77
+ return require_lib_errors_index.ok(void 0);
78
+ }
79
+ interrupt() {
80
+ this.close();
81
+ process.exit(0);
82
+ }
83
+ onData = (chunk) => {
84
+ const value = typeof chunk === "string" ? chunk : chunk.toString("utf8");
85
+ const combined = `${this.buffer}${value}`;
86
+ this.buffer = "";
87
+ const [parseError, result] = require_lib_errors_index.mightThrowSync(() => require_keys.parseKeys(combined));
88
+ if (parseError || !result) {
89
+ for (const waiter of this.waiters.splice(0)) waiter(require_lib_errors_index.err("PromptIOError", "Failed to parse input"));
90
+ return;
91
+ }
92
+ this.buffer = result.remaining;
93
+ for (const key of result.keys) {
94
+ const waiter = this.waiters.shift();
95
+ if (waiter) waiter(require_lib_errors_index.ok(key));
96
+ else this.queue.push(key);
97
+ }
98
+ };
99
+ };
100
+ const createNodePromptRuntime = () => {
101
+ return new NodePromptRuntime();
102
+ };
103
+ //#endregion
104
+ exports.createNodePromptRuntime = createNodePromptRuntime;
@@ -0,0 +1,106 @@
1
+ import { err, mightThrowSync, ok } from "../../lib/errors/index.mjs";
2
+ import { parseKeys } from "./keys.mjs";
3
+ //#region src/lib/prompts/core/runtime.ts
4
+ const HIDE_CURSOR = "\x1B[?25l";
5
+ const SHOW_CURSOR = "\x1B[?25h";
6
+ const countLines = (text) => {
7
+ let count = 1;
8
+ for (let i = 0; i < text.length; i++) if (text[i] === "\n") count += 1;
9
+ return count;
10
+ };
11
+ var NodePromptRuntime = class {
12
+ stdin;
13
+ stdout;
14
+ queue = [];
15
+ waiters = [];
16
+ initialized = false;
17
+ previousLines = 0;
18
+ buffer = "";
19
+ constructor(stdin = process.stdin, stdout = process.stdout) {
20
+ this.stdin = stdin;
21
+ this.stdout = stdout;
22
+ }
23
+ isInteractive() {
24
+ return Boolean(this.stdin.isTTY && this.stdout.isTTY && typeof this.stdin.setRawMode === "function");
25
+ }
26
+ init() {
27
+ if (!this.isInteractive()) return err("PromptEnvironmentError", "Interactive prompts require a TTY with raw mode support");
28
+ if (this.initialized) return ok(void 0);
29
+ const [initError] = mightThrowSync(() => {
30
+ this.stdin.setRawMode(true);
31
+ this.stdin.setEncoding("utf8");
32
+ this.stdin.resume();
33
+ this.stdin.on("data", this.onData);
34
+ this.stdout.write(HIDE_CURSOR);
35
+ });
36
+ if (initError) return err("PromptIOError", "Unable to initialize prompt runtime");
37
+ this.initialized = true;
38
+ return ok(void 0);
39
+ }
40
+ readKey() {
41
+ const queued = this.queue.shift();
42
+ if (queued) return Promise.resolve(ok(queued));
43
+ return new Promise((resolve) => {
44
+ this.waiters.push(resolve);
45
+ });
46
+ }
47
+ render(frame) {
48
+ const [renderError] = mightThrowSync(() => {
49
+ if (this.previousLines > 1) this.stdout.write(`\u001B[${this.previousLines - 1}A`);
50
+ this.stdout.write("\r\x1B[J");
51
+ this.stdout.write(frame);
52
+ this.previousLines = countLines(frame);
53
+ });
54
+ if (renderError) return err("PromptIOError", "Unable to render prompt frame");
55
+ return ok(void 0);
56
+ }
57
+ done(frame) {
58
+ const [doneError] = mightThrowSync(() => {
59
+ if (this.previousLines > 1) this.stdout.write(`\u001B[${this.previousLines - 1}A`);
60
+ this.stdout.write("\r\x1B[J");
61
+ this.stdout.write(`${frame}\n`);
62
+ this.previousLines = 0;
63
+ });
64
+ if (doneError) return err("PromptIOError", "Unable to finalize prompt frame");
65
+ return ok(void 0);
66
+ }
67
+ close() {
68
+ if (!this.initialized) return ok(void 0);
69
+ this.initialized = false;
70
+ const [closeError] = mightThrowSync(() => {
71
+ this.stdin.off("data", this.onData);
72
+ this.stdin.setRawMode(false);
73
+ this.stdin.pause?.();
74
+ this.stdout.write(SHOW_CURSOR);
75
+ });
76
+ if (closeError) return err("PromptIOError", "Unable to close prompt runtime");
77
+ return ok(void 0);
78
+ }
79
+ interrupt() {
80
+ this.close();
81
+ process.exit(0);
82
+ }
83
+ onData = (chunk) => {
84
+ const value = typeof chunk === "string" ? chunk : chunk.toString("utf8");
85
+ const combined = `${this.buffer}${value}`;
86
+ this.buffer = "";
87
+ const [parseError, result] = mightThrowSync(() => parseKeys(combined));
88
+ if (parseError || !result) {
89
+ for (const waiter of this.waiters.splice(0)) waiter(err("PromptIOError", "Failed to parse input"));
90
+ return;
91
+ }
92
+ this.buffer = result.remaining;
93
+ for (const key of result.keys) {
94
+ const waiter = this.waiters.shift();
95
+ if (waiter) waiter(ok(key));
96
+ else this.queue.push(key);
97
+ }
98
+ };
99
+ };
100
+ const createNodePromptRuntime = () => {
101
+ return new NodePromptRuntime();
102
+ };
103
+ //#endregion
104
+ export { createNodePromptRuntime };
105
+
106
+ //# sourceMappingURL=runtime.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.mjs","names":[],"sources":["../../../src/lib/prompts/core/runtime.ts"],"sourcesContent":["import { err, mightThrowSync, ok } from \"../../errors/index.js\";\nimport { parseKeys } from \"./keys.js\";\nimport type { Key, PromptResultLike, PromptRuntime } from \"./types.js\";\n\nconst HIDE_CURSOR = \"\\u001B[?25l\";\nconst SHOW_CURSOR = \"\\u001B[?25h\";\n\nconst countLines = (text: string) => {\n let count = 1;\n\n for (let i = 0; i < text.length; i++) {\n if (text[i] === \"\\n\") {\n count += 1;\n }\n }\n\n return count;\n};\n\ntype StdinLike = {\n isTTY?: boolean;\n setRawMode: (mode: boolean) => void;\n setEncoding: (encoding: BufferEncoding) => void;\n resume: () => void;\n pause?: () => void;\n on: (event: string, listener: (chunk: Buffer | string) => void) => unknown;\n off: (event: string, listener: (chunk: Buffer | string) => void) => unknown;\n};\n\ntype StdoutLike = {\n isTTY?: boolean;\n write: (chunk: string) => boolean;\n};\n\nexport class NodePromptRuntime implements PromptRuntime {\n private readonly stdin: StdinLike;\n private readonly stdout: StdoutLike;\n private readonly queue: Key[] = [];\n private readonly waiters: Array<(result: PromptResultLike<Key>) => void> = [];\n private initialized = false;\n private previousLines = 0;\n private buffer = \"\";\n\n public constructor(\n stdin: StdinLike = process.stdin,\n stdout: StdoutLike = process.stdout,\n ) {\n this.stdin = stdin;\n this.stdout = stdout;\n }\n\n public isInteractive() {\n return Boolean(\n this.stdin.isTTY &&\n this.stdout.isTTY &&\n typeof this.stdin.setRawMode === \"function\",\n );\n }\n\n public init() {\n if (!this.isInteractive()) {\n return err(\n \"PromptEnvironmentError\",\n \"Interactive prompts require a TTY with raw mode support\",\n );\n }\n\n if (this.initialized) {\n return ok(undefined);\n }\n\n const [initError] = mightThrowSync(() => {\n this.stdin.setRawMode(true);\n this.stdin.setEncoding(\"utf8\");\n this.stdin.resume();\n this.stdin.on(\"data\", this.onData);\n this.stdout.write(HIDE_CURSOR);\n });\n\n if (initError) {\n return err(\"PromptIOError\", \"Unable to initialize prompt runtime\");\n }\n\n this.initialized = true;\n return ok(undefined);\n }\n\n public readKey(): Promise<PromptResultLike<Key>> {\n const queued = this.queue.shift();\n\n if (queued) {\n return Promise.resolve(ok(queued));\n }\n\n return new Promise<PromptResultLike<Key>>((resolve) => {\n this.waiters.push(resolve);\n });\n }\n\n public render(frame: string) {\n const [renderError] = mightThrowSync(() => {\n if (this.previousLines > 1) {\n this.stdout.write(`\\u001B[${this.previousLines - 1}A`);\n }\n\n this.stdout.write(\"\\r\\u001B[J\");\n this.stdout.write(frame);\n\n this.previousLines = countLines(frame);\n });\n\n if (renderError) {\n return err(\"PromptIOError\", \"Unable to render prompt frame\");\n }\n\n return ok(undefined);\n }\n\n public done(frame: string) {\n const [doneError] = mightThrowSync(() => {\n if (this.previousLines > 1) {\n this.stdout.write(`\\u001B[${this.previousLines - 1}A`);\n }\n\n this.stdout.write(\"\\r\\u001B[J\");\n this.stdout.write(`${frame}\\n`);\n this.previousLines = 0;\n });\n\n if (doneError) {\n return err(\"PromptIOError\", \"Unable to finalize prompt frame\");\n }\n\n return ok(undefined);\n }\n\n public close() {\n if (!this.initialized) {\n return ok(undefined);\n }\n\n this.initialized = false;\n\n const [closeError] = mightThrowSync(() => {\n this.stdin.off(\"data\", this.onData);\n this.stdin.setRawMode(false);\n this.stdin.pause?.();\n this.stdout.write(SHOW_CURSOR);\n });\n\n if (closeError) {\n return err(\"PromptIOError\", \"Unable to close prompt runtime\");\n }\n\n return ok(undefined);\n }\n\n public interrupt(): never {\n this.close();\n process.exit(0);\n }\n\n private onData = (chunk: Buffer | string) => {\n const value = typeof chunk === \"string\" ? chunk : chunk.toString(\"utf8\");\n const combined = `${this.buffer}${value}`;\n this.buffer = \"\";\n\n const [parseError, result] = mightThrowSync(() => parseKeys(combined));\n\n if (parseError || !result) {\n for (const waiter of this.waiters.splice(0)) {\n waiter(err(\"PromptIOError\", \"Failed to parse input\"));\n }\n\n return;\n }\n\n this.buffer = result.remaining;\n\n for (const key of result.keys) {\n const waiter = this.waiters.shift();\n\n if (waiter) {\n waiter(ok(key));\n } else {\n this.queue.push(key);\n }\n }\n };\n}\n\nexport const createNodePromptRuntime = () => {\n return new NodePromptRuntime();\n};\n"],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ const require_lib_errors_index = require("../../lib/errors/index.cjs");
2
+ //#region src/lib/prompts/core/session.ts
3
+ const CANCEL_MESSAGE = "Interrupted, bye!";
4
+ const resolveOutput = async (options, value) => {
5
+ if (!options.transform) return require_lib_errors_index.ok(value);
6
+ const [transformError, transformed] = await require_lib_errors_index.mightThrow(Promise.resolve().then(() => options.transform?.(value)));
7
+ if (transformError || transformed === null || transformed === void 0) return require_lib_errors_index.err("PromptIOError", "Prompt transform callback failed unexpectedly");
8
+ return require_lib_errors_index.ok(transformed);
9
+ };
10
+ const runValidation = async (options, value) => {
11
+ if (!options.validate) return require_lib_errors_index.ok(null);
12
+ const [validationError, validationMessage] = await require_lib_errors_index.mightThrow(Promise.resolve().then(() => options.validate?.(value)));
13
+ if (validationError) return require_lib_errors_index.err("PromptIOError", "Prompt validate callback failed unexpectedly");
14
+ if (typeof validationMessage === "string" && validationMessage.length > 0) return require_lib_errors_index.ok(validationMessage);
15
+ return require_lib_errors_index.ok(null);
16
+ };
17
+ const isCancelKey = (key) => {
18
+ if (key.name === "ctrl_c") return true;
19
+ if (key.name === "escape") return true;
20
+ return false;
21
+ };
22
+ const runPromptSession = async (params) => {
23
+ const [initError] = params.runtime.init();
24
+ if (initError) return require_lib_errors_index.err(initError.type, initError.message);
25
+ let state = params.initialState;
26
+ let errorMessage = null;
27
+ const closeAndDone = (message) => {
28
+ const [closeErr] = params.runtime.close();
29
+ if (closeErr) return require_lib_errors_index.err(closeErr.type, closeErr.message);
30
+ const [doneErr] = params.runtime.done(message);
31
+ if (doneErr) return require_lib_errors_index.err(doneErr.type, doneErr.message);
32
+ return null;
33
+ };
34
+ while (true) {
35
+ const [renderError] = params.runtime.render(params.render({
36
+ options: params.options,
37
+ state,
38
+ errorMessage
39
+ }));
40
+ if (renderError) {
41
+ params.runtime.close();
42
+ return require_lib_errors_index.err(renderError.type, renderError.message);
43
+ }
44
+ const [readError, key] = await params.runtime.readKey();
45
+ if (readError || !key) {
46
+ params.runtime.close();
47
+ return require_lib_errors_index.err(readError?.type ?? "PromptIOError", readError?.message ?? "Unable to read prompt input");
48
+ }
49
+ if (isCancelKey(key)) {
50
+ const [closeError] = params.runtime.close();
51
+ if (closeError) return require_lib_errors_index.err(closeError.type, closeError.message);
52
+ const [doneError] = params.runtime.done(`✖ ${CANCEL_MESSAGE}`);
53
+ if (doneError) return require_lib_errors_index.err(doneError.type, doneError.message);
54
+ if (params.runtime.interrupt) {
55
+ const [interruptError] = params.runtime.interrupt(CANCEL_MESSAGE);
56
+ if (interruptError) return require_lib_errors_index.err(interruptError.type, interruptError.message);
57
+ }
58
+ return require_lib_errors_index.err("PromptCancelledError", CANCEL_MESSAGE);
59
+ }
60
+ if (key.name !== "enter") {
61
+ state = params.onKey(state, key);
62
+ errorMessage = null;
63
+ continue;
64
+ }
65
+ const submitResult = params.onSubmit(state);
66
+ if ("errorMessage" in submitResult) {
67
+ errorMessage = submitResult.errorMessage;
68
+ continue;
69
+ }
70
+ const rawValue = submitResult.value;
71
+ const [validationRunError, validationErrorMessage] = await runValidation(params.options, rawValue);
72
+ if (validationRunError) {
73
+ const closeDoneErr = closeAndDone(`✖ ${params.options.message}`);
74
+ if (closeDoneErr) return closeDoneErr;
75
+ return require_lib_errors_index.err(validationRunError.type, validationRunError.message);
76
+ }
77
+ if (validationErrorMessage) {
78
+ errorMessage = validationErrorMessage;
79
+ continue;
80
+ }
81
+ const [transformError, finalValue] = await resolveOutput(params.options, rawValue);
82
+ if (transformError) {
83
+ const closeDoneErr = closeAndDone(`✖ ${params.options.message}`);
84
+ if (closeDoneErr) return closeDoneErr;
85
+ return require_lib_errors_index.err(transformError.type, transformError.message);
86
+ }
87
+ if (finalValue === null) return require_lib_errors_index.err("PromptIOError", "Unable to transform prompt value");
88
+ const closeDoneErr = closeAndDone(params.complete({
89
+ options: params.options,
90
+ state,
91
+ value: finalValue
92
+ }));
93
+ if (closeDoneErr) return closeDoneErr;
94
+ return require_lib_errors_index.ok(finalValue);
95
+ }
96
+ };
97
+ //#endregion
98
+ exports.runPromptSession = runPromptSession;