@aglyn/aglyn 1.0.0-beta.221 → 1.0.0-beta.222

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 (346) hide show
  1. package/package.json +15 -11
  2. package/src/lib/app-utils/agent-openapi.js +1 -1
  3. package/src/lib/app-utils/agent-openapi.js.map +1 -1
  4. package/src/lib/app-utils/analytics-events.d.ts +3 -2
  5. package/src/lib/app-utils/analytics-events.js +3 -2
  6. package/src/lib/app-utils/analytics-events.js.map +1 -1
  7. package/src/lib/app-utils/api-plugins.d.ts +30 -0
  8. package/src/lib/app-utils/api-plugins.js +24 -1
  9. package/src/lib/app-utils/api-plugins.js.map +1 -1
  10. package/src/lib/app-utils/author-html.d.ts +1 -1
  11. package/src/lib/app-utils/author-html.js.map +1 -1
  12. package/src/lib/app-utils/bandwidth-cap.d.ts +12 -1
  13. package/src/lib/app-utils/bandwidth-cap.js +17 -1
  14. package/src/lib/app-utils/bandwidth-cap.js.map +1 -1
  15. package/src/lib/app-utils/compose-reusable-components.d.ts +19 -0
  16. package/src/lib/app-utils/compose-reusable-components.js +116 -26
  17. package/src/lib/app-utils/compose-reusable-components.js.map +1 -1
  18. package/src/lib/app-utils/console-routes.d.ts +4 -0
  19. package/src/lib/app-utils/console-routes.js +3 -0
  20. package/src/lib/app-utils/console-routes.js.map +1 -1
  21. package/src/lib/app-utils/contacts.d.ts +71 -0
  22. package/src/lib/app-utils/contacts.js +55 -0
  23. package/src/lib/app-utils/contacts.js.map +1 -1
  24. package/src/lib/app-utils/contexts.d.ts +1 -0
  25. package/src/lib/app-utils/contexts.js +1 -0
  26. package/src/lib/app-utils/contexts.js.map +1 -1
  27. package/src/lib/app-utils/crm-email-templates.js +21 -4
  28. package/src/lib/app-utils/crm-email-templates.js.map +1 -1
  29. package/src/lib/app-utils/crm-kinds.d.ts +2 -0
  30. package/src/lib/app-utils/crm-kinds.js +1 -0
  31. package/src/lib/app-utils/crm-kinds.js.map +1 -1
  32. package/src/lib/app-utils/crm.d.ts +1199 -67
  33. package/src/lib/app-utils/crm.js +1951 -310
  34. package/src/lib/app-utils/crm.js.map +1 -1
  35. package/src/lib/app-utils/csv-import.d.ts +10 -38
  36. package/src/lib/app-utils/csv-import.js +17 -42
  37. package/src/lib/app-utils/csv-import.js.map +1 -1
  38. package/src/lib/app-utils/csv.d.ts +32 -11
  39. package/src/lib/app-utils/csv.js +43 -5
  40. package/src/lib/app-utils/csv.js.map +1 -1
  41. package/src/lib/app-utils/default-site.d.ts +116 -0
  42. package/src/lib/app-utils/default-site.js +1024 -0
  43. package/src/lib/app-utils/default-site.js.map +1 -0
  44. package/src/lib/app-utils/docs-help.generated.d.ts +22 -22
  45. package/src/lib/app-utils/docs-help.generated.js +44 -10
  46. package/src/lib/app-utils/docs-help.generated.js.map +1 -1
  47. package/src/lib/app-utils/docs-index.generated.js +738 -150
  48. package/src/lib/app-utils/docs-index.generated.js.map +1 -1
  49. package/src/lib/app-utils/draft-placeholders.d.ts +76 -0
  50. package/src/lib/app-utils/draft-placeholders.js +115 -0
  51. package/src/lib/app-utils/draft-placeholders.js.map +1 -0
  52. package/src/lib/app-utils/entity-picker-context.d.ts +19 -15
  53. package/src/lib/app-utils/entity-picker-context.js +4 -4
  54. package/src/lib/app-utils/entity-picker-context.js.map +1 -1
  55. package/src/lib/app-utils/expand-repeatables.d.ts +66 -10
  56. package/src/lib/app-utils/expand-repeatables.js +88 -14
  57. package/src/lib/app-utils/expand-repeatables.js.map +1 -1
  58. package/src/lib/app-utils/forms.d.ts +33 -22
  59. package/src/lib/app-utils/forms.js +47 -28
  60. package/src/lib/app-utils/forms.js.map +1 -1
  61. package/src/lib/app-utils/full-use-cost.d.ts +277 -0
  62. package/src/lib/app-utils/full-use-cost.js +421 -0
  63. package/src/lib/app-utils/full-use-cost.js.map +1 -0
  64. package/src/lib/app-utils/health-report.js +11 -0
  65. package/src/lib/app-utils/health-report.js.map +1 -1
  66. package/src/lib/app-utils/llms-txt.d.ts +20 -0
  67. package/src/lib/app-utils/llms-txt.js +7 -1
  68. package/src/lib/app-utils/llms-txt.js.map +1 -1
  69. package/src/lib/app-utils/media-asset-facts.d.ts +16 -1
  70. package/src/lib/app-utils/media-asset-facts.js +40 -13
  71. package/src/lib/app-utils/media-asset-facts.js.map +1 -1
  72. package/src/lib/app-utils/media-bandwidth.d.ts +52 -0
  73. package/src/lib/app-utils/media-bandwidth.js +94 -0
  74. package/src/lib/app-utils/media-bandwidth.js.map +1 -0
  75. package/src/lib/app-utils/media-ref.d.ts +241 -33
  76. package/src/lib/app-utils/media-ref.js +324 -43
  77. package/src/lib/app-utils/media-ref.js.map +1 -1
  78. package/src/lib/app-utils/media-src.d.ts +8 -8
  79. package/src/lib/app-utils/media-src.js +27 -11
  80. package/src/lib/app-utils/media-src.js.map +1 -1
  81. package/src/lib/app-utils/media-takedown-reach.d.ts +4 -1
  82. package/src/lib/app-utils/media-takedown-reach.js +6 -3
  83. package/src/lib/app-utils/media-takedown-reach.js.map +1 -1
  84. package/src/lib/app-utils/notifications.d.ts +1 -1
  85. package/src/lib/app-utils/notifications.js +2 -0
  86. package/src/lib/app-utils/notifications.js.map +1 -1
  87. package/src/lib/app-utils/organizations.d.ts +51 -2
  88. package/src/lib/app-utils/organizations.js +56 -3
  89. package/src/lib/app-utils/organizations.js.map +1 -1
  90. package/src/lib/app-utils/page-record-sources.d.ts +87 -0
  91. package/src/lib/app-utils/page-record-sources.js +53 -0
  92. package/src/lib/app-utils/page-record-sources.js.map +1 -0
  93. package/src/lib/app-utils/paid-media-source.d.ts +3 -7
  94. package/src/lib/app-utils/paid-media-source.js +5 -19
  95. package/src/lib/app-utils/paid-media-source.js.map +1 -1
  96. package/src/lib/app-utils/person-erasure.d.ts +5 -2
  97. package/src/lib/app-utils/person-erasure.js.map +1 -1
  98. package/src/lib/app-utils/picklists.d.ts +187 -0
  99. package/src/lib/app-utils/picklists.js +320 -0
  100. package/src/lib/app-utils/picklists.js.map +1 -0
  101. package/src/lib/app-utils/plan-entitlements.d.ts +220 -50
  102. package/src/lib/app-utils/plan-entitlements.js +309 -115
  103. package/src/lib/app-utils/plan-entitlements.js.map +1 -1
  104. package/src/lib/app-utils/realm-host-surface.generated.js +2 -0
  105. package/src/lib/app-utils/realm-host-surface.generated.js.map +1 -1
  106. package/src/lib/app-utils/release-flags.d.ts +1 -1
  107. package/src/lib/app-utils/release-flags.js +11 -0
  108. package/src/lib/app-utils/release-flags.js.map +1 -1
  109. package/src/lib/app-utils/rendered-widths.d.ts +121 -0
  110. package/src/lib/app-utils/rendered-widths.js +211 -0
  111. package/src/lib/app-utils/rendered-widths.js.map +1 -0
  112. package/src/lib/app-utils/repeat-sources.d.ts +2 -1
  113. package/src/lib/app-utils/repeat-sources.js.map +1 -1
  114. package/src/lib/app-utils/screen-route.d.ts +154 -36
  115. package/src/lib/app-utils/screen-route.js +185 -40
  116. package/src/lib/app-utils/screen-route.js.map +1 -1
  117. package/src/lib/app-utils/seo-audit.d.ts +11 -1
  118. package/src/lib/app-utils/seo-audit.js +33 -13
  119. package/src/lib/app-utils/seo-audit.js.map +1 -1
  120. package/src/lib/app-utils/seo-keywords.d.ts +11 -0
  121. package/src/lib/app-utils/seo-keywords.js +19 -5
  122. package/src/lib/app-utils/seo-keywords.js.map +1 -1
  123. package/src/lib/app-utils/seo-page-facts.d.ts +47 -4
  124. package/src/lib/app-utils/seo-page-facts.js +136 -31
  125. package/src/lib/app-utils/seo-page-facts.js.map +1 -1
  126. package/src/lib/app-utils/seo-site-scan.d.ts +42 -4
  127. package/src/lib/app-utils/seo-site-scan.js +113 -12
  128. package/src/lib/app-utils/seo-site-scan.js.map +1 -1
  129. package/src/lib/app-utils/server.d.ts +5 -4
  130. package/src/lib/app-utils/server.js +14 -5
  131. package/src/lib/app-utils/server.js.map +1 -1
  132. package/src/lib/app-utils/site-icon-set.d.ts +195 -0
  133. package/src/lib/app-utils/site-icon-set.js +351 -0
  134. package/src/lib/app-utils/site-icon-set.js.map +1 -0
  135. package/src/lib/app-utils/site-interactions.d.ts +101 -4
  136. package/src/lib/app-utils/site-interactions.js +120 -4
  137. package/src/lib/app-utils/site-interactions.js.map +1 -1
  138. package/src/lib/app-utils/starter-template-nodes.d.ts +7 -0
  139. package/src/lib/app-utils/starter-template-nodes.js +3 -0
  140. package/src/lib/app-utils/starter-template-nodes.js.map +1 -1
  141. package/src/lib/app-utils/starter-templates.d.ts +5 -19
  142. package/src/lib/app-utils/starter-templates.js +5 -49
  143. package/src/lib/app-utils/starter-templates.js.map +1 -1
  144. package/src/lib/app-utils/transfer-launcher-context.d.ts +136 -0
  145. package/src/lib/app-utils/transfer-launcher-context.js +23 -0
  146. package/src/lib/app-utils/transfer-launcher-context.js.map +1 -0
  147. package/src/lib/app-utils/transfer-resume-import.d.ts +39 -0
  148. package/src/lib/app-utils/transfer-resume-import.js +128 -0
  149. package/src/lib/app-utils/transfer-resume-import.js.map +1 -0
  150. package/src/lib/app-utils/upgrade-proposal.d.ts +66 -0
  151. package/src/lib/app-utils/upgrade-proposal.js +95 -0
  152. package/src/lib/app-utils/upgrade-proposal.js.map +1 -0
  153. package/src/lib/app-utils/utc-month.d.ts +33 -0
  154. package/src/lib/app-utils/utc-month.js +35 -0
  155. package/src/lib/app-utils/utc-month.js.map +1 -0
  156. package/src/lib/app-utils/visitor-record-ceiling.d.ts +4 -4
  157. package/src/lib/app-utils/visitor-record-ceiling.js +4 -4
  158. package/src/lib/app-utils/visitor-record-ceiling.js.map +1 -1
  159. package/src/lib/app-utils/wire-nodes.d.ts +39 -19
  160. package/src/lib/app-utils/wire-nodes.js +120 -34
  161. package/src/lib/app-utils/wire-nodes.js.map +1 -1
  162. package/src/lib/data-transfer/access.d.ts +74 -0
  163. package/src/lib/data-transfer/access.js +93 -0
  164. package/src/lib/data-transfer/access.js.map +1 -0
  165. package/src/lib/data-transfer/derive.d.ts +246 -0
  166. package/src/lib/data-transfer/derive.js +1007 -0
  167. package/src/lib/data-transfer/derive.js.map +1 -0
  168. package/src/lib/data-transfer/export-file.d.ts +46 -0
  169. package/src/lib/data-transfer/export-file.js +146 -0
  170. package/src/lib/data-transfer/export-file.js.map +1 -0
  171. package/src/lib/data-transfer/field-catalog.d.ts +134 -0
  172. package/src/lib/data-transfer/field-catalog.js +278 -0
  173. package/src/lib/data-transfer/field-catalog.js.map +1 -0
  174. package/src/lib/data-transfer/header-match.d.ts +129 -0
  175. package/src/lib/data-transfer/header-match.js +367 -0
  176. package/src/lib/data-transfer/header-match.js.map +1 -0
  177. package/src/lib/data-transfer/index.d.ts +34 -0
  178. package/src/lib/data-transfer/index.js +40 -0
  179. package/src/lib/data-transfer/index.js.map +1 -0
  180. package/src/lib/data-transfer/job.d.ts +190 -0
  181. package/src/lib/data-transfer/job.js +229 -0
  182. package/src/lib/data-transfer/job.js.map +1 -0
  183. package/src/lib/data-transfer/lookup.d.ts +45 -0
  184. package/src/lib/data-transfer/lookup.js +71 -0
  185. package/src/lib/data-transfer/lookup.js.map +1 -0
  186. package/src/lib/data-transfer/match.d.ts +99 -0
  187. package/src/lib/data-transfer/match.js +244 -0
  188. package/src/lib/data-transfer/match.js.map +1 -0
  189. package/src/lib/data-transfer/package-plan.d.ts +205 -0
  190. package/src/lib/data-transfer/package-plan.js +475 -0
  191. package/src/lib/data-transfer/package-plan.js.map +1 -0
  192. package/src/lib/data-transfer/package.d.ts +181 -0
  193. package/src/lib/data-transfer/package.js +426 -0
  194. package/src/lib/data-transfer/package.js.map +1 -0
  195. package/src/lib/data-transfer/picklist-map.d.ts +139 -0
  196. package/src/lib/data-transfer/picklist-map.js +271 -0
  197. package/src/lib/data-transfer/picklist-map.js.map +1 -0
  198. package/src/lib/data-transfer/plan.d.ts +176 -0
  199. package/src/lib/data-transfer/plan.js +451 -0
  200. package/src/lib/data-transfer/plan.js.map +1 -0
  201. package/src/lib/data-transfer/policy.d.ts +170 -0
  202. package/src/lib/data-transfer/policy.js +378 -0
  203. package/src/lib/data-transfer/policy.js.map +1 -0
  204. package/src/lib/data-transfer/resource.d.ts +211 -0
  205. package/src/lib/data-transfer/resource.js +241 -0
  206. package/src/lib/data-transfer/resource.js.map +1 -0
  207. package/src/lib/data-transfer/review.d.ts +70 -0
  208. package/src/lib/data-transfer/review.js +233 -0
  209. package/src/lib/data-transfer/review.js.map +1 -0
  210. package/src/lib/data-transfer/similarity.d.ts +40 -0
  211. package/src/lib/data-transfer/similarity.js +106 -0
  212. package/src/lib/data-transfer/similarity.js.map +1 -0
  213. package/src/lib/data-transfer/site-package.d.ts +365 -0
  214. package/src/lib/data-transfer/site-package.js +1077 -0
  215. package/src/lib/data-transfer/site-package.js.map +1 -0
  216. package/src/lib/data-transfer/source.d.ts +74 -0
  217. package/src/lib/data-transfer/source.js +293 -0
  218. package/src/lib/data-transfer/source.js.map +1 -0
  219. package/src/lib/data-transfer/transfer-api.d.ts +898 -0
  220. package/src/lib/data-transfer/transfer-api.js +107 -0
  221. package/src/lib/data-transfer/transfer-api.js.map +1 -0
  222. package/src/lib/foundation/definitions/org-billing.types.d.ts +31 -0
  223. package/src/lib/foundation/definitions/org-billing.types.js.map +1 -1
  224. package/src/lib/foundation/definitions/organization.types.d.ts +42 -1
  225. package/src/lib/foundation/definitions/organization.types.js.map +1 -1
  226. package/src/lib/foundation/definitions/platform.types.d.ts +6 -4
  227. package/src/lib/foundation/definitions/platform.types.js.map +1 -1
  228. package/src/lib/foundation/index.d.ts +1 -1
  229. package/src/lib/foundation/index.js.map +1 -1
  230. package/src/lib/plugin-manager/feature-plugins.d.ts +91 -2
  231. package/src/lib/plugin-manager/feature-plugins.js +48 -3
  232. package/src/lib/plugin-manager/feature-plugins.js.map +1 -1
  233. package/src/lib/plugin-manager/first-party-plugins.generated.d.ts +50 -0
  234. package/src/lib/plugin-manager/first-party-plugins.generated.js +1129 -28
  235. package/src/lib/plugin-manager/first-party-plugins.generated.js.map +1 -1
  236. package/src/lib/plugin-manager/index.d.ts +0 -1
  237. package/src/lib/plugin-manager/index.js +0 -1
  238. package/src/lib/plugin-manager/index.js.map +1 -1
  239. package/src/lib/plugin-manager/interaction-recipes.d.ts +142 -0
  240. package/src/lib/plugin-manager/interaction-recipes.js +104 -0
  241. package/src/lib/plugin-manager/interaction-recipes.js.map +1 -0
  242. package/src/lib/plugin-manager/interaction-step-checks.d.ts +66 -0
  243. package/src/lib/plugin-manager/interaction-step-checks.js +86 -0
  244. package/src/lib/plugin-manager/interaction-step-checks.js.map +1 -0
  245. package/src/lib/plugin-manager/plugin-artifact-types.d.ts +235 -0
  246. package/src/lib/plugin-manager/plugin-artifact-types.js +99 -0
  247. package/src/lib/plugin-manager/plugin-artifact-types.js.map +1 -0
  248. package/src/lib/plugin-manager/plugin-contact-capture.d.ts +8 -0
  249. package/src/lib/plugin-manager/plugin-contact-capture.js.map +1 -1
  250. package/src/lib/plugin-manager/plugin-conversion-credit.d.ts +216 -0
  251. package/src/lib/plugin-manager/plugin-conversion-credit.js +91 -0
  252. package/src/lib/plugin-manager/plugin-conversion-credit.js.map +1 -0
  253. package/src/lib/plugin-manager/plugin-entity-pickers.d.ts +83 -0
  254. package/src/lib/plugin-manager/plugin-entity-pickers.js +87 -0
  255. package/src/lib/plugin-manager/plugin-entity-pickers.js.map +1 -0
  256. package/src/lib/plugin-manager/plugin-host-resources.d.ts +6 -0
  257. package/src/lib/plugin-manager/plugin-host-resources.js +6 -1
  258. package/src/lib/plugin-manager/plugin-host-resources.js.map +1 -1
  259. package/src/lib/plugin-manager/plugin-intake-gates.d.ts +75 -0
  260. package/src/lib/plugin-manager/plugin-intake-gates.js +49 -0
  261. package/src/lib/plugin-manager/plugin-intake-gates.js.map +1 -0
  262. package/src/lib/plugin-manager/plugin-jobs.d.ts +5 -5
  263. package/src/lib/plugin-manager/plugin-jobs.js +7 -7
  264. package/src/lib/plugin-manager/plugin-jobs.js.map +1 -1
  265. package/src/lib/plugin-manager/plugin-live-paths.d.ts +70 -0
  266. package/src/lib/plugin-manager/plugin-live-paths.js +66 -0
  267. package/src/lib/plugin-manager/plugin-live-paths.js.map +1 -0
  268. package/src/lib/plugin-manager/plugin-org-erasure.d.ts +3 -2
  269. package/src/lib/plugin-manager/plugin-org-erasure.js +30 -5
  270. package/src/lib/plugin-manager/plugin-org-erasure.js.map +1 -1
  271. package/src/lib/plugin-manager/plugin-person-erasure.d.ts +68 -9
  272. package/src/lib/plugin-manager/plugin-person-erasure.js +196 -51
  273. package/src/lib/plugin-manager/plugin-person-erasure.js.map +1 -1
  274. package/src/lib/plugin-manager/plugin-person-records.d.ts +275 -0
  275. package/src/lib/plugin-manager/plugin-person-records.js +107 -0
  276. package/src/lib/plugin-manager/plugin-person-records.js.map +1 -0
  277. package/src/lib/plugin-manager/plugin-record-counts.d.ts +76 -0
  278. package/src/lib/plugin-manager/plugin-record-counts.js +49 -0
  279. package/src/lib/plugin-manager/plugin-record-counts.js.map +1 -0
  280. package/src/lib/plugin-manager/plugin-record-email-state.d.ts +26 -0
  281. package/src/lib/plugin-manager/plugin-record-email-state.js +16 -0
  282. package/src/lib/plugin-manager/plugin-record-email-state.js.map +1 -1
  283. package/src/lib/plugin-manager/plugin-record-index.d.ts +10 -0
  284. package/src/lib/plugin-manager/plugin-record-index.js.map +1 -1
  285. package/src/lib/plugin-manager/plugin-record-lists.d.ts +86 -6
  286. package/src/lib/plugin-manager/plugin-record-lists.js +42 -5
  287. package/src/lib/plugin-manager/plugin-record-lists.js.map +1 -1
  288. package/src/lib/plugin-manager/plugin-record-origin.d.ts +79 -0
  289. package/src/lib/plugin-manager/plugin-record-origin.js +46 -0
  290. package/src/lib/plugin-manager/plugin-record-origin.js.map +1 -0
  291. package/src/lib/plugin-manager/plugin-record-pages.d.ts +37 -0
  292. package/src/lib/plugin-manager/plugin-record-pages.js +52 -0
  293. package/src/lib/plugin-manager/plugin-record-pages.js.map +1 -0
  294. package/src/lib/plugin-manager/plugin-record-timeline.d.ts +60 -0
  295. package/src/lib/plugin-manager/plugin-record-timeline.js +16 -0
  296. package/src/lib/plugin-manager/plugin-record-timeline.js.map +1 -1
  297. package/src/lib/plugin-manager/plugin-resource-drafts.d.ts +5 -5
  298. package/src/lib/plugin-manager/plugin-resource-drafts.js.map +1 -1
  299. package/src/lib/plugin-manager/plugin-revocations.d.ts +64 -0
  300. package/src/lib/plugin-manager/plugin-revocations.js +47 -0
  301. package/src/lib/plugin-manager/plugin-revocations.js.map +1 -0
  302. package/src/lib/plugin-manager/plugin-send-tallies.d.ts +69 -0
  303. package/src/lib/plugin-manager/plugin-send-tallies.js +45 -0
  304. package/src/lib/plugin-manager/plugin-send-tallies.js.map +1 -0
  305. package/src/lib/plugin-manager/plugin-site-bundle.d.ts +40 -0
  306. package/src/lib/plugin-manager/plugin-site-bundle.js +4 -0
  307. package/src/lib/plugin-manager/plugin-site-bundle.js.map +1 -1
  308. package/src/lib/plugin-manager/plugin-site-export.d.ts +57 -1
  309. package/src/lib/plugin-manager/plugin-site-export.js +23 -10
  310. package/src/lib/plugin-manager/plugin-site-export.js.map +1 -1
  311. package/src/lib/plugin-manager/plugin-sitemap-readers.d.ts +146 -0
  312. package/src/lib/plugin-manager/plugin-sitemap-readers.js +110 -0
  313. package/src/lib/plugin-manager/plugin-sitemap-readers.js.map +1 -0
  314. package/src/lib/plugin-manager/plugin-transfer-resources.d.ts +714 -0
  315. package/src/lib/plugin-manager/plugin-transfer-resources.js +443 -0
  316. package/src/lib/plugin-manager/plugin-transfer-resources.js.map +1 -0
  317. package/src/lib/plugin-manager/plugin-usage-axes.d.ts +54 -5
  318. package/src/lib/plugin-manager/plugin-usage-axes.js +11 -3
  319. package/src/lib/plugin-manager/plugin-usage-axes.js.map +1 -1
  320. package/src/lib/plugin-manager/plugin-user-erasure.js +9 -1
  321. package/src/lib/plugin-manager/plugin-user-erasure.js.map +1 -1
  322. package/src/lib/plugin-manager/plugin-visitor-doors.d.ts +104 -0
  323. package/src/lib/plugin-manager/plugin-visitor-doors.js +108 -0
  324. package/src/lib/plugin-manager/plugin-visitor-doors.js.map +1 -0
  325. package/src/lib/plugin-manager/realm-host-aglyn.generated.js +2 -0
  326. package/src/lib/plugin-manager/realm-host-aglyn.generated.js.map +1 -1
  327. package/src/lib/plugin-manager/repeat-rows.d.ts +5 -6
  328. package/src/lib/plugin-manager/repeat-rows.js.map +1 -1
  329. package/src/lib/app-utils/actions.d.ts +0 -310
  330. package/src/lib/app-utils/actions.js +0 -506
  331. package/src/lib/app-utils/actions.js.map +0 -1
  332. package/src/lib/app-utils/automation-placeholders.d.ts +0 -72
  333. package/src/lib/app-utils/automation-placeholders.js +0 -207
  334. package/src/lib/app-utils/automation-placeholders.js.map +0 -1
  335. package/src/lib/app-utils/dataset-models.d.ts +0 -339
  336. package/src/lib/app-utils/dataset-models.js +0 -722
  337. package/src/lib/app-utils/dataset-models.js.map +0 -1
  338. package/src/lib/app-utils/datasets.d.ts +0 -171
  339. package/src/lib/app-utils/datasets.js +0 -227
  340. package/src/lib/app-utils/datasets.js.map +0 -1
  341. package/src/lib/app-utils/form-abuse-ceiling.d.ts +0 -146
  342. package/src/lib/app-utils/form-abuse-ceiling.js +0 -158
  343. package/src/lib/app-utils/form-abuse-ceiling.js.map +0 -1
  344. package/src/lib/plugin-manager/order-fulfilment.d.ts +0 -142
  345. package/src/lib/plugin-manager/order-fulfilment.js +0 -104
  346. package/src/lib/plugin-manager/order-fulfilment.js.map +0 -1
@@ -0,0 +1,190 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import type { TransferFieldMode, TransferPolicy } from './policy';
18
+ import type { TransferPlanSummary, TransferRowReason, TransferWarningClass } from './plan';
19
+ import type { TransferFormat, TransferKind } from './resource';
20
+ /** Rows per chunk: a chunk is planned, applied and reported as one. */
21
+ export declare const TRANSFER_CHUNK_ROWS = 200;
22
+ /** The most writes in one batch (Firestore's limit). */
23
+ export declare const TRANSFER_BATCH_WRITES_MAX = 500;
24
+ /** How many records are written at once within a chunk. */
25
+ export declare const TRANSFER_WRITE_CONCURRENCY = 8;
26
+ /** How long an applied import may be undone. */
27
+ export declare const TRANSFER_UNDO_WINDOW_MS: number;
28
+ export type TransferJobStatus = 'draft' | 'analyzed' | 'planned' | 'applying' | 'applied' | 'failed' | 'undone';
29
+ export declare const TRANSFER_JOB_STATUSES: readonly TransferJobStatus[];
30
+ /**
31
+ * The moves each state allows. A state may be re-entered where the work is
32
+ * repeatable: re-analyzing, re-planning after a changed choice, and
33
+ * `applying` → `applying` as each chunk advances the cursor.
34
+ */
35
+ export declare const TRANSFER_JOB_TRANSITIONS: Readonly<Record<TransferJobStatus, readonly TransferJobStatus[]>>;
36
+ /** Whether a job may move from `from` to `to`. */
37
+ export declare function canTransitionTransferJob(from: TransferJobStatus, to: TransferJobStatus): boolean;
38
+ /** A move the state machine does not allow. */
39
+ export declare class TransferJobTransitionError extends Error {
40
+ readonly from: TransferJobStatus;
41
+ readonly to: TransferJobStatus;
42
+ constructor(from: TransferJobStatus, to: TransferJobStatus);
43
+ }
44
+ /** Where applying has reached: the next chunk to write. */
45
+ export interface TransferJobCursor {
46
+ chunk: number;
47
+ /** Rows written so far (all chunks before `chunk`). */
48
+ rowsDone: number;
49
+ }
50
+ export interface TransferJobError {
51
+ code: string;
52
+ message: string;
53
+ /** The chunk that failed, when one did. */
54
+ chunk?: number;
55
+ }
56
+ /** One import or export, as stored. */
57
+ export interface TransferJob {
58
+ id: string;
59
+ /** The resource key. */
60
+ resource: string;
61
+ kind: TransferKind;
62
+ direction: 'import' | 'export';
63
+ format: TransferFormat;
64
+ status: TransferJobStatus;
65
+ orgId: string;
66
+ /** The site, for a host-scoped resource. */
67
+ hostId?: string;
68
+ createdBy: string;
69
+ createdAt: number;
70
+ updatedAt: number;
71
+ fileName?: string;
72
+ rowCount?: number;
73
+ chunkCount?: number;
74
+ /** Column → field id, as the person confirmed it. */
75
+ mapping?: Record<number, string>;
76
+ matchKeys?: string[];
77
+ policy?: TransferPolicy;
78
+ summary?: TransferPlanSummary;
79
+ acknowledged?: TransferWarningClass[];
80
+ cursor?: TransferJobCursor;
81
+ error?: TransferJobError;
82
+ appliedAt?: number;
83
+ undoneAt?: number;
84
+ }
85
+ /**
86
+ * The job moved to `to` at `now`. Entering `applied` stamps `appliedAt`;
87
+ * entering `undone` stamps `undoneAt`; leaving `failed` clears the error.
88
+ * Throws {@link TransferJobTransitionError} for a move the machine refuses.
89
+ */
90
+ export declare function transitionTransferJob(job: TransferJob, to: TransferJobStatus, now: number, patch?: Partial<Omit<TransferJob, 'id' | 'status'>>): TransferJob;
91
+ /** Whether an applied job may still be undone at `now`. */
92
+ export declare function transferUndoAvailable(job: Pick<TransferJob, 'status' | 'appliedAt'>, now: number): boolean;
93
+ /** When an applied job's undo closes, or `null` when it was never applied. */
94
+ export declare function transferUndoExpiresAt(job: Pick<TransferJob, 'appliedAt'>): number | null;
95
+ /** The ledger key that makes one row's write happen once: `<jobId>:<rowIndex>`. */
96
+ export declare function transferLedgerKey(jobId: string, rowIndex: number): string;
97
+ /** A ledger key read back, or `null` when it is not one. */
98
+ export declare function parseTransferLedgerKey(key: string): {
99
+ jobId: string;
100
+ rowIndex: number;
101
+ } | null;
102
+ /** One chunk's span of the file. */
103
+ export interface TransferChunkRange {
104
+ index: number;
105
+ /** First row index, inclusive. */
106
+ start: number;
107
+ /** Last row index, exclusive. */
108
+ end: number;
109
+ }
110
+ /** A file of `rowCount` rows cut into chunks of `size`. */
111
+ export declare function transferChunkRanges(rowCount: number, size?: number): TransferChunkRange[];
112
+ /** The chunk a row falls in. */
113
+ export declare function transferChunkOfRow(rowIndex: number, size?: number): number;
114
+ /** Items cut into batches of at most `max` (one batch per commit). */
115
+ export declare function transferWriteBatches<T>(items: readonly T[], max?: number): T[][];
116
+ /** What applying did to one row. */
117
+ export type TransferRowOutcome = 'created' | 'updated' | 'unchanged' | 'skipped' | 'failed';
118
+ export interface TransferRowResult {
119
+ row: number;
120
+ outcome: TransferRowOutcome;
121
+ recordId?: string;
122
+ reason?: TransferRowReason | string;
123
+ /** A sentence for a failure the plan did not foresee. */
124
+ message?: string;
125
+ }
126
+ /** One chunk's plan, as stored for the apply step. */
127
+ export interface TransferChunk<Row = unknown> {
128
+ jobId: string;
129
+ index: number;
130
+ start: number;
131
+ end: number;
132
+ rows: Row[];
133
+ }
134
+ /** One chunk's results, as stored. */
135
+ export interface TransferChunkResult {
136
+ jobId: string;
137
+ index: number;
138
+ results: TransferRowResult[];
139
+ completedAt: number;
140
+ }
141
+ /** Counts by outcome. */
142
+ export type TransferResultSummary = Record<TransferRowOutcome, number> & {
143
+ total: number;
144
+ };
145
+ /** The results counted. */
146
+ export declare function summarizeTransferResults(results: Iterable<TransferRowResult>): TransferResultSummary;
147
+ /** What undo needs to reverse one row. */
148
+ export interface TransferUndoEntry {
149
+ row: number;
150
+ recordId: string;
151
+ action: 'created' | 'updated';
152
+ /** For an update: each touched field's value before the import (`null` for none). */
153
+ previous?: Record<string, unknown>;
154
+ /** The values the import wrote, to tell a later edit from the import's own. */
155
+ written: Record<string, unknown>;
156
+ /** The modes the fields were written under, for the undo screen. */
157
+ modes?: Record<string, TransferFieldMode>;
158
+ }
159
+ /** One chunk's undo entries, as stored. */
160
+ export interface TransferUndoSnapshot {
161
+ jobId: string;
162
+ chunk: number;
163
+ entries: TransferUndoEntry[];
164
+ }
165
+ /** What undo does for one row. */
166
+ export type TransferUndoStep = {
167
+ action: 'delete';
168
+ recordId: string;
169
+ } | {
170
+ action: 'restore';
171
+ recordId: string;
172
+ values: Record<string, unknown>;
173
+ } | {
174
+ action: 'conflict';
175
+ recordId: string;
176
+ fields: string[];
177
+ values: Record<string, unknown>;
178
+ } | {
179
+ action: 'nothing';
180
+ recordId: string;
181
+ why: 'gone' | 'alreadyReverted';
182
+ };
183
+ /**
184
+ * The undo step for one entry against the record as it is now (`null` when
185
+ * it no longer exists). A field the import wrote that still holds what the
186
+ * import wrote is restored; a field edited since is a conflict, and the
187
+ * person chooses. A created record is deleted only when untouched since;
188
+ * otherwise deleting it is a conflict too.
189
+ */
190
+ export declare function planTransferUndo(entry: TransferUndoEntry, current: Readonly<Record<string, unknown>> | null): TransferUndoStep;
@@ -0,0 +1,229 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ /*==========================================
17
+ * TRANSFER JOBS — the shapes an import is stored and applied in.
18
+ *
19
+ * An import is a job that moves through fixed states:
20
+ *
21
+ * draft → analyzed → planned → applying → applied → undone
22
+ * ↑ ↓
23
+ * └──── failed (resume, or re-plan)
24
+ *
25
+ * - `draft` — the file is uploaded and nothing is read yet;
26
+ * - `analyzed` — headers matched and values collected; the person maps;
27
+ * - `planned` — the dry run is stored; the person reviews and acknowledges;
28
+ * - `applying` — chunks are being written; the cursor says how far;
29
+ * - `applied` — every chunk is written; undo is open for seven days;
30
+ * - `failed` — a chunk could not be written; resuming re-enters `applying`;
31
+ * - `undone` — the undo ran. Nothing follows it.
32
+ *
33
+ * Applying is chunked and idempotent: rows go in chunks of
34
+ * {@link TRANSFER_CHUNK_ROWS}, writes in batches of at most
35
+ * {@link TRANSFER_BATCH_WRITES_MAX}, and every row is recorded in a ledger
36
+ * under {@link transferLedgerKey} before its write is acknowledged, so a
37
+ * retried chunk never writes a row twice.
38
+ *
39
+ * ## Undo
40
+ *
41
+ * Before a row updates a record, the previous values of the fields it
42
+ * touches are snapshotted; a created record's id is kept. Undo restores
43
+ * the snapshot or deletes the created record — unless the record changed
44
+ * since the import, in which case the person is asked (keep what it holds
45
+ * now, or restore) rather than having a later edit silently thrown away.
46
+ *=========================================*/ import { _ as _extends } from "@swc/helpers/_/_extends";
47
+ import { transferValuesEqual } from "./policy.js";
48
+ /** Rows per chunk: a chunk is planned, applied and reported as one. */ export const TRANSFER_CHUNK_ROWS = 200;
49
+ /** The most writes in one batch (Firestore's limit). */ export const TRANSFER_BATCH_WRITES_MAX = 500;
50
+ /** How many records are written at once within a chunk. */ export const TRANSFER_WRITE_CONCURRENCY = 8;
51
+ /** How long an applied import may be undone. */ export const TRANSFER_UNDO_WINDOW_MS = 7 * 24 * 60 * 60 * 1000;
52
+ export const TRANSFER_JOB_STATUSES = [
53
+ 'draft',
54
+ 'analyzed',
55
+ 'planned',
56
+ 'applying',
57
+ 'applied',
58
+ 'failed',
59
+ 'undone'
60
+ ];
61
+ /**
62
+ * The moves each state allows. A state may be re-entered where the work is
63
+ * repeatable: re-analyzing, re-planning after a changed choice, and
64
+ * `applying` → `applying` as each chunk advances the cursor.
65
+ */ export const TRANSFER_JOB_TRANSITIONS = {
66
+ draft: [
67
+ 'analyzed',
68
+ 'failed'
69
+ ],
70
+ analyzed: [
71
+ 'analyzed',
72
+ 'planned',
73
+ 'failed'
74
+ ],
75
+ planned: [
76
+ 'analyzed',
77
+ 'planned',
78
+ 'applying',
79
+ 'failed'
80
+ ],
81
+ applying: [
82
+ 'applying',
83
+ 'applied',
84
+ 'failed'
85
+ ],
86
+ applied: [
87
+ 'undone'
88
+ ],
89
+ failed: [
90
+ 'applying',
91
+ 'planned',
92
+ 'analyzed'
93
+ ],
94
+ undone: []
95
+ };
96
+ /** Whether a job may move from `from` to `to`. */ export function canTransitionTransferJob(from, to) {
97
+ var _ref;
98
+ var _TRANSFER_JOB_TRANSITIONS_from;
99
+ return (_ref = (_TRANSFER_JOB_TRANSITIONS_from = TRANSFER_JOB_TRANSITIONS[from]) == null ? void 0 : _TRANSFER_JOB_TRANSITIONS_from.includes(to)) != null ? _ref : false;
100
+ }
101
+ /** A move the state machine does not allow. */ export class TransferJobTransitionError extends Error {
102
+ constructor(from, to){
103
+ super(`A transfer job cannot move from ${from} to ${to}.`), this.from = from, this.to = to;
104
+ this.name = 'TransferJobTransitionError';
105
+ }
106
+ }
107
+ /**
108
+ * The job moved to `to` at `now`. Entering `applied` stamps `appliedAt`;
109
+ * entering `undone` stamps `undoneAt`; leaving `failed` clears the error.
110
+ * Throws {@link TransferJobTransitionError} for a move the machine refuses.
111
+ */ export function transitionTransferJob(job, to, now, patch = {}) {
112
+ if (!canTransitionTransferJob(job.status, to)) throw new TransferJobTransitionError(job.status, to);
113
+ const next = _extends({}, job, patch, {
114
+ status: to,
115
+ updatedAt: now
116
+ });
117
+ if (to === 'applied') next.appliedAt = now;
118
+ if (to === 'undone') next.undoneAt = now;
119
+ if (job.status === 'failed' && to !== 'failed' && !patch.error) delete next.error;
120
+ return next;
121
+ }
122
+ /** Whether an applied job may still be undone at `now`. */ export function transferUndoAvailable(job, now) {
123
+ return job.status === 'applied' && job.appliedAt !== undefined && now - job.appliedAt <= TRANSFER_UNDO_WINDOW_MS;
124
+ }
125
+ /** When an applied job's undo closes, or `null` when it was never applied. */ export function transferUndoExpiresAt(job) {
126
+ return job.appliedAt === undefined ? null : job.appliedAt + TRANSFER_UNDO_WINDOW_MS;
127
+ }
128
+ /** The ledger key that makes one row's write happen once: `<jobId>:<rowIndex>`. */ export function transferLedgerKey(jobId, rowIndex) {
129
+ if (!jobId || jobId.includes(':') || jobId.includes('/')) throw new Error(`"${jobId}" is not a job id.`);
130
+ if (!Number.isInteger(rowIndex) || rowIndex < 0) throw new Error(`${rowIndex} is not a row index.`);
131
+ return `${jobId}:${rowIndex}`;
132
+ }
133
+ /** A ledger key read back, or `null` when it is not one. */ export function parseTransferLedgerKey(key) {
134
+ const match = /^([^:/]+):(\d+)$/.exec(String(key != null ? key : ''));
135
+ if (!match) return null;
136
+ return {
137
+ jobId: match[1],
138
+ rowIndex: Number(match[2])
139
+ };
140
+ }
141
+ /** A file of `rowCount` rows cut into chunks of `size`. */ export function transferChunkRanges(rowCount, size = TRANSFER_CHUNK_ROWS) {
142
+ const ranges = [];
143
+ if (!(size > 0)) return ranges;
144
+ for(let start = 0, index = 0; start < rowCount; start += size, index += 1){
145
+ ranges.push({
146
+ index,
147
+ start,
148
+ end: Math.min(rowCount, start + size)
149
+ });
150
+ }
151
+ return ranges;
152
+ }
153
+ /** The chunk a row falls in. */ export function transferChunkOfRow(rowIndex, size = TRANSFER_CHUNK_ROWS) {
154
+ return Math.floor(rowIndex / size);
155
+ }
156
+ /** Items cut into batches of at most `max` (one batch per commit). */ export function transferWriteBatches(items, max = TRANSFER_BATCH_WRITES_MAX) {
157
+ const batches = [];
158
+ for(let at = 0; at < items.length; at += max)batches.push(items.slice(at, at + max));
159
+ return batches;
160
+ }
161
+ /** The results counted. */ export function summarizeTransferResults(results) {
162
+ const summary = {
163
+ created: 0,
164
+ updated: 0,
165
+ unchanged: 0,
166
+ skipped: 0,
167
+ failed: 0,
168
+ total: 0
169
+ };
170
+ for (const result of results){
171
+ summary[result.outcome] += 1;
172
+ summary.total += 1;
173
+ }
174
+ return summary;
175
+ }
176
+ /**
177
+ * The undo step for one entry against the record as it is now (`null` when
178
+ * it no longer exists). A field the import wrote that still holds what the
179
+ * import wrote is restored; a field edited since is a conflict, and the
180
+ * person chooses. A created record is deleted only when untouched since;
181
+ * otherwise deleting it is a conflict too.
182
+ */ export function planTransferUndo(entry, current) {
183
+ var _entry_previous;
184
+ if (!current) return {
185
+ action: 'nothing',
186
+ recordId: entry.recordId,
187
+ why: 'gone'
188
+ };
189
+ const edited = Object.keys(entry.written).filter((fieldId)=>!transferValuesEqual(current[fieldId], entry.written[fieldId]));
190
+ if (entry.action === 'created') {
191
+ return edited.length ? {
192
+ action: 'conflict',
193
+ recordId: entry.recordId,
194
+ fields: edited,
195
+ values: {}
196
+ } : {
197
+ action: 'delete',
198
+ recordId: entry.recordId
199
+ };
200
+ }
201
+ const previous = (_entry_previous = entry.previous) != null ? _entry_previous : {};
202
+ const values = {};
203
+ const conflicts = [];
204
+ for (const fieldId of Object.keys(entry.written)){
205
+ var _previous_fieldId;
206
+ const was = (_previous_fieldId = previous[fieldId]) != null ? _previous_fieldId : null;
207
+ if (transferValuesEqual(current[fieldId], was)) continue;
208
+ if (edited.includes(fieldId)) conflicts.push(fieldId);
209
+ values[fieldId] = was;
210
+ }
211
+ if (conflicts.length) return {
212
+ action: 'conflict',
213
+ recordId: entry.recordId,
214
+ fields: conflicts,
215
+ values
216
+ };
217
+ if (!Object.keys(values).length) return {
218
+ action: 'nothing',
219
+ recordId: entry.recordId,
220
+ why: 'alreadyReverted'
221
+ };
222
+ return {
223
+ action: 'restore',
224
+ recordId: entry.recordId,
225
+ values
226
+ };
227
+ }
228
+
229
+ //# sourceMappingURL=job.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/data-transfer/job.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*==========================================\n * TRANSFER JOBS — the shapes an import is stored and applied in.\n *\n * An import is a job that moves through fixed states:\n *\n * draft → analyzed → planned → applying → applied → undone\n * ↑ ↓\n * └──── failed (resume, or re-plan)\n *\n * - `draft` — the file is uploaded and nothing is read yet;\n * - `analyzed` — headers matched and values collected; the person maps;\n * - `planned` — the dry run is stored; the person reviews and acknowledges;\n * - `applying` — chunks are being written; the cursor says how far;\n * - `applied` — every chunk is written; undo is open for seven days;\n * - `failed` — a chunk could not be written; resuming re-enters `applying`;\n * - `undone` — the undo ran. Nothing follows it.\n *\n * Applying is chunked and idempotent: rows go in chunks of\n * {@link TRANSFER_CHUNK_ROWS}, writes in batches of at most\n * {@link TRANSFER_BATCH_WRITES_MAX}, and every row is recorded in a ledger\n * under {@link transferLedgerKey} before its write is acknowledged, so a\n * retried chunk never writes a row twice.\n *\n * ## Undo\n *\n * Before a row updates a record, the previous values of the fields it\n * touches are snapshotted; a created record's id is kept. Undo restores\n * the snapshot or deletes the created record — unless the record changed\n * since the import, in which case the person is asked (keep what it holds\n * now, or restore) rather than having a later edit silently thrown away.\n *=========================================*/\n\nimport type { TransferFieldMode, TransferPolicy } from './policy'\nimport type { TransferPlanSummary, TransferRowReason, TransferWarningClass } from './plan'\nimport { transferValuesEqual } from './policy'\nimport type { TransferFormat, TransferKind } from './resource'\n\n/** Rows per chunk: a chunk is planned, applied and reported as one. */\nexport const TRANSFER_CHUNK_ROWS = 200\n\n/** The most writes in one batch (Firestore's limit). */\nexport const TRANSFER_BATCH_WRITES_MAX = 500\n\n/** How many records are written at once within a chunk. */\nexport const TRANSFER_WRITE_CONCURRENCY = 8\n\n/** How long an applied import may be undone. */\nexport const TRANSFER_UNDO_WINDOW_MS = 7 * 24 * 60 * 60 * 1000\n\nexport type TransferJobStatus = 'draft' | 'analyzed' | 'planned' | 'applying' | 'applied' | 'failed' | 'undone'\n\nexport const TRANSFER_JOB_STATUSES: readonly TransferJobStatus[] = [\n 'draft',\n 'analyzed',\n 'planned',\n 'applying',\n 'applied',\n 'failed',\n 'undone',\n]\n\n/**\n * The moves each state allows. A state may be re-entered where the work is\n * repeatable: re-analyzing, re-planning after a changed choice, and\n * `applying` → `applying` as each chunk advances the cursor.\n */\nexport const TRANSFER_JOB_TRANSITIONS: Readonly<Record<TransferJobStatus, readonly TransferJobStatus[]>> = {\n draft: ['analyzed', 'failed'],\n analyzed: ['analyzed', 'planned', 'failed'],\n planned: ['analyzed', 'planned', 'applying', 'failed'],\n applying: ['applying', 'applied', 'failed'],\n applied: ['undone'],\n failed: ['applying', 'planned', 'analyzed'],\n undone: [],\n}\n\n/** Whether a job may move from `from` to `to`. */\nexport function canTransitionTransferJob(from: TransferJobStatus, to: TransferJobStatus): boolean {\n return TRANSFER_JOB_TRANSITIONS[from]?.includes(to) ?? false\n}\n\n/** A move the state machine does not allow. */\nexport class TransferJobTransitionError extends Error {\n constructor(\n readonly from: TransferJobStatus,\n readonly to: TransferJobStatus,\n ) {\n super(`A transfer job cannot move from ${from} to ${to}.`)\n this.name = 'TransferJobTransitionError'\n }\n}\n\n/** Where applying has reached: the next chunk to write. */\nexport interface TransferJobCursor {\n chunk: number\n /** Rows written so far (all chunks before `chunk`). */\n rowsDone: number\n}\n\nexport interface TransferJobError {\n code: string\n message: string\n /** The chunk that failed, when one did. */\n chunk?: number\n}\n\n/** One import or export, as stored. */\nexport interface TransferJob {\n id: string\n /** The resource key. */\n resource: string\n kind: TransferKind\n direction: 'import' | 'export'\n format: TransferFormat\n status: TransferJobStatus\n orgId: string\n /** The site, for a host-scoped resource. */\n hostId?: string\n createdBy: string\n createdAt: number\n updatedAt: number\n fileName?: string\n rowCount?: number\n chunkCount?: number\n /** Column → field id, as the person confirmed it. */\n mapping?: Record<number, string>\n matchKeys?: string[]\n policy?: TransferPolicy\n summary?: TransferPlanSummary\n acknowledged?: TransferWarningClass[]\n cursor?: TransferJobCursor\n error?: TransferJobError\n appliedAt?: number\n undoneAt?: number\n}\n\n/**\n * The job moved to `to` at `now`. Entering `applied` stamps `appliedAt`;\n * entering `undone` stamps `undoneAt`; leaving `failed` clears the error.\n * Throws {@link TransferJobTransitionError} for a move the machine refuses.\n */\nexport function transitionTransferJob(\n job: TransferJob,\n to: TransferJobStatus,\n now: number,\n patch: Partial<Omit<TransferJob, 'id' | 'status'>> = {},\n): TransferJob {\n if (!canTransitionTransferJob(job.status, to)) throw new TransferJobTransitionError(job.status, to)\n const next: TransferJob = { ...job, ...patch, status: to, updatedAt: now }\n if (to === 'applied') next.appliedAt = now\n if (to === 'undone') next.undoneAt = now\n if (job.status === 'failed' && to !== 'failed' && !patch.error) delete next.error\n return next\n}\n\n/** Whether an applied job may still be undone at `now`. */\nexport function transferUndoAvailable(job: Pick<TransferJob, 'status' | 'appliedAt'>, now: number): boolean {\n return job.status === 'applied' && job.appliedAt !== undefined && now - job.appliedAt <= TRANSFER_UNDO_WINDOW_MS\n}\n\n/** When an applied job's undo closes, or `null` when it was never applied. */\nexport function transferUndoExpiresAt(job: Pick<TransferJob, 'appliedAt'>): number | null {\n return job.appliedAt === undefined ? null : job.appliedAt + TRANSFER_UNDO_WINDOW_MS\n}\n\n/** The ledger key that makes one row's write happen once: `<jobId>:<rowIndex>`. */\nexport function transferLedgerKey(jobId: string, rowIndex: number): string {\n if (!jobId || jobId.includes(':') || jobId.includes('/')) throw new Error(`\"${jobId}\" is not a job id.`)\n if (!Number.isInteger(rowIndex) || rowIndex < 0) throw new Error(`${rowIndex} is not a row index.`)\n return `${jobId}:${rowIndex}`\n}\n\n/** A ledger key read back, or `null` when it is not one. */\nexport function parseTransferLedgerKey(key: string): { jobId: string; rowIndex: number } | null {\n const match = /^([^:/]+):(\\d+)$/.exec(String(key ?? ''))\n if (!match) return null\n return { jobId: match[1] as string, rowIndex: Number(match[2]) }\n}\n\n/** One chunk's span of the file. */\nexport interface TransferChunkRange {\n index: number\n /** First row index, inclusive. */\n start: number\n /** Last row index, exclusive. */\n end: number\n}\n\n/** A file of `rowCount` rows cut into chunks of `size`. */\nexport function transferChunkRanges(rowCount: number, size = TRANSFER_CHUNK_ROWS): TransferChunkRange[] {\n const ranges: TransferChunkRange[] = []\n if (!(size > 0)) return ranges\n for (let start = 0, index = 0; start < rowCount; start += size, index += 1) {\n ranges.push({ index, start, end: Math.min(rowCount, start + size) })\n }\n return ranges\n}\n\n/** The chunk a row falls in. */\nexport function transferChunkOfRow(rowIndex: number, size = TRANSFER_CHUNK_ROWS): number {\n return Math.floor(rowIndex / size)\n}\n\n/** Items cut into batches of at most `max` (one batch per commit). */\nexport function transferWriteBatches<T>(items: readonly T[], max = TRANSFER_BATCH_WRITES_MAX): T[][] {\n const batches: T[][] = []\n for (let at = 0; at < items.length; at += max) batches.push(items.slice(at, at + max))\n return batches\n}\n\n/** What applying did to one row. */\nexport type TransferRowOutcome = 'created' | 'updated' | 'unchanged' | 'skipped' | 'failed'\n\nexport interface TransferRowResult {\n row: number\n outcome: TransferRowOutcome\n recordId?: string\n reason?: TransferRowReason | string\n /** A sentence for a failure the plan did not foresee. */\n message?: string\n}\n\n/** One chunk's plan, as stored for the apply step. */\nexport interface TransferChunk<Row = unknown> {\n jobId: string\n index: number\n start: number\n end: number\n rows: Row[]\n}\n\n/** One chunk's results, as stored. */\nexport interface TransferChunkResult {\n jobId: string\n index: number\n results: TransferRowResult[]\n completedAt: number\n}\n\n/** Counts by outcome. */\nexport type TransferResultSummary = Record<TransferRowOutcome, number> & { total: number }\n\n/** The results counted. */\nexport function summarizeTransferResults(results: Iterable<TransferRowResult>): TransferResultSummary {\n const summary: TransferResultSummary = { created: 0, updated: 0, unchanged: 0, skipped: 0, failed: 0, total: 0 }\n for (const result of results) {\n summary[result.outcome] += 1\n summary.total += 1\n }\n return summary\n}\n\n/** What undo needs to reverse one row. */\nexport interface TransferUndoEntry {\n row: number\n recordId: string\n action: 'created' | 'updated'\n /** For an update: each touched field's value before the import (`null` for none). */\n previous?: Record<string, unknown>\n /** The values the import wrote, to tell a later edit from the import's own. */\n written: Record<string, unknown>\n /** The modes the fields were written under, for the undo screen. */\n modes?: Record<string, TransferFieldMode>\n}\n\n/** One chunk's undo entries, as stored. */\nexport interface TransferUndoSnapshot {\n jobId: string\n chunk: number\n entries: TransferUndoEntry[]\n}\n\n/** What undo does for one row. */\nexport type TransferUndoStep =\n | { action: 'delete'; recordId: string }\n | { action: 'restore'; recordId: string; values: Record<string, unknown> }\n | { action: 'conflict'; recordId: string; fields: string[]; values: Record<string, unknown> }\n | { action: 'nothing'; recordId: string; why: 'gone' | 'alreadyReverted' }\n\n/**\n * The undo step for one entry against the record as it is now (`null` when\n * it no longer exists). A field the import wrote that still holds what the\n * import wrote is restored; a field edited since is a conflict, and the\n * person chooses. A created record is deleted only when untouched since;\n * otherwise deleting it is a conflict too.\n */\nexport function planTransferUndo(\n entry: TransferUndoEntry,\n current: Readonly<Record<string, unknown>> | null,\n): TransferUndoStep {\n if (!current) return { action: 'nothing', recordId: entry.recordId, why: 'gone' }\n const edited = Object.keys(entry.written).filter(\n (fieldId) => !transferValuesEqual(current[fieldId], entry.written[fieldId]),\n )\n if (entry.action === 'created') {\n return edited.length\n ? { action: 'conflict', recordId: entry.recordId, fields: edited, values: {} }\n : { action: 'delete', recordId: entry.recordId }\n }\n const previous = entry.previous ?? {}\n const values: Record<string, unknown> = {}\n const conflicts: string[] = []\n for (const fieldId of Object.keys(entry.written)) {\n const was = previous[fieldId] ?? null\n if (transferValuesEqual(current[fieldId], was)) continue\n if (edited.includes(fieldId)) conflicts.push(fieldId)\n values[fieldId] = was\n }\n if (conflicts.length) return { action: 'conflict', recordId: entry.recordId, fields: conflicts, values }\n if (!Object.keys(values).length) return { action: 'nothing', recordId: entry.recordId, why: 'alreadyReverted' }\n return { action: 'restore', recordId: entry.recordId, values }\n}\n"],"names":["transferValuesEqual","TRANSFER_CHUNK_ROWS","TRANSFER_BATCH_WRITES_MAX","TRANSFER_WRITE_CONCURRENCY","TRANSFER_UNDO_WINDOW_MS","TRANSFER_JOB_STATUSES","TRANSFER_JOB_TRANSITIONS","draft","analyzed","planned","applying","applied","failed","undone","canTransitionTransferJob","from","to","includes","TransferJobTransitionError","Error","name","transitionTransferJob","job","now","patch","status","next","updatedAt","appliedAt","undoneAt","error","transferUndoAvailable","undefined","transferUndoExpiresAt","transferLedgerKey","jobId","rowIndex","Number","isInteger","parseTransferLedgerKey","key","match","exec","String","transferChunkRanges","rowCount","size","ranges","start","index","push","end","Math","min","transferChunkOfRow","floor","transferWriteBatches","items","max","batches","at","length","slice","summarizeTransferResults","results","summary","created","updated","unchanged","skipped","total","result","outcome","planTransferUndo","entry","current","action","recordId","why","edited","Object","keys","written","filter","fieldId","fields","values","previous","conflicts","was"],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /** A record a lookup value may mean, offered when the value names none exactly. */
18
+ export interface TransferLookupSuggestion {
19
+ recordId: string;
20
+ label: string;
21
+ }
22
+ /** Marks a value the person chose to create; no Aglyn id contains a colon. */
23
+ export declare const TRANSFER_LOOKUP_NEW_PREFIX = "new:";
24
+ /** The value a row carries for a record the plugin creates from `name`. */
25
+ export declare function transferLookupNewValue(name: string): string;
26
+ /** The name behind a {@link transferLookupNewValue}, or `null` for any other value. */
27
+ export declare function transferLookupNewName(value: unknown): string | null;
28
+ /**
29
+ * The key a lookup value's choice is filed under: the text trimmed and
30
+ * lowercased, so "Acme" and "acme " are one decision.
31
+ */
32
+ export declare function transferLookupKey(value: unknown): string;
33
+ /**
34
+ * Whether a cell could be an Aglyn id, worth asking the target for by id
35
+ * before reading it as a name: one word of letters, digits, `-` and `_`.
36
+ */
37
+ export declare function mayBeTransferRecordId(value: unknown): boolean;
38
+ /**
39
+ * The closest candidates to `value`, best first: at most `limit`, each at
40
+ * least `threshold` similar (`textSimilarity`), one per record.
41
+ */
42
+ export declare function rankTransferLookupSuggestions(value: string, candidates: readonly TransferLookupSuggestion[], options?: {
43
+ limit?: number;
44
+ threshold?: number;
45
+ }): TransferLookupSuggestion[];
@@ -0,0 +1,71 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ /*==========================================
17
+ * LOOKUP COLUMNS — a cell that names another record (AGL-3541).
18
+ *
19
+ * A `lookup` field holds a record of another resource: a contact's company,
20
+ * a deal's contact, a task's owner. A file names that record the way a
21
+ * person would — "Acme", `acme.com`, `ana@acme.com` — or by its Aglyn ID,
22
+ * and the job engine resolves each distinct value through the target's own
23
+ * `lookup` hook. A value that names no record, or several, is the person's
24
+ * to decide: create the record, use a similar one, leave the field blank,
25
+ * or refuse the rows (`TransferLookupChoice`).
26
+ *
27
+ * What a row carries once resolved is the record's id. A value the person
28
+ * chose to CREATE is carried as {@link transferLookupNewValue} — the text
29
+ * behind a marker no Aglyn id can hold — so the plugin that writes the row
30
+ * creates the record (once, however many rows name it) on its own path.
31
+ *=========================================*/ import { textSimilarity } from "./similarity.js";
32
+ /** Marks a value the person chose to create; no Aglyn id contains a colon. */ export const TRANSFER_LOOKUP_NEW_PREFIX = 'new:';
33
+ /** The value a row carries for a record the plugin creates from `name`. */ export function transferLookupNewValue(name) {
34
+ return `${TRANSFER_LOOKUP_NEW_PREFIX}${name.trim()}`;
35
+ }
36
+ /** The name behind a {@link transferLookupNewValue}, or `null` for any other value. */ export function transferLookupNewName(value) {
37
+ if (typeof value !== 'string' || !value.startsWith(TRANSFER_LOOKUP_NEW_PREFIX)) return null;
38
+ const name = value.slice(TRANSFER_LOOKUP_NEW_PREFIX.length).trim();
39
+ return name || null;
40
+ }
41
+ /**
42
+ * The key a lookup value's choice is filed under: the text trimmed and
43
+ * lowercased, so "Acme" and "acme " are one decision.
44
+ */ export function transferLookupKey(value) {
45
+ return String(value != null ? value : '').trim().toLowerCase();
46
+ }
47
+ /**
48
+ * Whether a cell could be an Aglyn id, worth asking the target for by id
49
+ * before reading it as a name: one word of letters, digits, `-` and `_`.
50
+ */ export function mayBeTransferRecordId(value) {
51
+ return typeof value === 'string' && /^[A-Za-z0-9_-]{6,128}$/.test(value.trim());
52
+ }
53
+ /**
54
+ * The closest candidates to `value`, best first: at most `limit`, each at
55
+ * least `threshold` similar (`textSimilarity`), one per record.
56
+ */ export function rankTransferLookupSuggestions(value, candidates, options = {}) {
57
+ var _options_limit, _options_threshold;
58
+ const limit = (_options_limit = options.limit) != null ? _options_limit : 3;
59
+ const threshold = (_options_threshold = options.threshold) != null ? _options_threshold : 0.5;
60
+ const seen = new Set();
61
+ return candidates.map((candidate)=>({
62
+ candidate,
63
+ score: textSimilarity(value, candidate.label)
64
+ })).filter((entry)=>entry.score >= threshold).sort((a, b)=>b.score - a.score).filter((entry)=>{
65
+ if (seen.has(entry.candidate.recordId)) return false;
66
+ seen.add(entry.candidate.recordId);
67
+ return true;
68
+ }).slice(0, limit).map((entry)=>entry.candidate);
69
+ }
70
+
71
+ //# sourceMappingURL=lookup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/data-transfer/lookup.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*==========================================\n * LOOKUP COLUMNS — a cell that names another record (AGL-3541).\n *\n * A `lookup` field holds a record of another resource: a contact's company,\n * a deal's contact, a task's owner. A file names that record the way a\n * person would — \"Acme\", `acme.com`, `ana@acme.com` — or by its Aglyn ID,\n * and the job engine resolves each distinct value through the target's own\n * `lookup` hook. A value that names no record, or several, is the person's\n * to decide: create the record, use a similar one, leave the field blank,\n * or refuse the rows (`TransferLookupChoice`).\n *\n * What a row carries once resolved is the record's id. A value the person\n * chose to CREATE is carried as {@link transferLookupNewValue} — the text\n * behind a marker no Aglyn id can hold — so the plugin that writes the row\n * creates the record (once, however many rows name it) on its own path.\n *=========================================*/\n\nimport { textSimilarity } from './similarity'\n\n/** A record a lookup value may mean, offered when the value names none exactly. */\nexport interface TransferLookupSuggestion {\n recordId: string\n label: string\n}\n\n/** Marks a value the person chose to create; no Aglyn id contains a colon. */\nexport const TRANSFER_LOOKUP_NEW_PREFIX = 'new:'\n\n/** The value a row carries for a record the plugin creates from `name`. */\nexport function transferLookupNewValue(name: string): string {\n return `${TRANSFER_LOOKUP_NEW_PREFIX}${name.trim()}`\n}\n\n/** The name behind a {@link transferLookupNewValue}, or `null` for any other value. */\nexport function transferLookupNewName(value: unknown): string | null {\n if (typeof value !== 'string' || !value.startsWith(TRANSFER_LOOKUP_NEW_PREFIX)) return null\n const name = value.slice(TRANSFER_LOOKUP_NEW_PREFIX.length).trim()\n return name || null\n}\n\n/**\n * The key a lookup value's choice is filed under: the text trimmed and\n * lowercased, so \"Acme\" and \"acme \" are one decision.\n */\nexport function transferLookupKey(value: unknown): string {\n return String(value ?? '').trim().toLowerCase()\n}\n\n/**\n * Whether a cell could be an Aglyn id, worth asking the target for by id\n * before reading it as a name: one word of letters, digits, `-` and `_`.\n */\nexport function mayBeTransferRecordId(value: unknown): boolean {\n return typeof value === 'string' && /^[A-Za-z0-9_-]{6,128}$/.test(value.trim())\n}\n\n/**\n * The closest candidates to `value`, best first: at most `limit`, each at\n * least `threshold` similar (`textSimilarity`), one per record.\n */\nexport function rankTransferLookupSuggestions(\n value: string,\n candidates: readonly TransferLookupSuggestion[],\n options: { limit?: number; threshold?: number } = {},\n): TransferLookupSuggestion[] {\n const limit = options.limit ?? 3\n const threshold = options.threshold ?? 0.5\n const seen = new Set<string>()\n return candidates\n .map((candidate) => ({ candidate, score: textSimilarity(value, candidate.label) }))\n .filter((entry) => entry.score >= threshold)\n .sort((a, b) => b.score - a.score)\n .filter((entry) => {\n if (seen.has(entry.candidate.recordId)) return false\n seen.add(entry.candidate.recordId)\n return true\n })\n .slice(0, limit)\n .map((entry) => entry.candidate)\n}\n"],"names":["textSimilarity","TRANSFER_LOOKUP_NEW_PREFIX","transferLookupNewValue","name","trim","transferLookupNewName","value","startsWith","slice","length","transferLookupKey","String","toLowerCase","mayBeTransferRecordId","test","rankTransferLookupSuggestions","candidates","options","limit","threshold","seen","Set","map","candidate","score","label","filter","entry","sort","a","b","has","recordId","add"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;;;;;;;;;2CAe2C,GAE3C,SAASA,cAAc,QAAQ,kBAAc;AAQ7C,4EAA4E,GAC5E,OAAO,MAAMC,6BAA6B,OAAM;AAEhD,yEAAyE,GACzE,OAAO,SAASC,uBAAuBC,IAAY;IACjD,OAAO,GAAGF,6BAA6BE,KAAKC,IAAI,IAAI;AACtD;AAEA,qFAAqF,GACrF,OAAO,SAASC,sBAAsBC,KAAc;IAClD,IAAI,OAAOA,UAAU,YAAY,CAACA,MAAMC,UAAU,CAACN,6BAA6B,OAAO;IACvF,MAAME,OAAOG,MAAME,KAAK,CAACP,2BAA2BQ,MAAM,EAAEL,IAAI;IAChE,OAAOD,QAAQ;AACjB;AAEA;;;CAGC,GACD,OAAO,SAASO,kBAAkBJ,KAAc;IAC9C,OAAOK,OAAOL,gBAAAA,QAAS,IAAIF,IAAI,GAAGQ,WAAW;AAC/C;AAEA;;;CAGC,GACD,OAAO,SAASC,sBAAsBP,KAAc;IAClD,OAAO,OAAOA,UAAU,YAAY,yBAAyBQ,IAAI,CAACR,MAAMF,IAAI;AAC9E;AAEA;;;CAGC,GACD,OAAO,SAASW,8BACdT,KAAa,EACbU,UAA+C,EAC/CC,UAAkD,CAAC,CAAC;QAEtCA,gBACIA;IADlB,MAAMC,SAAQD,iBAAAA,QAAQC,KAAK,YAAbD,iBAAiB;IAC/B,MAAME,aAAYF,qBAAAA,QAAQE,SAAS,YAAjBF,qBAAqB;IACvC,MAAMG,OAAO,IAAIC;IACjB,OAAOL,WACJM,GAAG,CAAC,CAACC,YAAe,CAAA;YAAEA;YAAWC,OAAOxB,eAAeM,OAAOiB,UAAUE,KAAK;QAAE,CAAA,GAC/EC,MAAM,CAAC,CAACC,QAAUA,MAAMH,KAAK,IAAIL,WACjCS,IAAI,CAAC,CAACC,GAAGC,IAAMA,EAAEN,KAAK,GAAGK,EAAEL,KAAK,EAChCE,MAAM,CAAC,CAACC;QACP,IAAIP,KAAKW,GAAG,CAACJ,MAAMJ,SAAS,CAACS,QAAQ,GAAG,OAAO;QAC/CZ,KAAKa,GAAG,CAACN,MAAMJ,SAAS,CAACS,QAAQ;QACjC,OAAO;IACT,GACCxB,KAAK,CAAC,GAAGU,OACTI,GAAG,CAAC,CAACK,QAAUA,MAAMJ,SAAS;AACnC"}