@solidxai/core 0.1.13-beta.2 → 0.1.13-beta.21

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 (517) hide show
  1. package/CHANGELOG.md +10107 -0
  2. package/CLAUDE.md +5 -6
  3. package/README.md +19 -0
  4. package/dist/commands/run-tests.command.d.ts +9 -1
  5. package/dist/commands/run-tests.command.d.ts.map +1 -1
  6. package/dist/commands/run-tests.command.js +69 -6
  7. package/dist/commands/run-tests.command.js.map +1 -1
  8. package/dist/commands/seed.command.d.ts +2 -0
  9. package/dist/commands/seed.command.d.ts.map +1 -1
  10. package/dist/commands/seed.command.js +21 -0
  11. package/dist/commands/seed.command.js.map +1 -1
  12. package/dist/config/cache.options.d.ts.map +1 -1
  13. package/dist/config/cache.options.js +2 -2
  14. package/dist/config/cache.options.js.map +1 -1
  15. package/dist/constants/chatter-message.constants.d.ts +1 -0
  16. package/dist/constants/chatter-message.constants.d.ts.map +1 -1
  17. package/dist/constants/chatter-message.constants.js +3 -1
  18. package/dist/constants/chatter-message.constants.js.map +1 -1
  19. package/dist/constants/draft-publish-fields.d.ts +2 -0
  20. package/dist/constants/draft-publish-fields.d.ts.map +1 -0
  21. package/dist/constants/draft-publish-fields.js +5 -0
  22. package/dist/constants/draft-publish-fields.js.map +1 -0
  23. package/dist/constants/error-messages.d.ts +7 -0
  24. package/dist/constants/error-messages.d.ts.map +1 -1
  25. package/dist/constants/error-messages.js +7 -0
  26. package/dist/constants/error-messages.js.map +1 -1
  27. package/dist/constants/media-file-types.d.ts +12 -0
  28. package/dist/constants/media-file-types.d.ts.map +1 -1
  29. package/dist/constants/media-file-types.js +66 -1
  30. package/dist/constants/media-file-types.js.map +1 -1
  31. package/dist/constants/success-messages.d.ts +3 -0
  32. package/dist/constants/success-messages.d.ts.map +1 -1
  33. package/dist/constants/success-messages.js +3 -0
  34. package/dist/constants/success-messages.js.map +1 -1
  35. package/dist/constants/user.constants.d.ts +2 -0
  36. package/dist/constants/user.constants.d.ts.map +1 -0
  37. package/dist/constants/user.constants.js +5 -0
  38. package/dist/constants/user.constants.js.map +1 -0
  39. package/dist/controllers/action-metadata.controller.d.ts +1 -1
  40. package/dist/controllers/action-metadata.controller.js +1 -1
  41. package/dist/controllers/agent-event.controller.d.ts +1 -1
  42. package/dist/controllers/agent-event.controller.js +1 -1
  43. package/dist/controllers/agent-session.controller.d.ts +1 -1
  44. package/dist/controllers/agent-session.controller.js +1 -1
  45. package/dist/controllers/authentication.controller.d.ts +1 -1
  46. package/dist/controllers/authentication.controller.d.ts.map +1 -1
  47. package/dist/controllers/authentication.controller.js +4 -3
  48. package/dist/controllers/authentication.controller.js.map +1 -1
  49. package/dist/controllers/chatter-message.controller.d.ts +5 -0
  50. package/dist/controllers/chatter-message.controller.d.ts.map +1 -1
  51. package/dist/controllers/chatter-message.controller.js +14 -0
  52. package/dist/controllers/chatter-message.controller.js.map +1 -1
  53. package/dist/controllers/dashboard-user-layout.controller.d.ts +1 -1
  54. package/dist/controllers/dashboard-user-layout.controller.js +1 -1
  55. package/dist/controllers/email-template.controller.d.ts +1 -1
  56. package/dist/controllers/email-template.controller.js +1 -1
  57. package/dist/controllers/export-template.controller.d.ts +1 -1
  58. package/dist/controllers/export-template.controller.d.ts.map +1 -1
  59. package/dist/controllers/export-template.controller.js +6 -4
  60. package/dist/controllers/export-template.controller.js.map +1 -1
  61. package/dist/controllers/export-transaction.controller.d.ts +1 -1
  62. package/dist/controllers/export-transaction.controller.js +1 -1
  63. package/dist/controllers/field-metadata.controller.d.ts +2 -2
  64. package/dist/controllers/import-transaction-error-log.controller.d.ts +1 -1
  65. package/dist/controllers/import-transaction-error-log.controller.js +1 -1
  66. package/dist/controllers/import-transaction.controller.d.ts +1 -1
  67. package/dist/controllers/import-transaction.controller.d.ts.map +1 -1
  68. package/dist/controllers/import-transaction.controller.js +7 -7
  69. package/dist/controllers/import-transaction.controller.js.map +1 -1
  70. package/dist/controllers/list-of-values.controller.d.ts +1 -1
  71. package/dist/controllers/list-of-values.controller.js +1 -1
  72. package/dist/controllers/locale.controller.d.ts +1 -1
  73. package/dist/controllers/locale.controller.js +1 -1
  74. package/dist/controllers/mcp-audit-log.controller.d.ts +1 -1
  75. package/dist/controllers/mcp-audit-log.controller.js +1 -1
  76. package/dist/controllers/media.controller.d.ts +2 -2
  77. package/dist/controllers/media.controller.d.ts.map +1 -1
  78. package/dist/controllers/media.controller.js +13 -8
  79. package/dist/controllers/media.controller.js.map +1 -1
  80. package/dist/controllers/menu-item-metadata.controller.d.ts +1 -1
  81. package/dist/controllers/menu-item-metadata.controller.js +1 -1
  82. package/dist/controllers/model-sequence.controller.d.ts +1 -1
  83. package/dist/controllers/model-sequence.controller.js +1 -1
  84. package/dist/controllers/module-package.controller.d.ts.map +1 -1
  85. package/dist/controllers/module-package.controller.js +2 -3
  86. package/dist/controllers/module-package.controller.js.map +1 -1
  87. package/dist/controllers/mpin-authentication.controller.d.ts +44 -0
  88. package/dist/controllers/mpin-authentication.controller.d.ts.map +1 -0
  89. package/dist/controllers/mpin-authentication.controller.js +102 -0
  90. package/dist/controllers/mpin-authentication.controller.js.map +1 -0
  91. package/dist/controllers/mq-message-queue.controller.d.ts +1 -1
  92. package/dist/controllers/mq-message-queue.controller.js +1 -1
  93. package/dist/controllers/mq-message.controller.d.ts +1 -1
  94. package/dist/controllers/mq-message.controller.js +1 -1
  95. package/dist/controllers/permission-metadata.controller.d.ts +1 -1
  96. package/dist/controllers/permission-metadata.controller.js +1 -1
  97. package/dist/controllers/role-metadata.controller.d.ts +1 -1
  98. package/dist/controllers/role-metadata.controller.js +1 -1
  99. package/dist/controllers/saved-filters.controller.d.ts +1 -1
  100. package/dist/controllers/saved-filters.controller.js +1 -1
  101. package/dist/controllers/scheduled-job.controller.d.ts +1 -1
  102. package/dist/controllers/scheduled-job.controller.js +1 -1
  103. package/dist/controllers/security-rule.controller.d.ts +1 -1
  104. package/dist/controllers/security-rule.controller.js +1 -1
  105. package/dist/controllers/sms-template.controller.d.ts +1 -1
  106. package/dist/controllers/sms-template.controller.js +1 -1
  107. package/dist/controllers/user-activity-history.controller.d.ts +1 -1
  108. package/dist/controllers/user-activity-history.controller.js +1 -1
  109. package/dist/controllers/user-view-metadata.controller.d.ts +1 -1
  110. package/dist/controllers/user-view-metadata.controller.js +1 -1
  111. package/dist/controllers/user.controller.d.ts +2 -2
  112. package/dist/controllers/user.controller.js +2 -2
  113. package/dist/controllers/view-metadata.controller.d.ts +2 -2
  114. package/dist/controllers/view-metadata.controller.js +1 -1
  115. package/dist/controllers/workflow-definition.controller.d.ts +1 -1
  116. package/dist/controllers/workflow-definition.controller.js +1 -1
  117. package/dist/controllers/workflow-execution-artifact.controller.d.ts +1 -1
  118. package/dist/controllers/workflow-execution-artifact.controller.js +1 -1
  119. package/dist/controllers/workflow-execution-log.controller.d.ts +1 -1
  120. package/dist/controllers/workflow-execution-log.controller.js +1 -1
  121. package/dist/controllers/workflow-execution.controller.d.ts +1 -1
  122. package/dist/controllers/workflow-execution.controller.js +1 -1
  123. package/dist/controllers/workflow-secret.controller.d.ts +1 -1
  124. package/dist/controllers/workflow-secret.controller.js +1 -1
  125. package/dist/controllers/workflow-step-execution.controller.d.ts +1 -1
  126. package/dist/controllers/workflow-step-execution.controller.js +1 -1
  127. package/dist/controllers/workflow-trigger-execution.controller.d.ts +1 -1
  128. package/dist/controllers/workflow-trigger-execution.controller.js +1 -1
  129. package/dist/dtos/basic-filters.dto.d.ts +0 -1
  130. package/dist/dtos/basic-filters.dto.d.ts.map +1 -1
  131. package/dist/dtos/basic-filters.dto.js +1 -6
  132. package/dist/dtos/basic-filters.dto.js.map +1 -1
  133. package/dist/dtos/change-mpin.dto.d.ts +6 -0
  134. package/dist/dtos/change-mpin.dto.d.ts.map +1 -0
  135. package/dist/dtos/change-mpin.dto.js +39 -0
  136. package/dist/dtos/change-mpin.dto.js.map +1 -0
  137. package/dist/dtos/create-field-metadata.dto.d.ts +3 -6
  138. package/dist/dtos/create-field-metadata.dto.d.ts.map +1 -1
  139. package/dist/dtos/create-field-metadata.dto.js +15 -10
  140. package/dist/dtos/create-field-metadata.dto.js.map +1 -1
  141. package/dist/dtos/create-model-sequence.dto.d.ts +1 -1
  142. package/dist/dtos/create-model-sequence.dto.d.ts.map +1 -1
  143. package/dist/dtos/create-model-sequence.dto.js +1 -1
  144. package/dist/dtos/create-model-sequence.dto.js.map +1 -1
  145. package/dist/dtos/mpin-login.dto.d.ts +5 -0
  146. package/dist/dtos/mpin-login.dto.d.ts.map +1 -0
  147. package/dist/dtos/mpin-login.dto.js +33 -0
  148. package/dist/dtos/mpin-login.dto.js.map +1 -0
  149. package/dist/dtos/setup-mpin.dto.d.ts +7 -0
  150. package/dist/dtos/setup-mpin.dto.d.ts.map +1 -0
  151. package/dist/dtos/setup-mpin.dto.js +47 -0
  152. package/dist/dtos/setup-mpin.dto.js.map +1 -0
  153. package/dist/entities/common.entity.d.ts +4 -0
  154. package/dist/entities/common.entity.d.ts.map +1 -1
  155. package/dist/entities/common.entity.js +25 -1
  156. package/dist/entities/common.entity.js.map +1 -1
  157. package/dist/entities/dashboard-user-layout.entity.js +2 -2
  158. package/dist/entities/dashboard-user-layout.entity.js.map +1 -1
  159. package/dist/entities/field-metadata.entity.d.ts +1 -0
  160. package/dist/entities/field-metadata.entity.d.ts.map +1 -1
  161. package/dist/entities/field-metadata.entity.js +5 -1
  162. package/dist/entities/field-metadata.entity.js.map +1 -1
  163. package/dist/entities/saved-filters.entity.js +3 -3
  164. package/dist/entities/saved-filters.entity.js.map +1 -1
  165. package/dist/entities/user-device-credential.entity.d.ts +18 -0
  166. package/dist/entities/user-device-credential.entity.d.ts.map +1 -0
  167. package/dist/entities/user-device-credential.entity.js +91 -0
  168. package/dist/entities/user-device-credential.entity.js.map +1 -0
  169. package/dist/entities/user.entity.d.ts.map +1 -1
  170. package/dist/entities/user.entity.js +36 -0
  171. package/dist/entities/user.entity.js.map +1 -1
  172. package/dist/entities/view-metadata.entity.js.map +1 -1
  173. package/dist/entities/workflow-execution-artifact.entity.d.ts.map +1 -1
  174. package/dist/entities/workflow-execution-artifact.entity.js +4 -3
  175. package/dist/entities/workflow-execution-artifact.entity.js.map +1 -1
  176. package/dist/entities/workflow-execution-log.entity.d.ts.map +1 -1
  177. package/dist/entities/workflow-execution-log.entity.js +4 -3
  178. package/dist/entities/workflow-execution-log.entity.js.map +1 -1
  179. package/dist/entities/workflow-execution.entity.d.ts.map +1 -1
  180. package/dist/entities/workflow-execution.entity.js +3 -2
  181. package/dist/entities/workflow-execution.entity.js.map +1 -1
  182. package/dist/entities/workflow-secret.entity.d.ts.map +1 -1
  183. package/dist/entities/workflow-secret.entity.js +3 -2
  184. package/dist/entities/workflow-secret.entity.js.map +1 -1
  185. package/dist/entities/workflow-step-execution.entity.d.ts.map +1 -1
  186. package/dist/entities/workflow-step-execution.entity.js +3 -2
  187. package/dist/entities/workflow-step-execution.entity.js.map +1 -1
  188. package/dist/entities/workflow-trigger-execution.entity.d.ts.map +1 -1
  189. package/dist/entities/workflow-trigger-execution.entity.js +7 -6
  190. package/dist/entities/workflow-trigger-execution.entity.js.map +1 -1
  191. package/dist/factories/mail.factory.d.ts.map +1 -1
  192. package/dist/factories/mail.factory.js +4 -0
  193. package/dist/factories/mail.factory.js.map +1 -1
  194. package/dist/filters/http-exception.filter.d.ts.map +1 -1
  195. package/dist/filters/http-exception.filter.js +5 -1
  196. package/dist/filters/http-exception.filter.js.map +1 -1
  197. package/dist/helpers/bootstrap.helper.d.ts +5 -2
  198. package/dist/helpers/bootstrap.helper.d.ts.map +1 -1
  199. package/dist/helpers/bootstrap.helper.js +7 -3
  200. package/dist/helpers/bootstrap.helper.js.map +1 -1
  201. package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts +7 -0
  202. package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts.map +1 -1
  203. package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js +66 -32
  204. package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js.map +1 -1
  205. package/dist/helpers/file-download.helper.d.ts +9 -0
  206. package/dist/helpers/file-download.helper.d.ts.map +1 -0
  207. package/dist/helpers/file-download.helper.js +19 -0
  208. package/dist/helpers/file-download.helper.js.map +1 -0
  209. package/dist/helpers/model-metadata-helper.service.d.ts.map +1 -1
  210. package/dist/helpers/model-metadata-helper.service.js +30 -1
  211. package/dist/helpers/model-metadata-helper.service.js.map +1 -1
  212. package/dist/helpers/security.helper.d.ts +5 -1
  213. package/dist/helpers/security.helper.d.ts.map +1 -1
  214. package/dist/helpers/security.helper.js +15 -4
  215. package/dist/helpers/security.helper.js.map +1 -1
  216. package/dist/helpers/solid-core-error-codes-provider.service.d.ts.map +1 -1
  217. package/dist/helpers/solid-core-error-codes-provider.service.js +45 -0
  218. package/dist/helpers/solid-core-error-codes-provider.service.js.map +1 -1
  219. package/dist/helpers/solid-microservice-adapter.service.d.ts.map +1 -1
  220. package/dist/helpers/solid-microservice-adapter.service.js +1 -1
  221. package/dist/helpers/solid-microservice-adapter.service.js.map +1 -1
  222. package/dist/helpers/solid-registry.js +1 -1
  223. package/dist/helpers/solid-registry.js.map +1 -1
  224. package/dist/helpers/typeorm-db-helper.d.ts.map +1 -1
  225. package/dist/helpers/typeorm-db-helper.js +9 -0
  226. package/dist/helpers/typeorm-db-helper.js.map +1 -1
  227. package/dist/index.d.ts +10 -0
  228. package/dist/index.d.ts.map +1 -1
  229. package/dist/index.js +10 -0
  230. package/dist/index.js.map +1 -1
  231. package/dist/interfaces/active-user-data.interface.d.ts +1 -0
  232. package/dist/interfaces/active-user-data.interface.d.ts.map +1 -1
  233. package/dist/interfaces/active-user-data.interface.js.map +1 -1
  234. package/dist/interfaces.d.ts +1 -0
  235. package/dist/interfaces.d.ts.map +1 -1
  236. package/dist/interfaces.js.map +1 -1
  237. package/dist/repository/user-device-credential.repository.d.ts +12 -0
  238. package/dist/repository/user-device-credential.repository.d.ts.map +1 -0
  239. package/dist/repository/user-device-credential.repository.js +34 -0
  240. package/dist/repository/user-device-credential.repository.js.map +1 -0
  241. package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
  242. package/dist/seeders/module-metadata-seeder.service.js +51 -30
  243. package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
  244. package/dist/seeders/module-test-data.service.d.ts +3 -1
  245. package/dist/seeders/module-test-data.service.d.ts.map +1 -1
  246. package/dist/seeders/module-test-data.service.js +8 -2
  247. package/dist/seeders/module-test-data.service.js.map +1 -1
  248. package/dist/seeders/seed-data/solid-core-metadata.json +290 -78
  249. package/dist/services/api-key.service.d.ts.map +1 -1
  250. package/dist/services/api-key.service.js +1 -1
  251. package/dist/services/api-key.service.js.map +1 -1
  252. package/dist/services/authentication.service.d.ts +9 -5
  253. package/dist/services/authentication.service.d.ts.map +1 -1
  254. package/dist/services/authentication.service.js +102 -23
  255. package/dist/services/authentication.service.js.map +1 -1
  256. package/dist/services/chatter-message.service.d.ts +16 -1
  257. package/dist/services/chatter-message.service.d.ts.map +1 -1
  258. package/dist/services/chatter-message.service.js +100 -16
  259. package/dist/services/chatter-message.service.js.map +1 -1
  260. package/dist/services/crud-helper.service.d.ts +6 -4
  261. package/dist/services/crud-helper.service.d.ts.map +1 -1
  262. package/dist/services/crud-helper.service.js +32 -48
  263. package/dist/services/crud-helper.service.js.map +1 -1
  264. package/dist/services/crud.service.d.ts +13 -1
  265. package/dist/services/crud.service.d.ts.map +1 -1
  266. package/dist/services/crud.service.js +94 -68
  267. package/dist/services/crud.service.js.map +1 -1
  268. package/dist/services/datasource-introspection.service.d.ts.map +1 -1
  269. package/dist/services/datasource-introspection.service.js.map +1 -1
  270. package/dist/services/draft-publish-helper.service.d.ts +53 -0
  271. package/dist/services/draft-publish-helper.service.d.ts.map +1 -0
  272. package/dist/services/draft-publish-helper.service.js +402 -0
  273. package/dist/services/draft-publish-helper.service.js.map +1 -0
  274. package/dist/services/field-metadata.service.d.ts +2 -2
  275. package/dist/services/field-metadata.service.d.ts.map +1 -1
  276. package/dist/services/field-metadata.service.js +4 -1
  277. package/dist/services/field-metadata.service.js.map +1 -1
  278. package/dist/services/internationalisation-helper.service.d.ts +19 -0
  279. package/dist/services/internationalisation-helper.service.d.ts.map +1 -0
  280. package/dist/services/internationalisation-helper.service.js +107 -0
  281. package/dist/services/internationalisation-helper.service.js.map +1 -0
  282. package/dist/services/locale.service.d.ts +1 -1
  283. package/dist/services/media-storage.utils.d.ts +1 -0
  284. package/dist/services/media-storage.utils.d.ts.map +1 -1
  285. package/dist/services/media-storage.utils.js +12 -1
  286. package/dist/services/media-storage.utils.js.map +1 -1
  287. package/dist/services/media.service.d.ts +3 -2
  288. package/dist/services/media.service.d.ts.map +1 -1
  289. package/dist/services/media.service.js +45 -29
  290. package/dist/services/media.service.js.map +1 -1
  291. package/dist/services/metadata-validation.service.d.ts +7 -0
  292. package/dist/services/metadata-validation.service.d.ts.map +1 -0
  293. package/dist/services/metadata-validation.service.js +42 -0
  294. package/dist/services/metadata-validation.service.js.map +1 -0
  295. package/dist/services/model-metadata.service.d.ts.map +1 -1
  296. package/dist/services/model-metadata.service.js +2 -1
  297. package/dist/services/model-metadata.service.js.map +1 -1
  298. package/dist/services/module-metadata.service.d.ts.map +1 -1
  299. package/dist/services/module-metadata.service.js +9 -1
  300. package/dist/services/module-metadata.service.js.map +1 -1
  301. package/dist/services/mpin.service.d.ts +67 -0
  302. package/dist/services/mpin.service.d.ts.map +1 -0
  303. package/dist/services/mpin.service.js +282 -0
  304. package/dist/services/mpin.service.js.map +1 -0
  305. package/dist/services/object.utils.d.ts +2 -0
  306. package/dist/services/object.utils.d.ts.map +1 -0
  307. package/dist/services/object.utils.js +11 -0
  308. package/dist/services/object.utils.js.map +1 -0
  309. package/dist/services/refresh-token-ids-storage.service.d.ts +25 -6
  310. package/dist/services/refresh-token-ids-storage.service.d.ts.map +1 -1
  311. package/dist/services/refresh-token-ids-storage.service.js +80 -42
  312. package/dist/services/refresh-token-ids-storage.service.js.map +1 -1
  313. package/dist/services/setting.service.d.ts.map +1 -1
  314. package/dist/services/setting.service.js +6 -1
  315. package/dist/services/setting.service.js.map +1 -1
  316. package/dist/services/settings/default-settings-provider.service.d.ts +248 -12
  317. package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
  318. package/dist/services/settings/default-settings-provider.service.js +143 -6
  319. package/dist/services/settings/default-settings-provider.service.js.map +1 -1
  320. package/dist/services/user.service.d.ts +2 -2
  321. package/dist/services/user.service.d.ts.map +1 -1
  322. package/dist/services/user.service.js +9 -3
  323. package/dist/services/user.service.js.map +1 -1
  324. package/dist/services/view-metadata.service.d.ts +1 -2
  325. package/dist/services/view-metadata.service.d.ts.map +1 -1
  326. package/dist/services/view-metadata.service.js +3 -55
  327. package/dist/services/view-metadata.service.js.map +1 -1
  328. package/dist/services/workflow/nodes/execution-fail.node.d.ts +6 -0
  329. package/dist/services/workflow/nodes/execution-fail.node.d.ts.map +1 -0
  330. package/dist/services/workflow/nodes/execution-fail.node.js +81 -0
  331. package/dist/services/workflow/nodes/execution-fail.node.js.map +1 -0
  332. package/dist/services/workflow/nodes/for-each.node.d.ts +2 -0
  333. package/dist/services/workflow/nodes/for-each.node.d.ts.map +1 -1
  334. package/dist/services/workflow/nodes/for-each.node.js +114 -5
  335. package/dist/services/workflow/nodes/for-each.node.js.map +1 -1
  336. package/dist/services/workflow/nodes/if.node.d.ts.map +1 -1
  337. package/dist/services/workflow/nodes/if.node.js +7 -0
  338. package/dist/services/workflow/nodes/if.node.js.map +1 -1
  339. package/dist/services/workflow/nodes/log-write.node.d.ts.map +1 -1
  340. package/dist/services/workflow/nodes/log-write.node.js +2 -0
  341. package/dist/services/workflow/nodes/log-write.node.js.map +1 -1
  342. package/dist/services/workflow/nodes/loop-until.node.d.ts +12 -0
  343. package/dist/services/workflow/nodes/loop-until.node.d.ts.map +1 -0
  344. package/dist/services/workflow/nodes/loop-until.node.js +281 -0
  345. package/dist/services/workflow/nodes/loop-until.node.js.map +1 -0
  346. package/dist/services/workflow/nodes/parallel.node.d.ts.map +1 -1
  347. package/dist/services/workflow/nodes/parallel.node.js +7 -0
  348. package/dist/services/workflow/nodes/parallel.node.js.map +1 -1
  349. package/dist/services/workflow/nodes/sequential.node.d.ts.map +1 -1
  350. package/dist/services/workflow/nodes/sequential.node.js +7 -0
  351. package/dist/services/workflow/nodes/sequential.node.js.map +1 -1
  352. package/dist/services/workflow/nodes/switch.node.d.ts.map +1 -1
  353. package/dist/services/workflow/nodes/switch.node.js +7 -0
  354. package/dist/services/workflow/nodes/switch.node.js.map +1 -1
  355. package/dist/services/workflow/workflow-definition-validator.service.d.ts.map +1 -1
  356. package/dist/services/workflow/workflow-definition-validator.service.js +5 -2
  357. package/dist/services/workflow/workflow-definition-validator.service.js.map +1 -1
  358. package/dist/services/workflow/workflow-expression.service.d.ts.map +1 -1
  359. package/dist/services/workflow/workflow-expression.service.js +5 -0
  360. package/dist/services/workflow/workflow-expression.service.js.map +1 -1
  361. package/dist/services/workflow/workflow-node-registry.service.d.ts +2 -1
  362. package/dist/services/workflow/workflow-node-registry.service.d.ts.map +1 -1
  363. package/dist/services/workflow/workflow-node-registry.service.js +7 -0
  364. package/dist/services/workflow/workflow-node-registry.service.js.map +1 -1
  365. package/dist/services/workflow/workflow-runtime.service.d.ts +8 -0
  366. package/dist/services/workflow/workflow-runtime.service.d.ts.map +1 -1
  367. package/dist/services/workflow/workflow-runtime.service.js +197 -32
  368. package/dist/services/workflow/workflow-runtime.service.js.map +1 -1
  369. package/dist/services/workflow-definition.service.d.ts +1 -1
  370. package/dist/solid-core.module.d.ts +1 -3
  371. package/dist/solid-core.module.d.ts.map +1 -1
  372. package/dist/solid-core.module.js +28 -40
  373. package/dist/solid-core.module.js.map +1 -1
  374. package/dist/testing/adapters/ui/playwright-adapter.d.ts +5 -0
  375. package/dist/testing/adapters/ui/playwright-adapter.d.ts.map +1 -1
  376. package/dist/testing/adapters/ui/playwright-adapter.js +17 -1
  377. package/dist/testing/adapters/ui/playwright-adapter.js.map +1 -1
  378. package/dist/testing/adapters/ui/ui.types.d.ts +2 -0
  379. package/dist/testing/adapters/ui/ui.types.d.ts.map +1 -1
  380. package/dist/testing/adapters/ui/ui.types.js.map +1 -1
  381. package/dist/testing/reporter/console-reporter.d.ts +3 -0
  382. package/dist/testing/reporter/console-reporter.d.ts.map +1 -1
  383. package/dist/testing/reporter/console-reporter.js +2 -0
  384. package/dist/testing/reporter/console-reporter.js.map +1 -1
  385. package/dist/testing/reporter/progress-reporter.d.ts +64 -0
  386. package/dist/testing/reporter/progress-reporter.d.ts.map +1 -0
  387. package/dist/testing/reporter/progress-reporter.js +224 -0
  388. package/dist/testing/reporter/progress-reporter.js.map +1 -0
  389. package/dist/testing/reporter/reporter.types.d.ts +3 -0
  390. package/dist/testing/reporter/reporter.types.d.ts.map +1 -1
  391. package/dist/testing/reporter/reporter.types.js.map +1 -1
  392. package/dist/testing/runner/run-from-metadata.d.ts.map +1 -1
  393. package/dist/testing/runner/run-from-metadata.js +1 -0
  394. package/dist/testing/runner/run-from-metadata.js.map +1 -1
  395. package/dist/testing/steps/ui/actions.step.d.ts.map +1 -1
  396. package/dist/testing/steps/ui/actions.step.js +6 -2
  397. package/dist/testing/steps/ui/actions.step.js.map +1 -1
  398. package/dist/testing/steps/ui/assertions.step.d.ts.map +1 -1
  399. package/dist/testing/steps/ui/assertions.step.js +11 -3
  400. package/dist/testing/steps/ui/assertions.step.js.map +1 -1
  401. package/dist/testing/steps/ui/form.step.d.ts.map +1 -1
  402. package/dist/testing/steps/ui/form.step.js +9 -3
  403. package/dist/testing/steps/ui/form.step.js.map +1 -1
  404. package/dist/testing/steps/ui/manual.step.js +1 -1
  405. package/dist/testing/steps/ui/manual.step.js.map +1 -1
  406. package/dist/testing/steps/ui/navigation.step.d.ts.map +1 -1
  407. package/dist/testing/steps/ui/navigation.step.js +3 -1
  408. package/dist/testing/steps/ui/navigation.step.js.map +1 -1
  409. package/dist/theme/theme-registry.d.ts +14 -0
  410. package/dist/theme/theme-registry.d.ts.map +1 -0
  411. package/dist/theme/theme-registry.js +147 -0
  412. package/dist/theme/theme-registry.js.map +1 -0
  413. package/dist/types/workflow-dsl.types.d.ts +14 -0
  414. package/dist/types/workflow-dsl.types.d.ts.map +1 -1
  415. package/dist/types/workflow-dsl.types.js.map +1 -1
  416. package/package.json +2 -2
  417. package/src/commands/run-tests.command.ts +64 -4
  418. package/src/commands/seed.command.ts +19 -0
  419. package/src/config/cache.options.ts +9 -1
  420. package/src/constants/chatter-message.constants.ts +12 -0
  421. package/src/constants/draft-publish-fields.ts +5 -0
  422. package/src/constants/error-messages.ts +14 -0
  423. package/src/constants/media-file-types.ts +128 -0
  424. package/src/constants/success-messages.ts +5 -0
  425. package/src/constants/user.constants.ts +13 -0
  426. package/src/controllers/authentication.controller.ts +5 -2
  427. package/src/controllers/chatter-message.controller.ts +8 -0
  428. package/src/controllers/export-template.controller.ts +5 -3
  429. package/src/controllers/import-transaction.controller.ts +6 -6
  430. package/src/controllers/media.controller.ts +17 -6
  431. package/src/controllers/module-package.controller.ts +2 -3
  432. package/src/controllers/mpin-authentication.controller.ts +67 -0
  433. package/src/dtos/basic-filters.dto.ts +0 -4
  434. package/src/dtos/change-mpin.dto.ts +18 -0
  435. package/src/dtos/create-field-metadata.dto.ts +17 -9
  436. package/src/dtos/create-model-sequence.dto.ts +1 -1
  437. package/src/dtos/mpin-login.dto.ts +24 -0
  438. package/src/dtos/setup-mpin.dto.ts +51 -0
  439. package/src/entities/common.entity.ts +24 -0
  440. package/src/entities/dashboard-user-layout.entity.ts +2 -2
  441. package/src/entities/field-metadata.entity.ts +3 -0
  442. package/src/entities/saved-filters.entity.ts +3 -3
  443. package/src/entities/user-device-credential.entity.ts +130 -0
  444. package/src/entities/user.entity.ts +53 -36
  445. package/src/entities/view-metadata.entity.ts +2 -2
  446. package/src/entities/workflow-execution-artifact.entity.ts +4 -3
  447. package/src/entities/workflow-execution-log.entity.ts +4 -3
  448. package/src/entities/workflow-execution.entity.ts +3 -2
  449. package/src/entities/workflow-secret.entity.ts +3 -2
  450. package/src/entities/workflow-step-execution.entity.ts +3 -2
  451. package/src/entities/workflow-trigger-execution.entity.ts +7 -6
  452. package/src/factories/mail.factory.ts +7 -1
  453. package/src/filters/http-exception.filter.ts +11 -1
  454. package/src/helpers/bootstrap.helper.ts +43 -6
  455. package/src/helpers/field-crud-managers/MediaFieldCrudManager.ts +90 -37
  456. package/src/helpers/file-download.helper.ts +45 -0
  457. package/src/helpers/model-metadata-helper.service.ts +32 -1
  458. package/src/helpers/security.helper.ts +35 -8
  459. package/src/helpers/solid-core-error-codes-provider.service.ts +53 -0
  460. package/src/helpers/solid-microservice-adapter.service.ts +6 -1
  461. package/src/helpers/solid-registry.ts +1 -1
  462. package/src/helpers/typeorm-db-helper.ts +12 -1
  463. package/src/index.ts +10 -0
  464. package/src/interfaces/active-user-data.interface.ts +9 -0
  465. package/src/interfaces.ts +1 -0
  466. package/src/repository/user-device-credential.repository.ts +17 -0
  467. package/src/seeders/module-metadata-seeder.service.ts +61 -39
  468. package/src/seeders/module-test-data.service.ts +6 -0
  469. package/src/seeders/seed-data/solid-core-metadata.json +290 -78
  470. package/src/services/api-key.service.ts +13 -1
  471. package/src/services/authentication.service.ts +203 -41
  472. package/src/services/chatter-message.service.ts +180 -19
  473. package/src/services/crud-helper.service.ts +35 -50
  474. package/src/services/crud.service.ts +132 -105
  475. package/src/services/datasource-introspection.service.ts +5 -0
  476. package/src/services/draft-publish-helper.service.ts +581 -0
  477. package/src/services/field-metadata.service.ts +5 -2
  478. package/src/services/internationalisation-helper.service.ts +148 -0
  479. package/src/services/media-storage.utils.ts +26 -1
  480. package/src/services/media.service.ts +68 -36
  481. package/src/services/metadata-validation.service.ts +39 -0
  482. package/src/services/model-metadata.service.ts +4 -1
  483. package/src/services/module-metadata.service.ts +10 -1
  484. package/src/services/mpin.service.ts +447 -0
  485. package/src/services/object.utils.ts +10 -0
  486. package/src/services/refresh-token-ids-storage.service.ts +229 -90
  487. package/src/services/setting.service.ts +8 -1
  488. package/src/services/settings/default-settings-provider.service.ts +154 -6
  489. package/src/services/user.service.ts +18 -3
  490. package/src/services/view-metadata.service.ts +5 -145
  491. package/src/services/workflow/nodes/execution-fail.node.ts +82 -0
  492. package/src/services/workflow/nodes/for-each.node.ts +140 -6
  493. package/src/services/workflow/nodes/if.node.ts +7 -0
  494. package/src/services/workflow/nodes/log-write.node.ts +2 -0
  495. package/src/services/workflow/nodes/loop-until.node.ts +343 -0
  496. package/src/services/workflow/nodes/parallel.node.ts +7 -0
  497. package/src/services/workflow/nodes/sequential.node.ts +7 -0
  498. package/src/services/workflow/nodes/switch.node.ts +7 -0
  499. package/src/services/workflow/workflow-definition-validator.service.ts +5 -2
  500. package/src/services/workflow/workflow-expression.service.ts +5 -0
  501. package/src/services/workflow/workflow-node-registry.service.ts +11 -0
  502. package/src/services/workflow/workflow-runtime.service.ts +274 -39
  503. package/src/solid-core.module.ts +46 -15
  504. package/src/testing/README.md +75 -3
  505. package/src/testing/adapters/ui/playwright-adapter.ts +25 -0
  506. package/src/testing/adapters/ui/ui.types.ts +2 -0
  507. package/src/testing/reporter/console-reporter.ts +4 -0
  508. package/src/testing/reporter/progress-reporter.ts +251 -0
  509. package/src/testing/reporter/reporter.types.ts +3 -0
  510. package/src/testing/runner/run-from-metadata.ts +1 -0
  511. package/src/testing/steps/ui/actions.step.ts +8 -4
  512. package/src/testing/steps/ui/assertions.step.ts +18 -5
  513. package/src/testing/steps/ui/form.step.ts +16 -6
  514. package/src/testing/steps/ui/manual.step.ts +1 -1
  515. package/src/testing/steps/ui/navigation.step.ts +4 -2
  516. package/src/theme/theme-registry.ts +181 -0
  517. package/src/types/workflow-dsl.types.ts +43 -0
@@ -75,6 +75,57 @@ General step fields:
75
75
  - `timeoutMs` (optional): per-step timeout override
76
76
  - `spec` (optional): used by `test.spec` to identify the spec
77
77
 
78
+ ## Timeouts
79
+ There are two independent timeout layers. They are easy to confuse, so note which one you want:
80
+
81
+ **1. Engine timeouts** — `scenario.timeoutMs` and the top-level `step.timeoutMs`.
82
+ These wrap execution in a `Promise.race` (`core/timeout.ts`). They are a hard upper bound
83
+ on wall-clock time and do **not** cancel the underlying browser call, so the failure message
84
+ only tells you the scenario or op that overran.
85
+
86
+ **2. UI (Playwright) timeouts** — the run-wide default plus per-step `with.timeoutMs`.
87
+ This is what governs how long `ui.expectVisible`, `ui.click`, `ui.fill` etc. wait for a
88
+ selector. Playwright cancels the operation itself, so the error names the selector and the
89
+ state it was waiting for. **If your UI steps are timing out, this is the knob to turn.**
90
+
91
+ Resolution order for UI steps: `with.timeoutMs` → `--ui-timeout-ms` → `UI_TIMEOUT_MS` →
92
+ `uiTestDefaultTimeoutMs` setting → `30000`.
93
+ `ui.goto` uses the navigation timeout instead: `with.timeoutMs` → `--ui-navigation-timeout-ms`
94
+ → `UI_NAVIGATION_TIMEOUT_MS` → `uiTestNavigationTimeoutMs` setting → the resolved UI timeout.
95
+
96
+ Raise the default for a whole run:
97
+ ```bash
98
+ solid test run --module <module-name> --ui-timeout-ms 60000
99
+ # or
100
+ UI_TIMEOUT_MS=60000 solid test run --module <module-name>
101
+ ```
102
+
103
+ Or set the installation-wide default under **Settings → Testing Settings** in the admin UI
104
+ (`uiTestDefaultTimeoutMs` / `uiTestNavigationTimeoutMs`). Those rows are created by `solid seed`;
105
+ until then the built-in `30000` applies. Flags and env vars still win, so CI keeps per-run control.
106
+
107
+ The seeded value of those two settings can be provisioned from the environment with
108
+ `COMMON_UI_TEST_DEFAULT_TIMEOUT_MS` and `COMMON_UI_TEST_NAVIGATION_TIMEOUT_MS` (the latter falls
109
+ back to the former). Seeding is insert-only, so these apply on first seed only — afterwards the
110
+ stored value wins and the setting must be changed in the admin UI. Values that are missing,
111
+ non-numeric, or not positive fall back to `30000`.
112
+
113
+ Note these are distinct from the run-time `UI_TIMEOUT_MS` / `UI_NAVIGATION_TIMEOUT_MS` vars,
114
+ which override the setting on a per-run basis and are read every run.
115
+
116
+ Or bump only the one slow step, leaving the rest of the suite strict:
117
+ ```json
118
+ {
119
+ "then": {
120
+ "op": "ui.expectVisible",
121
+ "with": { "selector": "#report-grid", "timeoutMs": 90000 }
122
+ }
123
+ }
124
+ ```
125
+
126
+ Caution: a scenario-level `timeoutMs` lower than the UI timeout will fire first and mask the
127
+ more useful Playwright error. Keep `defaults.timeoutMs` above your UI timeout.
128
+
78
129
  ## Interpolation
79
130
  Available tokens:
80
131
  - `${env:NAME}` (environment variables)
@@ -198,6 +249,7 @@ Description: Navigates the browser to a URL.
198
249
 
199
250
  Options in `with`:
200
251
  - `url` (required)
252
+ - `timeoutMs` (optional, overrides the run-wide UI navigation timeout)
201
253
 
202
254
  ### **Op: `ui.expectUrl`**
203
255
  Description: Asserts the current page URL.
@@ -212,6 +264,7 @@ Description: Fills an input or editable element.
212
264
  Options in `with`:
213
265
  - `selector` (required)
214
266
  - `value` (required)
267
+ - `timeoutMs` (optional, overrides the run-wide UI timeout)
215
268
 
216
269
  ### **Op: `ui.select`**
217
270
  Description: Selects an option in a select element.
@@ -219,12 +272,14 @@ Description: Selects an option in a select element.
219
272
  Options in `with`:
220
273
  - `selector` (required)
221
274
  - `value` (required)
275
+ - `timeoutMs` (optional, overrides the run-wide UI timeout)
222
276
 
223
277
  ### **Op: `ui.click`**
224
278
  Description: Clicks an element located by selector.
225
279
 
226
280
  Options in `with`:
227
281
  - `selector` (required)
282
+ - `timeoutMs` (optional, overrides the run-wide UI timeout)
228
283
 
229
284
  ### **Op: `ui.press`**
230
285
  Description: Presses a keyboard key on a focused element.
@@ -232,6 +287,7 @@ Description: Presses a keyboard key on a focused element.
232
287
  Options in `with`:
233
288
  - `selector` (required)
234
289
  - `key` (required)
290
+ - `timeoutMs` (optional, overrides the run-wide UI timeout)
235
291
 
236
292
  ### **Op: `ui.waitForManual`**
237
293
  Description: Pauses a headed Playwright run so a human can interact with the live browser, then resumes when Enter is pressed in the terminal.
@@ -242,7 +298,7 @@ Options in `with`:
242
298
  - `waitForSelector` (optional, waits for a visible selector after resume)
243
299
  - `waitForUrlEquals` (optional, waits until the current URL exactly matches)
244
300
  - `waitForUrlContains` (optional, waits until the current URL contains a substring)
245
- - `timeoutMs` (optional, timeout for post-resume waits)
301
+ - `timeoutMs` (optional, timeout for post-resume waits; defaults to the run-wide UI timeout)
246
302
  - `bringToFront` (optional, defaults to `true`)
247
303
 
248
304
  Notes:
@@ -269,6 +325,7 @@ Description: Waits for an element to be visible.
269
325
 
270
326
  Options in `with`:
271
327
  - `selector` (required)
328
+ - `timeoutMs` (optional, overrides the run-wide UI timeout)
272
329
 
273
330
  ### **Op: `ui.expectText`**
274
331
  Description: Asserts the text content of an element.
@@ -277,6 +334,7 @@ Options in `with`:
277
334
  - `selector` (required)
278
335
  - `equals` (optional)
279
336
  - `contains` (optional)
337
+ - `timeoutMs` (optional, overrides the run-wide UI timeout)
280
338
 
281
339
  ### **Op: `assert.equals`**
282
340
  Description: Asserts strict equality between two values.
@@ -388,7 +446,12 @@ await runFromMetadata({
388
446
  includeTags: ["smoke"],
389
447
  defaults: { timeoutMs: 30_000, retries: 1 },
390
448
  api: { baseUrl: "https://api.example.com" },
391
- ui: { baseUrl: "https://app.example.com", headless: true }
449
+ ui: {
450
+ baseUrl: "https://app.example.com",
451
+ headless: true,
452
+ defaultTimeoutMs: 30_000,
453
+ navigationTimeoutMs: 45_000
454
+ }
392
455
  });
393
456
  ```
394
457
 
@@ -409,9 +472,18 @@ Lightweight existing-database workflow:
409
472
 
410
473
  For human-assisted OTP or third-party verification flows, use `ui.waitForManual` in a headed run so the browser remains interactive while the scenario is paused.
411
474
 
475
+ Common `test run` flags (all pass through solidctl unchanged):
476
+ - `--ui-base-url <url>` / `--api-base-url <url>`
477
+ - `--headless [true|false]`
478
+ - `--ui-timeout-ms <number>` — default wait for every UI step (see [Timeouts](#timeouts))
479
+ - `--ui-navigation-timeout-ms <number>` — default wait for `ui.goto`
480
+ - `--timeout-ms <number>` / `--retries <number>` — scenario-level guard and retry count
481
+ - `--scenario-ids <ids>` / `--include-tags <tags>` / `--skip-scenario-ids <ids>`
482
+ - `--no-progress` — disable the interactive test progress footer
483
+
412
484
  ## Add A New Step (SOP)
413
485
  1. Create a new `*.step.ts` in the right domain folder.
414
486
  2. Implement a `registerXSteps(registry)` function and `registry.register("op.name", handler)`.
415
487
  3. Validate required `step.with` fields and throw clear errors.
416
488
  4. Use adapters via `ctx.api` / `ctx.ui` and update `ctx.last` when helpful.
417
- 5. Export and register it from the domain `index.ts`.
489
+ 5. Export and register it from the domain `index.ts`.
@@ -6,9 +6,13 @@ function isAbsoluteUrl(url: string): boolean {
6
6
  return /^https?:\/\//i.test(url);
7
7
  }
8
8
 
9
+ export const DEFAULT_UI_TIMEOUT_MS = 30_000;
10
+
9
11
  export class PlaywrightAdapter {
10
12
  private readonly baseUrl?: string;
11
13
  private readonly headless: boolean;
14
+ private readonly defaultTimeoutMs: number;
15
+ private readonly navigationTimeoutMs: number;
12
16
  private browser?: Browser;
13
17
  private context?: BrowserContext;
14
18
  public page?: Page;
@@ -16,16 +20,37 @@ export class PlaywrightAdapter {
16
20
  constructor(opts?: PlaywrightAdapterOptions) {
17
21
  this.baseUrl = opts?.baseUrl;
18
22
  this.headless = opts?.headless ?? true;
23
+ this.defaultTimeoutMs = opts?.defaultTimeoutMs ?? DEFAULT_UI_TIMEOUT_MS;
24
+ this.navigationTimeoutMs =
25
+ opts?.navigationTimeoutMs ?? this.defaultTimeoutMs;
19
26
  }
20
27
 
21
28
  isHeadless(): boolean {
22
29
  return this.headless;
23
30
  }
24
31
 
32
+ /**
33
+ * Resolves the timeout for a single Playwright call: an explicit per-step
34
+ * value wins, otherwise the run-wide default applies.
35
+ */
36
+ resolveTimeout(stepTimeoutMs?: number): number {
37
+ return typeof stepTimeoutMs === 'number' && Number.isFinite(stepTimeoutMs)
38
+ ? stepTimeoutMs
39
+ : this.defaultTimeoutMs;
40
+ }
41
+
42
+ resolveNavigationTimeout(stepTimeoutMs?: number): number {
43
+ return typeof stepTimeoutMs === 'number' && Number.isFinite(stepTimeoutMs)
44
+ ? stepTimeoutMs
45
+ : this.navigationTimeoutMs;
46
+ }
47
+
25
48
  async start(): Promise<void> {
26
49
  const { chromium } = await import('playwright');
27
50
  this.browser = await chromium.launch({ headless: this.headless });
28
51
  this.context = await this.browser.newContext();
52
+ this.context.setDefaultTimeout(this.defaultTimeoutMs);
53
+ this.context.setDefaultNavigationTimeout(this.navigationTimeoutMs);
29
54
  this.page = await this.context.newPage();
30
55
  }
31
56
 
@@ -1,4 +1,6 @@
1
1
  export interface PlaywrightAdapterOptions {
2
2
  headless?: boolean;
3
3
  baseUrl?: string;
4
+ defaultTimeoutMs?: number;
5
+ navigationTimeoutMs?: number;
4
6
  }
@@ -150,6 +150,10 @@ export class ConsoleReporter implements Reporter {
150
150
  private passedScenarios = 0;
151
151
  private failedScenarios = 0;
152
152
 
153
+ onRunStart(_args: { total: number }): void {
154
+ // Progress-aware reporters use this hook; the plain console reporter has no setup.
155
+ }
156
+
153
157
  onScenarioStart(scenario: { id: string; name?: string }): void {
154
158
  const label = scenario.name ? `${scenario.id} (${scenario.name})` : scenario.id;
155
159
  console.log(`\n▶ Scenario: ${label}`);
@@ -0,0 +1,251 @@
1
+ import * as readline from "readline";
2
+ import type { StepPhase } from "../contracts/runtime-context.types";
3
+ import type { OpStep, ScenarioSpec } from "../contracts/testing-metadata.types";
4
+ import type { SolidTestSpecResult } from "../contracts/test-spec.types";
5
+ import type { Reporter } from "./reporter.types";
6
+
7
+ const ANSI_BOLD = "\u001b[1m";
8
+ const ANSI_BOLD_OFF = "\u001b[22m";
9
+ const ANSI_DIM = "\u001b[2m";
10
+ const ANSI_GREEN = "\u001b[32m";
11
+ const ANSI_COLOR_OFF = "\u001b[39m";
12
+ const ANSI_RED = "\u001b[31m";
13
+ const ANSI_INVERSE = "\u001b[7m";
14
+ const ANSI_INVERSE_OFF = "\u001b[27m";
15
+
16
+ export class ProgressReporter implements Reporter {
17
+ private startedAt = Date.now();
18
+ private total = 0;
19
+ private completed = 0;
20
+ private passed = 0;
21
+ private failed = 0;
22
+ private timer?: NodeJS.Timeout;
23
+ private rendered = false;
24
+
25
+ constructor(private readonly delegate: Reporter) {}
26
+
27
+ onRunStart(args: { total: number }): void {
28
+ this.total = args.total;
29
+ this.startedAt = Date.now();
30
+ this.completed = 0;
31
+ this.passed = 0;
32
+ this.failed = 0;
33
+ this.delegate.onRunStart?.(args);
34
+ this.startTimer();
35
+ this.renderFooter();
36
+ }
37
+
38
+ onScenarioStart(scenario: ScenarioSpec): void {
39
+ this.withFooterPaused(() => this.delegate.onScenarioStart(scenario));
40
+ }
41
+
42
+ onScenarioEnd(
43
+ scenario: ScenarioSpec,
44
+ result: { ok: boolean; error?: unknown; durationMs: number },
45
+ ): void {
46
+ this.completed += 1;
47
+ if (result.ok) {
48
+ this.passed += 1;
49
+ } else {
50
+ this.failed += 1;
51
+ }
52
+ this.withFooterPaused(() => this.delegate.onScenarioEnd(scenario, result));
53
+ }
54
+
55
+ onStepStart(args: {
56
+ scenarioId: string;
57
+ phase: StepPhase;
58
+ step: OpStep;
59
+ }): void {
60
+ this.withFooterPaused(() => this.delegate.onStepStart(args));
61
+ }
62
+
63
+ onStepEnd(args: {
64
+ scenarioId: string;
65
+ phase: StepPhase;
66
+ step: OpStep;
67
+ ok: boolean;
68
+ error?: unknown;
69
+ durationMs: number;
70
+ }): void {
71
+ this.withFooterPaused(() => this.delegate.onStepEnd(args));
72
+ }
73
+
74
+ onSpecResult(args: {
75
+ scenarioId: string;
76
+ specId: string;
77
+ stepName?: string;
78
+ result: SolidTestSpecResult;
79
+ }): void {
80
+ this.withFooterPaused(() => this.delegate.onSpecResult?.(args));
81
+ }
82
+
83
+ attach(args: {
84
+ scenarioId: string;
85
+ name: string;
86
+ contentType: string;
87
+ data: Buffer | string;
88
+ }): void {
89
+ this.withFooterPaused(() => this.delegate.attach?.(args));
90
+ }
91
+
92
+ onRunEnd(args: {
93
+ ok: boolean;
94
+ total: number;
95
+ passed: number;
96
+ failed: number;
97
+ durationMs: number;
98
+ }): void {
99
+ this.completed = args.passed + args.failed;
100
+ this.passed = args.passed;
101
+ this.failed = args.failed;
102
+ this.total = args.total;
103
+ this.stopTimer();
104
+ this.withFooterPaused(() => this.delegate.onRunEnd?.(args), false);
105
+ }
106
+
107
+ private startTimer(): void {
108
+ this.stopTimer();
109
+ if (!this.isInteractive()) {
110
+ return;
111
+ }
112
+ this.timer = setInterval(() => this.renderFooter(), 1_000);
113
+ this.timer.unref?.();
114
+ }
115
+
116
+ private stopTimer(): void {
117
+ if (!this.timer) {
118
+ return;
119
+ }
120
+ clearInterval(this.timer);
121
+ this.timer = undefined;
122
+ }
123
+
124
+ private withFooterPaused(callback: () => void, renderAfter = true): void {
125
+ this.clearFooter();
126
+ callback();
127
+ if (renderAfter) {
128
+ this.renderFooter();
129
+ }
130
+ }
131
+
132
+ private renderFooter(): void {
133
+ if (!this.isInteractive()) {
134
+ return;
135
+ }
136
+
137
+ const terminalWidth = process.stdout.columns || 80;
138
+ const elapsed = formatElapsed(Date.now() - this.startedAt);
139
+ const progressText = `${this.completed}/${this.total}`;
140
+ const resultText = `${ANSI_GREEN}${this.passed} passed${ANSI_COLOR_OFF}${ANSI_DIM} | ${ANSI_BOLD_OFF}${this.failed ? ANSI_RED : ANSI_DIM}${this.failed} failed${this.failed ? ANSI_COLOR_OFF : ANSI_BOLD_OFF}`;
141
+ const footer = [
142
+ `${ANSI_BOLD}Tests${ANSI_BOLD_OFF}: ${this.renderProgressBar(terminalWidth)} ${progressText}`,
143
+ `${ANSI_BOLD}Elapsed${ANSI_BOLD_OFF}: ${elapsed}`,
144
+ resultText,
145
+ ].join(`${ANSI_DIM} | ${ANSI_BOLD_OFF}`);
146
+
147
+ readline.clearLine(process.stdout, 0);
148
+ readline.cursorTo(process.stdout, 0);
149
+ process.stdout.write(truncateAnsiText(`${ANSI_INVERSE} ${footer} ${ANSI_INVERSE_OFF}`, terminalWidth));
150
+ this.rendered = true;
151
+ }
152
+
153
+ private clearFooter(): void {
154
+ if (!this.rendered || !this.isInteractive()) {
155
+ return;
156
+ }
157
+ readline.clearLine(process.stdout, 0);
158
+ readline.cursorTo(process.stdout, 0);
159
+ this.rendered = false;
160
+ }
161
+
162
+ private renderProgressBar(terminalWidth: number): string {
163
+ const width = terminalWidth >= 120 ? 30 : terminalWidth >= 90 ? 22 : 14;
164
+ const ratio = this.total > 0 ? Math.min(1, this.completed / this.total) : 0;
165
+ const filled = Math.round(width * ratio);
166
+ const empty = Math.max(0, width - filled);
167
+ return `[${ANSI_GREEN}${"=".repeat(filled)}${ANSI_COLOR_OFF}${" ".repeat(empty)}]`;
168
+ }
169
+
170
+ private isInteractive(): boolean {
171
+ return Boolean(process.stdout.isTTY || process.env.SOLIDCTL_TEST_PROGRESS === "1");
172
+ }
173
+ }
174
+
175
+ function formatElapsed(durationMs: number): string {
176
+ const totalSeconds = Math.max(0, Math.floor(durationMs / 1000));
177
+ const minutes = Math.floor(totalSeconds / 60);
178
+ const seconds = totalSeconds % 60;
179
+ if (minutes < 60) {
180
+ return `${minutes}:${seconds.toString().padStart(2, "0")}`;
181
+ }
182
+ const hours = Math.floor(minutes / 60);
183
+ const remainingMinutes = minutes % 60;
184
+ return `${hours}:${remainingMinutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`;
185
+ }
186
+
187
+ function truncateAnsiText(text: string, maxWidth: number): string {
188
+ if (maxWidth <= 0) {
189
+ return "";
190
+ }
191
+
192
+ let visibleWidth = 0;
193
+ let index = 0;
194
+ let output = "";
195
+ let hasEscape = false;
196
+
197
+ while (index < text.length) {
198
+ if (text[index] === "\u001b") {
199
+ const match = /\u001b\[[0-9;]*m/.exec(text.slice(index));
200
+ if (!match) {
201
+ break;
202
+ }
203
+ output += match[0];
204
+ hasEscape = true;
205
+ index += match[0].length;
206
+ continue;
207
+ }
208
+
209
+ if (visibleWidth >= maxWidth) {
210
+ break;
211
+ }
212
+
213
+ output += text[index];
214
+ visibleWidth += 1;
215
+ index += 1;
216
+ }
217
+
218
+ if (index < text.length && maxWidth >= 1) {
219
+ output = trimAnsiText(output, maxWidth - 1) + "…";
220
+ }
221
+
222
+ if (hasEscape && !output.endsWith(ANSI_INVERSE_OFF)) {
223
+ output += ANSI_INVERSE_OFF;
224
+ }
225
+
226
+ return output;
227
+ }
228
+
229
+ function trimAnsiText(text: string, maxWidth: number): string {
230
+ let visibleWidth = 0;
231
+ let index = 0;
232
+ let output = "";
233
+
234
+ while (index < text.length && visibleWidth < maxWidth) {
235
+ if (text[index] === "\u001b") {
236
+ const match = /\u001b\[[0-9;]*m/.exec(text.slice(index));
237
+ if (!match) {
238
+ break;
239
+ }
240
+ output += match[0];
241
+ index += match[0].length;
242
+ continue;
243
+ }
244
+
245
+ output += text[index];
246
+ visibleWidth += 1;
247
+ index += 1;
248
+ }
249
+
250
+ return output;
251
+ }
@@ -3,6 +3,9 @@ import type { OpStep, ScenarioSpec } from "../contracts/testing-metadata.types";
3
3
  import type { SolidTestSpecResult } from "../contracts/test-spec.types";
4
4
 
5
5
  export interface Reporter {
6
+ onRunStart?(args: {
7
+ total: number;
8
+ }): void;
6
9
  onScenarioStart(scenario: ScenarioSpec): void;
7
10
  onScenarioEnd(
8
11
  scenario: ScenarioSpec,
@@ -67,6 +67,7 @@ export async function runFromMetadata(opts: RunnerOptions): Promise<void> {
67
67
 
68
68
  const resources = new SimpleResourceStore();
69
69
  const reporter = opts.reporter ?? new ConsoleReporter();
70
+ reporter.onRunStart?.({ total: scenarios.length });
70
71
  const api = new ApiAdapter(opts.api);
71
72
  const { PlaywrightAdapter } = await import("../adapters/ui/playwright-adapter");
72
73
  const ui = new PlaywrightAdapter(opts.ui);
@@ -2,8 +2,8 @@ import type { TestContext } from "../../contracts/runtime-context.types";
2
2
  import type { OpStep } from "../../contracts/testing-metadata.types";
3
3
  import { StepRegistry } from "../../core/step-registry";
4
4
 
5
- type ClickInput = { selector: string };
6
- type PressInput = { selector: string; key: string };
5
+ type ClickInput = { selector: string; timeoutMs?: number };
6
+ type PressInput = { selector: string; key: string; timeoutMs?: number };
7
7
 
8
8
  function requirePage(ctx: TestContext, op: string) {
9
9
  if (!ctx.ui || !ctx.ui.page) {
@@ -19,7 +19,9 @@ export function registerActionSteps(registry: StepRegistry): void {
19
19
  if (!input.selector) {
20
20
  throw new Error('Missing "selector" in step.with for op "ui.click"');
21
21
  }
22
- await page.click(input.selector);
22
+ await page.click(input.selector, {
23
+ timeout: ctx.ui?.resolveTimeout(input.timeoutMs),
24
+ });
23
25
  });
24
26
 
25
27
  registry.register("ui.press", async (ctx: TestContext, step: OpStep) => {
@@ -31,6 +33,8 @@ export function registerActionSteps(registry: StepRegistry): void {
31
33
  if (!input.key) {
32
34
  throw new Error('Missing "key" in step.with for op "ui.press"');
33
35
  }
34
- await page.press(input.selector, input.key);
36
+ await page.press(input.selector, input.key, {
37
+ timeout: ctx.ui?.resolveTimeout(input.timeoutMs),
38
+ });
35
39
  });
36
40
  }
@@ -2,8 +2,13 @@ import type { TestContext } from "../../contracts/runtime-context.types";
2
2
  import type { OpStep } from "../../contracts/testing-metadata.types";
3
3
  import { StepRegistry } from "../../core/step-registry";
4
4
 
5
- type VisibleInput = { selector: string };
6
- type ExpectTextInput = { selector: string; equals?: string; contains?: string };
5
+ type VisibleInput = { selector: string; timeoutMs?: number };
6
+ type ExpectTextInput = {
7
+ selector: string;
8
+ equals?: string;
9
+ contains?: string;
10
+ timeoutMs?: number;
11
+ };
7
12
 
8
13
  function requirePage(ctx: TestContext, op: string) {
9
14
  if (!ctx.ui || !ctx.ui.page) {
@@ -19,7 +24,10 @@ export function registerAssertionSteps(registry: StepRegistry): void {
19
24
  if (!input.selector) {
20
25
  throw new Error('Missing "selector" in step.with for op "ui.expectVisible"');
21
26
  }
22
- await page.waitForSelector(input.selector, { state: "visible" });
27
+ await page.waitForSelector(input.selector, {
28
+ state: "visible",
29
+ timeout: ctx.ui?.resolveTimeout(input.timeoutMs),
30
+ });
23
31
  });
24
32
 
25
33
  registry.register("ui.expectHidden", async (ctx: TestContext, step: OpStep) => {
@@ -28,7 +36,10 @@ export function registerAssertionSteps(registry: StepRegistry): void {
28
36
  if (!input.selector) {
29
37
  throw new Error('Missing "selector" in step.with for op "ui.expectHidden"');
30
38
  }
31
- await page.waitForSelector(input.selector, { state: "hidden" });
39
+ await page.waitForSelector(input.selector, {
40
+ state: "hidden",
41
+ timeout: ctx.ui?.resolveTimeout(input.timeoutMs),
42
+ });
32
43
  });
33
44
 
34
45
  registry.register("ui.expectText", async (ctx: TestContext, step: OpStep) => {
@@ -38,7 +49,9 @@ export function registerAssertionSteps(registry: StepRegistry): void {
38
49
  throw new Error('Missing "selector" in step.with for op "ui.expectText"');
39
50
  }
40
51
 
41
- const text = await page.locator(input.selector).innerText();
52
+ const text = await page
53
+ .locator(input.selector)
54
+ .innerText({ timeout: ctx.ui?.resolveTimeout(input.timeoutMs) });
42
55
  if (input.equals !== undefined) {
43
56
  if (text !== input.equals) {
44
57
  throw new Error(
@@ -4,9 +4,13 @@ import type { TestContext } from "../../contracts/runtime-context.types";
4
4
  import type { OpStep } from "../../contracts/testing-metadata.types";
5
5
  import { StepRegistry } from "../../core/step-registry";
6
6
 
7
- type FillInput = { selector: string; value: string };
8
- type SelectInput = { selector: string; value: string };
9
- type UploadFileInput = { selector: string; filePath: string | string[] };
7
+ type FillInput = { selector: string; value: string; timeoutMs?: number };
8
+ type SelectInput = { selector: string; value: string; timeoutMs?: number };
9
+ type UploadFileInput = {
10
+ selector: string;
11
+ filePath: string | string[];
12
+ timeoutMs?: number;
13
+ };
10
14
 
11
15
  function requirePage(ctx: TestContext, op: string) {
12
16
  if (!ctx.ui || !ctx.ui.page) {
@@ -25,7 +29,9 @@ export function registerFormSteps(registry: StepRegistry): void {
25
29
  if (input.value === undefined) {
26
30
  throw new Error('Missing "value" in step.with for op "ui.fill"');
27
31
  }
28
- await page.fill(input.selector, String(input.value));
32
+ await page.fill(input.selector, String(input.value), {
33
+ timeout: ctx.ui?.resolveTimeout(input.timeoutMs),
34
+ });
29
35
  });
30
36
 
31
37
  registry.register("ui.select", async (ctx: TestContext, step: OpStep) => {
@@ -37,7 +43,9 @@ export function registerFormSteps(registry: StepRegistry): void {
37
43
  if (input.value === undefined) {
38
44
  throw new Error('Missing "value" in step.with for op "ui.select"');
39
45
  }
40
- await page.selectOption(input.selector, String(input.value));
46
+ await page.selectOption(input.selector, String(input.value), {
47
+ timeout: ctx.ui?.resolveTimeout(input.timeoutMs),
48
+ });
41
49
  });
42
50
 
43
51
  registry.register("ui.uploadFile", async (ctx: TestContext, step: OpStep) => {
@@ -53,6 +61,8 @@ export function registerFormSteps(registry: StepRegistry): void {
53
61
  const resolved = Array.isArray(input.filePath)
54
62
  ? input.filePath.map((p) => path.resolve(cwd, String(p)))
55
63
  : path.resolve(cwd, String(input.filePath));
56
- await page.setInputFiles(input.selector, resolved);
64
+ await page.setInputFiles(input.selector, resolved, {
65
+ timeout: ctx.ui?.resolveTimeout(input.timeoutMs),
66
+ });
57
67
  });
58
68
  }
@@ -28,7 +28,7 @@ export function registerManualSteps(registry: StepRegistry): void {
28
28
  const inputConfig = (step.with ?? {}) as WaitForManualInput;
29
29
  const message = inputConfig.message?.trim() || "Manual interaction required.";
30
30
  const prompt = inputConfig.prompt?.trim() || "Press Enter to continue...";
31
- const timeoutMs = inputConfig.timeoutMs;
31
+ const timeoutMs = ctx.ui?.resolveTimeout(inputConfig.timeoutMs);
32
32
  const bringToFront = inputConfig.bringToFront ?? true;
33
33
 
34
34
  if (ctx.ui?.isHeadless()) {
@@ -2,7 +2,7 @@ import type { TestContext } from "../../contracts/runtime-context.types";
2
2
  import type { OpStep } from "../../contracts/testing-metadata.types";
3
3
  import { StepRegistry } from "../../core/step-registry";
4
4
 
5
- type GotoInput = { url: string };
5
+ type GotoInput = { url: string; timeoutMs?: number };
6
6
  type ExpectUrlInput = { equals?: string; contains?: string };
7
7
 
8
8
  function requirePage(ctx: TestContext, op: string) {
@@ -20,7 +20,9 @@ export function registerNavigationSteps(registry: StepRegistry): void {
20
20
  throw new Error('Missing "url" in step.with for op "ui.goto"');
21
21
  }
22
22
  const url = ctx.ui?.resolveUrl(input.url) ?? input.url;
23
- await page.goto(url);
23
+ await page.goto(url, {
24
+ timeout: ctx.ui?.resolveNavigationTimeout(input.timeoutMs),
25
+ });
24
26
  });
25
27
 
26
28
  registry.register("ui.expectUrl", async (ctx: TestContext, step: OpStep) => {