@baasix/baasix 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.MD +85 -0
- package/README.md +526 -0
- package/assets/banner.jpg +0 -0
- package/assets/banner_small.jpg +0 -0
- package/assets/logo_icon.svg +20 -0
- package/assets/logo_icon_rounded.svg +20 -0
- package/dist/LICENSE.MD +85 -0
- package/dist/README.md +526 -0
- package/dist/app/404/index.html +1 -0
- package/dist/app/404.html +1 -0
- package/dist/app/_next/static/chunks/041e1f03-56ae8a902a7f2fe6.js +24 -0
- package/dist/app/_next/static/chunks/1117-05479929a8da73e3.js +1 -0
- package/dist/app/_next/static/chunks/1299.77cc7b7b76b75cba.js +1 -0
- package/dist/app/_next/static/chunks/1303-35a96e9c9cdeab9d.js +1 -0
- package/dist/app/_next/static/chunks/1509-56ac00cdaaecdf53.js +1 -0
- package/dist/app/_next/static/chunks/1668-e3eabd0f6753c780.js +1 -0
- package/dist/app/_next/static/chunks/1783-d9fb550fd324300c.js +1 -0
- package/dist/app/_next/static/chunks/2117-29b5fa47421595ad.js +2 -0
- package/dist/app/_next/static/chunks/2344.35b46d2179a765b5.js +1 -0
- package/dist/app/_next/static/chunks/257.990da16794a31292.js +1 -0
- package/dist/app/_next/static/chunks/2676-73b0ee7c80073a84.js +1 -0
- package/dist/app/_next/static/chunks/3563-b8842744384391fe.js +1 -0
- package/dist/app/_next/static/chunks/363642f4-933b579ed3c85f60.js +1 -0
- package/dist/app/_next/static/chunks/3817-e20c8f0a0810fc95.js +1 -0
- package/dist/app/_next/static/chunks/3834.84944e390d902509.js +2 -0
- package/dist/app/_next/static/chunks/4043-3a30c8a75896f241.js +1 -0
- package/dist/app/_next/static/chunks/4225-14090c7c0cd9dec6.js +1 -0
- package/dist/app/_next/static/chunks/4438-c9a12ca15b6e9160.js +1 -0
- package/dist/app/_next/static/chunks/4458-679fd0c6884f456a.js +1 -0
- package/dist/app/_next/static/chunks/4475-8bdfbd536fba8c48.js +1 -0
- package/dist/app/_next/static/chunks/4883-8a924721bb21b3b0.js +1 -0
- package/dist/app/_next/static/chunks/489-683ab07188f9df2b.js +1 -0
- package/dist/app/_next/static/chunks/4952-1b97320cf61f3f21.js +1 -0
- package/dist/app/_next/static/chunks/5094-8d53e403235d4ca6.js +1 -0
- package/dist/app/_next/static/chunks/5101-3a146e0625747ad1.js +1 -0
- package/dist/app/_next/static/chunks/54a60aa6-d9747982e0a81f58.js +79 -0
- package/dist/app/_next/static/chunks/5650-f096291df402bfc2.js +1 -0
- package/dist/app/_next/static/chunks/600-539045311240f579.js +1 -0
- package/dist/app/_next/static/chunks/6170-803b82e19d3ade6d.js +89 -0
- package/dist/app/_next/static/chunks/6241-30d7169d1010e5a4.js +1 -0
- package/dist/app/_next/static/chunks/6530-a91e10cffa4200c4.js +1 -0
- package/dist/app/_next/static/chunks/6547-4bbbdb5c399aef1e.js +1 -0
- package/dist/app/_next/static/chunks/6712-781937c53a2c49da.js +1 -0
- package/dist/app/_next/static/chunks/6fcbdc68-90be1a5480b8d353.js +1 -0
- package/dist/app/_next/static/chunks/70e0d97a-aeaf0cdc26ba1a58.js +1 -0
- package/dist/app/_next/static/chunks/7214-5154a89d08d24dde.js +1 -0
- package/dist/app/_next/static/chunks/7324-b53229c59a640880.js +10 -0
- package/dist/app/_next/static/chunks/7636-66424f0b51d350e9.js +1 -0
- package/dist/app/_next/static/chunks/7874-39a3f2541165a675.js +1 -0
- package/dist/app/_next/static/chunks/7982-9da12b83f11e3f5f.js +1 -0
- package/dist/app/_next/static/chunks/8213a2eb-da25a3b3c5521b2b.js +1 -0
- package/dist/app/_next/static/chunks/8473-6598318371eca31b.js +1 -0
- package/dist/app/_next/static/chunks/8640fa6b-72e43370f68e5587.js +1 -0
- package/dist/app/_next/static/chunks/9090-3ef676f29c95f1c7.js +1 -0
- package/dist/app/_next/static/chunks/9124-a02f9e209e6e3cce.js +1 -0
- package/dist/app/_next/static/chunks/926-156f32067d111d6b.js +1 -0
- package/dist/app/_next/static/chunks/9487-b17481605e513b83.js +1 -0
- package/dist/app/_next/static/chunks/9599-a7e572bb88c3392b.js +1 -0
- package/dist/app/_next/static/chunks/9881-419697138376e755.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/all-activity/page-8917930b4d663405.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/email-log/page-b27a6ee32782d7df.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/notifications/page-b7eda523ede2702c.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/page-1cfa62d1caedaed0.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/sessions/page-3e21e20db90aeff7.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/workflow-executions/page-27bcc26b747fb29b.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/activity-log/workflow-logs/page-9f9e9e952aef436e.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/change-password/page-8d61aa499eabb127.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/dashboard/page-1ceeac9e72997a8a.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/data-browser/page-8cda2b57759dd670.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/file-manager/page-8c6f1b1da66ad7e4.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/layout-f70d225b2759c998.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/settings/migrations/page-aacec8f7cfb40ab2.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/settings/permissions/page-828110cfcde429c6.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/settings/project/page-420e794bb76bd204.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/settings/roles/page-9001d02b28f70708.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/settings/schema/page-899574f35091dd58.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/settings/tasks/page-ad7ab3e27c83f44f.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/settings/templates/edit/page-bd83414cb8c4cb04.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/settings/templates/page-3181447f8772b1d3.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/settings/tenants/page-ef9bfbacef5a1d73.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/users/invites/page-480306b7b2bbac7e.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/users/list/page-74da51254c2606b3.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/users/page-e99c6f0b915001b2.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/users/preferences/page-1a935630ce8f2b12.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/users/user-roles/page-901dfb8ea1f39ca8.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/workflows/detail/page-9a6b839aea688ca4.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/workflows/edit/page-11774efbc2fecae2.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/workflows/execution/page-8ec1aea90412c03d.js +1 -0
- package/dist/app/_next/static/chunks/app/(authenticated)/workflows/page-88bc5b36ccb0a1f7.js +1 -0
- package/dist/app/_next/static/chunks/app/(public)/forgot-password/page-ed263fd46ef81c20.js +1 -0
- package/dist/app/_next/static/chunks/app/(public)/layout-f538977545844af8.js +1 -0
- package/dist/app/_next/static/chunks/app/(public)/login/page-c0a10b137f346096.js +1 -0
- package/dist/app/_next/static/chunks/app/(public)/register/page-4cb7644893efd9b3.js +1 -0
- package/dist/app/_next/static/chunks/app/_not-found/page-653f8815b78256cc.js +1 -0
- package/dist/app/_next/static/chunks/app/layout-591ca7a3e16528a1.js +1 -0
- package/dist/app/_next/static/chunks/app/page-dd19d124b5fa2577.js +1 -0
- package/dist/app/_next/static/chunks/c37d3baf.c2ff165f5b02c692.js +1 -0
- package/dist/app/_next/static/chunks/d0deef33.0379166a4ec23470.js +1 -0
- package/dist/app/_next/static/chunks/fd9d1056-54169f07cd680d6c.js +1 -0
- package/dist/app/_next/static/chunks/framework-8e0e0f4a6b83a956.js +1 -0
- package/dist/app/_next/static/chunks/main-324e91f5a430cddf.js +1 -0
- package/dist/app/_next/static/chunks/main-app-55bcae20c77aaf0e.js +1 -0
- package/dist/app/_next/static/chunks/pages/_app-3c9ca398d360b709.js +1 -0
- package/dist/app/_next/static/chunks/pages/_error-cf5ca766ac8f493f.js +1 -0
- package/dist/app/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- package/dist/app/_next/static/chunks/webpack-2c306566f7ee1b63.js +1 -0
- package/dist/app/_next/static/css/6c4002bae4e236b2.css +3 -0
- package/dist/app/_next/static/css/a275cc2b185e04f8.css +1 -0
- package/dist/app/_next/static/eCWhKA8XHqmB1zgFcEtN2/_buildManifest.js +1 -0
- package/dist/app/_next/static/eCWhKA8XHqmB1zgFcEtN2/_ssgManifest.js +1 -0
- package/dist/app/activity-log/all-activity/index.html +1 -0
- package/dist/app/activity-log/all-activity/index.txt +14 -0
- package/dist/app/activity-log/email-log/index.html +1 -0
- package/dist/app/activity-log/email-log/index.txt +14 -0
- package/dist/app/activity-log/index.html +1 -0
- package/dist/app/activity-log/index.txt +14 -0
- package/dist/app/activity-log/notifications/index.html +1 -0
- package/dist/app/activity-log/notifications/index.txt +14 -0
- package/dist/app/activity-log/sessions/index.html +1 -0
- package/dist/app/activity-log/sessions/index.txt +14 -0
- package/dist/app/activity-log/workflow-executions/index.html +1 -0
- package/dist/app/activity-log/workflow-executions/index.txt +14 -0
- package/dist/app/activity-log/workflow-logs/index.html +1 -0
- package/dist/app/activity-log/workflow-logs/index.txt +14 -0
- package/dist/app/change-password/index.html +1 -0
- package/dist/app/change-password/index.txt +14 -0
- package/dist/app/dashboard/index.html +1 -0
- package/dist/app/dashboard/index.txt +14 -0
- package/dist/app/data-browser/index.html +1 -0
- package/dist/app/data-browser/index.txt +14 -0
- package/dist/app/file-manager/index.html +1 -0
- package/dist/app/file-manager/index.txt +14 -0
- package/dist/app/forgot-password/index.html +1 -0
- package/dist/app/forgot-password/index.txt +13 -0
- package/dist/app/index.html +1 -0
- package/dist/app/index.txt +9 -0
- package/dist/app/login/index.html +1 -0
- package/dist/app/login/index.txt +13 -0
- package/dist/app/logo-dark.png +0 -0
- package/dist/app/logo-icon.svg +81 -0
- package/dist/app/logo-light.png +0 -0
- package/dist/app/register/index.html +1 -0
- package/dist/app/register/index.txt +13 -0
- package/dist/app/settings/migrations/index.html +1 -0
- package/dist/app/settings/migrations/index.txt +14 -0
- package/dist/app/settings/permissions/index.html +1 -0
- package/dist/app/settings/permissions/index.txt +14 -0
- package/dist/app/settings/project/index.html +1 -0
- package/dist/app/settings/project/index.txt +14 -0
- package/dist/app/settings/roles/index.html +1 -0
- package/dist/app/settings/roles/index.txt +14 -0
- package/dist/app/settings/schema/index.html +1 -0
- package/dist/app/settings/schema/index.txt +14 -0
- package/dist/app/settings/tasks/index.html +1 -0
- package/dist/app/settings/tasks/index.txt +14 -0
- package/dist/app/settings/templates/edit/index.html +1 -0
- package/dist/app/settings/templates/edit/index.txt +14 -0
- package/dist/app/settings/templates/index.html +1 -0
- package/dist/app/settings/templates/index.txt +14 -0
- package/dist/app/settings/tenants/index.html +1 -0
- package/dist/app/settings/tenants/index.txt +14 -0
- package/dist/app/users/index.html +1 -0
- package/dist/app/users/index.txt +14 -0
- package/dist/app/users/invites/index.html +1 -0
- package/dist/app/users/invites/index.txt +14 -0
- package/dist/app/users/list/index.html +1 -0
- package/dist/app/users/list/index.txt +14 -0
- package/dist/app/users/preferences/index.html +1 -0
- package/dist/app/users/preferences/index.txt +14 -0
- package/dist/app/users/user-roles/index.html +1 -0
- package/dist/app/users/user-roles/index.txt +14 -0
- package/dist/app/workflows/detail/index.html +1 -0
- package/dist/app/workflows/detail/index.txt +14 -0
- package/dist/app/workflows/edit/index.html +1 -0
- package/dist/app/workflows/edit/index.txt +14 -0
- package/dist/app/workflows/execution/index.html +1 -0
- package/dist/app/workflows/execution/index.txt +14 -0
- package/dist/app/workflows/index.html +1 -0
- package/dist/app/workflows/index.txt +14 -0
- package/dist/app.d.ts +36 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +546 -0
- package/dist/app.js.map +1 -0
- package/dist/auth/adapters/baasix-adapter.d.ts +12 -0
- package/dist/auth/adapters/baasix-adapter.d.ts.map +1 -0
- package/dist/auth/adapters/baasix-adapter.js +318 -0
- package/dist/auth/adapters/baasix-adapter.js.map +1 -0
- package/dist/auth/adapters/index.d.ts +6 -0
- package/dist/auth/adapters/index.d.ts.map +1 -0
- package/dist/auth/adapters/index.js +5 -0
- package/dist/auth/adapters/index.js.map +1 -0
- package/dist/auth/core.d.ts +73 -0
- package/dist/auth/core.d.ts.map +1 -0
- package/dist/auth/core.js +528 -0
- package/dist/auth/core.js.map +1 -0
- package/dist/auth/index.d.ts +56 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +58 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/oauth2/index.d.ts +5 -0
- package/dist/auth/oauth2/index.d.ts.map +1 -0
- package/dist/auth/oauth2/index.js +5 -0
- package/dist/auth/oauth2/index.js.map +1 -0
- package/dist/auth/oauth2/utils.d.ts +90 -0
- package/dist/auth/oauth2/utils.d.ts.map +1 -0
- package/dist/auth/oauth2/utils.js +167 -0
- package/dist/auth/oauth2/utils.js.map +1 -0
- package/dist/auth/providers/apple.d.ts +28 -0
- package/dist/auth/providers/apple.d.ts.map +1 -0
- package/dist/auth/providers/apple.js +192 -0
- package/dist/auth/providers/apple.js.map +1 -0
- package/dist/auth/providers/credential.d.ts +87 -0
- package/dist/auth/providers/credential.d.ts.map +1 -0
- package/dist/auth/providers/credential.js +162 -0
- package/dist/auth/providers/credential.js.map +1 -0
- package/dist/auth/providers/facebook.d.ts +26 -0
- package/dist/auth/providers/facebook.d.ts.map +1 -0
- package/dist/auth/providers/facebook.js +112 -0
- package/dist/auth/providers/facebook.js.map +1 -0
- package/dist/auth/providers/github.d.ts +29 -0
- package/dist/auth/providers/github.d.ts.map +1 -0
- package/dist/auth/providers/github.js +144 -0
- package/dist/auth/providers/github.js.map +1 -0
- package/dist/auth/providers/google.d.ts +32 -0
- package/dist/auth/providers/google.d.ts.map +1 -0
- package/dist/auth/providers/google.js +145 -0
- package/dist/auth/providers/google.js.map +1 -0
- package/dist/auth/providers/index.d.ts +22 -0
- package/dist/auth/providers/index.d.ts.map +1 -0
- package/dist/auth/providers/index.js +17 -0
- package/dist/auth/providers/index.js.map +1 -0
- package/dist/auth/routes.d.ts +63 -0
- package/dist/auth/routes.d.ts.map +1 -0
- package/dist/auth/routes.js +827 -0
- package/dist/auth/routes.js.map +1 -0
- package/dist/auth/services/index.d.ts +10 -0
- package/dist/auth/services/index.d.ts.map +1 -0
- package/dist/auth/services/index.js +7 -0
- package/dist/auth/services/index.js.map +1 -0
- package/dist/auth/services/session.d.ts +81 -0
- package/dist/auth/services/session.d.ts.map +1 -0
- package/dist/auth/services/session.js +186 -0
- package/dist/auth/services/session.js.map +1 -0
- package/dist/auth/services/token.d.ts +41 -0
- package/dist/auth/services/token.d.ts.map +1 -0
- package/dist/auth/services/token.js +44 -0
- package/dist/auth/services/token.js.map +1 -0
- package/dist/auth/services/verification.d.ts +77 -0
- package/dist/auth/services/verification.d.ts.map +1 -0
- package/dist/auth/services/verification.js +143 -0
- package/dist/auth/services/verification.js.map +1 -0
- package/dist/auth/types.d.ts +318 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +6 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/customTypes/arrays.d.ts +200 -0
- package/dist/customTypes/arrays.d.ts.map +1 -0
- package/dist/customTypes/arrays.js +309 -0
- package/dist/customTypes/arrays.js.map +1 -0
- package/dist/customTypes/index.d.ts +8 -0
- package/dist/customTypes/index.d.ts.map +1 -0
- package/dist/customTypes/index.js +11 -0
- package/dist/customTypes/index.js.map +1 -0
- package/dist/customTypes/postgis.d.ts +146 -0
- package/dist/customTypes/postgis.d.ts.map +1 -0
- package/dist/customTypes/postgis.js +315 -0
- package/dist/customTypes/postgis.js.map +1 -0
- package/dist/customTypes/ranges.d.ts +128 -0
- package/dist/customTypes/ranges.d.ts.map +1 -0
- package/dist/customTypes/ranges.js +257 -0
- package/dist/customTypes/ranges.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/migrations/0.1.0-alpha.0_initial_setup.d.ts +29 -0
- package/dist/migrations/0.1.0-alpha.0_initial_setup.d.ts.map +1 -0
- package/dist/migrations/0.1.0-alpha.0_initial_setup.js +72 -0
- package/dist/migrations/0.1.0-alpha.0_initial_setup.js.map +1 -0
- package/dist/migrations/_example_migration.d.ts +31 -0
- package/dist/migrations/_example_migration.d.ts.map +1 -0
- package/dist/migrations/_example_migration.js +75 -0
- package/dist/migrations/_example_migration.js.map +1 -0
- package/dist/plugins/definePlugin.d.ts +49 -0
- package/dist/plugins/definePlugin.d.ts.map +1 -0
- package/dist/plugins/definePlugin.js +131 -0
- package/dist/plugins/definePlugin.js.map +1 -0
- package/dist/plugins/softDelete.d.ts +179 -0
- package/dist/plugins/softDelete.d.ts.map +1 -0
- package/dist/plugins/softDelete.js +235 -0
- package/dist/plugins/softDelete.js.map +1 -0
- package/dist/routes/auth.route.d.ts +14 -0
- package/dist/routes/auth.route.d.ts.map +1 -0
- package/dist/routes/auth.route.js +421 -0
- package/dist/routes/auth.route.js.map +1 -0
- package/dist/routes/file.route.d.ts +7 -0
- package/dist/routes/file.route.d.ts.map +1 -0
- package/dist/routes/file.route.js +274 -0
- package/dist/routes/file.route.js.map +1 -0
- package/dist/routes/items.route.d.ts +7 -0
- package/dist/routes/items.route.d.ts.map +1 -0
- package/dist/routes/items.route.js +369 -0
- package/dist/routes/items.route.js.map +1 -0
- package/dist/routes/migration.route.d.ts +7 -0
- package/dist/routes/migration.route.d.ts.map +1 -0
- package/dist/routes/migration.route.js +225 -0
- package/dist/routes/migration.route.js.map +1 -0
- package/dist/routes/notification.route.d.ts +7 -0
- package/dist/routes/notification.route.d.ts.map +1 -0
- package/dist/routes/notification.route.js +124 -0
- package/dist/routes/notification.route.js.map +1 -0
- package/dist/routes/openapi.route.d.ts +7 -0
- package/dist/routes/openapi.route.d.ts.map +1 -0
- package/dist/routes/openapi.route.js +2169 -0
- package/dist/routes/openapi.route.js.map +1 -0
- package/dist/routes/permission.route.d.ts +7 -0
- package/dist/routes/permission.route.d.ts.map +1 -0
- package/dist/routes/permission.route.js +158 -0
- package/dist/routes/permission.route.js.map +1 -0
- package/dist/routes/realtime.route.d.ts +21 -0
- package/dist/routes/realtime.route.d.ts.map +1 -0
- package/dist/routes/realtime.route.js +243 -0
- package/dist/routes/realtime.route.js.map +1 -0
- package/dist/routes/reports.route.d.ts +7 -0
- package/dist/routes/reports.route.d.ts.map +1 -0
- package/dist/routes/reports.route.js +95 -0
- package/dist/routes/reports.route.js.map +1 -0
- package/dist/routes/schema.route.d.ts +7 -0
- package/dist/routes/schema.route.d.ts.map +1 -0
- package/dist/routes/schema.route.js +1780 -0
- package/dist/routes/schema.route.js.map +1 -0
- package/dist/routes/settings.route.d.ts +7 -0
- package/dist/routes/settings.route.d.ts.map +1 -0
- package/dist/routes/settings.route.js +154 -0
- package/dist/routes/settings.route.js.map +1 -0
- package/dist/routes/templates.route.d.ts +7 -0
- package/dist/routes/templates.route.d.ts.map +1 -0
- package/dist/routes/templates.route.js +91 -0
- package/dist/routes/templates.route.js.map +1 -0
- package/dist/routes/utils.route.d.ts +7 -0
- package/dist/routes/utils.route.d.ts.map +1 -0
- package/dist/routes/utils.route.js +33 -0
- package/dist/routes/utils.route.js.map +1 -0
- package/dist/routes/workflow.route.d.ts +7 -0
- package/dist/routes/workflow.route.d.ts.map +1 -0
- package/dist/routes/workflow.route.js +787 -0
- package/dist/routes/workflow.route.js.map +1 -0
- package/dist/services/AssetsService.d.ts +39 -0
- package/dist/services/AssetsService.d.ts.map +1 -0
- package/dist/services/AssetsService.js +255 -0
- package/dist/services/AssetsService.js.map +1 -0
- package/dist/services/CacheService.d.ts +169 -0
- package/dist/services/CacheService.d.ts.map +1 -0
- package/dist/services/CacheService.js +722 -0
- package/dist/services/CacheService.js.map +1 -0
- package/dist/services/FilesService.d.ts +30 -0
- package/dist/services/FilesService.d.ts.map +1 -0
- package/dist/services/FilesService.js +268 -0
- package/dist/services/FilesService.js.map +1 -0
- package/dist/services/HooksManager.d.ts +38 -0
- package/dist/services/HooksManager.d.ts.map +1 -0
- package/dist/services/HooksManager.js +165 -0
- package/dist/services/HooksManager.js.map +1 -0
- package/dist/services/ItemsService.d.ts +273 -0
- package/dist/services/ItemsService.d.ts.map +1 -0
- package/dist/services/ItemsService.js +2458 -0
- package/dist/services/ItemsService.js.map +1 -0
- package/dist/services/MailService.d.ts +76 -0
- package/dist/services/MailService.d.ts.map +1 -0
- package/dist/services/MailService.js +585 -0
- package/dist/services/MailService.js.map +1 -0
- package/dist/services/MigrationService.d.ts +243 -0
- package/dist/services/MigrationService.d.ts.map +1 -0
- package/dist/services/MigrationService.js +914 -0
- package/dist/services/MigrationService.js.map +1 -0
- package/dist/services/NotificationService.d.ts +35 -0
- package/dist/services/NotificationService.d.ts.map +1 -0
- package/dist/services/NotificationService.js +159 -0
- package/dist/services/NotificationService.js.map +1 -0
- package/dist/services/PermissionService.d.ts +128 -0
- package/dist/services/PermissionService.d.ts.map +1 -0
- package/dist/services/PermissionService.js +373 -0
- package/dist/services/PermissionService.js.map +1 -0
- package/dist/services/PluginManager.d.ts +138 -0
- package/dist/services/PluginManager.d.ts.map +1 -0
- package/dist/services/PluginManager.js +463 -0
- package/dist/services/PluginManager.js.map +1 -0
- package/dist/services/RealtimeService.d.ts +209 -0
- package/dist/services/RealtimeService.d.ts.map +1 -0
- package/dist/services/RealtimeService.js +978 -0
- package/dist/services/RealtimeService.js.map +1 -0
- package/dist/services/ReportService.d.ts +13 -0
- package/dist/services/ReportService.d.ts.map +1 -0
- package/dist/services/ReportService.js +91 -0
- package/dist/services/ReportService.js.map +1 -0
- package/dist/services/SettingsService.d.ts +60 -0
- package/dist/services/SettingsService.d.ts.map +1 -0
- package/dist/services/SettingsService.js +474 -0
- package/dist/services/SettingsService.js.map +1 -0
- package/dist/services/SocketService.d.ts +129 -0
- package/dist/services/SocketService.d.ts.map +1 -0
- package/dist/services/SocketService.js +600 -0
- package/dist/services/SocketService.js.map +1 -0
- package/dist/services/StatsService.d.ts +10 -0
- package/dist/services/StatsService.d.ts.map +1 -0
- package/dist/services/StatsService.js +40 -0
- package/dist/services/StatsService.js.map +1 -0
- package/dist/services/StorageService.d.ts +20 -0
- package/dist/services/StorageService.d.ts.map +1 -0
- package/dist/services/StorageService.js +164 -0
- package/dist/services/StorageService.js.map +1 -0
- package/dist/services/TasksService.d.ts +74 -0
- package/dist/services/TasksService.d.ts.map +1 -0
- package/dist/services/TasksService.js +404 -0
- package/dist/services/TasksService.js.map +1 -0
- package/dist/services/WorkflowService.d.ts +305 -0
- package/dist/services/WorkflowService.d.ts.map +1 -0
- package/dist/services/WorkflowService.js +1811 -0
- package/dist/services/WorkflowService.js.map +1 -0
- package/dist/templates/logo/logo.png +0 -0
- package/dist/templates/mails/default.liquid +23 -0
- package/dist/types/aggregation.d.ts +40 -0
- package/dist/types/aggregation.d.ts.map +1 -0
- package/dist/types/aggregation.js +6 -0
- package/dist/types/aggregation.js.map +1 -0
- package/dist/types/assets.d.ts +32 -0
- package/dist/types/assets.d.ts.map +1 -0
- package/dist/types/assets.js +6 -0
- package/dist/types/assets.js.map +1 -0
- package/dist/types/auth.d.ts +50 -0
- package/dist/types/auth.d.ts.map +1 -0
- package/dist/types/auth.js +6 -0
- package/dist/types/auth.js.map +1 -0
- package/dist/types/cache.d.ts +47 -0
- package/dist/types/cache.d.ts.map +1 -0
- package/dist/types/cache.js +6 -0
- package/dist/types/cache.js.map +1 -0
- package/dist/types/database.d.ts +16 -0
- package/dist/types/database.d.ts.map +1 -0
- package/dist/types/database.js +6 -0
- package/dist/types/database.js.map +1 -0
- package/dist/types/fields.d.ts +71 -0
- package/dist/types/fields.d.ts.map +1 -0
- package/dist/types/fields.js +6 -0
- package/dist/types/fields.js.map +1 -0
- package/dist/types/files.d.ts +33 -0
- package/dist/types/files.d.ts.map +1 -0
- package/dist/types/files.js +6 -0
- package/dist/types/files.js.map +1 -0
- package/dist/types/hooks.d.ts +29 -0
- package/dist/types/hooks.d.ts.map +1 -0
- package/dist/types/hooks.js +6 -0
- package/dist/types/hooks.js.map +1 -0
- package/dist/types/import-export.d.ts +62 -0
- package/dist/types/import-export.d.ts.map +1 -0
- package/dist/types/import-export.js +6 -0
- package/dist/types/import-export.js.map +1 -0
- package/dist/types/index.d.ts +31 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +58 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/mail.d.ts +34 -0
- package/dist/types/mail.d.ts.map +1 -0
- package/dist/types/mail.js +6 -0
- package/dist/types/mail.js.map +1 -0
- package/dist/types/notifications.d.ts +16 -0
- package/dist/types/notifications.d.ts.map +1 -0
- package/dist/types/notifications.js +6 -0
- package/dist/types/notifications.js.map +1 -0
- package/dist/types/plugin.d.ts +351 -0
- package/dist/types/plugin.d.ts.map +1 -0
- package/dist/types/plugin.js +8 -0
- package/dist/types/plugin.js.map +1 -0
- package/dist/types/query.d.ts +71 -0
- package/dist/types/query.d.ts.map +1 -0
- package/dist/types/query.js +6 -0
- package/dist/types/query.js.map +1 -0
- package/dist/types/relations.d.ts +111 -0
- package/dist/types/relations.d.ts.map +1 -0
- package/dist/types/relations.js +6 -0
- package/dist/types/relations.js.map +1 -0
- package/dist/types/reports.d.ts +17 -0
- package/dist/types/reports.d.ts.map +1 -0
- package/dist/types/reports.js +6 -0
- package/dist/types/reports.js.map +1 -0
- package/dist/types/schema.d.ts +26 -0
- package/dist/types/schema.d.ts.map +1 -0
- package/dist/types/schema.js +6 -0
- package/dist/types/schema.js.map +1 -0
- package/dist/types/seed.d.ts +27 -0
- package/dist/types/seed.d.ts.map +1 -0
- package/dist/types/seed.js +6 -0
- package/dist/types/seed.js.map +1 -0
- package/dist/types/services.d.ts +68 -0
- package/dist/types/services.d.ts.map +1 -0
- package/dist/types/services.js +6 -0
- package/dist/types/services.js.map +1 -0
- package/dist/types/settings.d.ts +36 -0
- package/dist/types/settings.d.ts.map +1 -0
- package/dist/types/settings.js +6 -0
- package/dist/types/settings.js.map +1 -0
- package/dist/types/sockets.d.ts +26 -0
- package/dist/types/sockets.d.ts.map +1 -0
- package/dist/types/sockets.js +6 -0
- package/dist/types/sockets.js.map +1 -0
- package/dist/types/sort.d.ts +25 -0
- package/dist/types/sort.d.ts.map +1 -0
- package/dist/types/sort.js +6 -0
- package/dist/types/sort.js.map +1 -0
- package/dist/types/spatial.d.ts +19 -0
- package/dist/types/spatial.d.ts.map +1 -0
- package/dist/types/spatial.js +6 -0
- package/dist/types/spatial.js.map +1 -0
- package/dist/types/stats.d.ts +21 -0
- package/dist/types/stats.d.ts.map +1 -0
- package/dist/types/stats.js +6 -0
- package/dist/types/stats.js.map +1 -0
- package/dist/types/storage.d.ts +19 -0
- package/dist/types/storage.d.ts.map +1 -0
- package/dist/types/storage.js +6 -0
- package/dist/types/storage.js.map +1 -0
- package/dist/types/tasks.d.ts +14 -0
- package/dist/types/tasks.d.ts.map +1 -0
- package/dist/types/tasks.js +6 -0
- package/dist/types/tasks.js.map +1 -0
- package/dist/types/utils.d.ts +54 -0
- package/dist/types/utils.d.ts.map +1 -0
- package/dist/types/utils.js +6 -0
- package/dist/types/utils.js.map +1 -0
- package/dist/types/workflow.d.ts +17 -0
- package/dist/types/workflow.d.ts.map +1 -0
- package/dist/types/workflow.js +6 -0
- package/dist/types/workflow.js.map +1 -0
- package/dist/utils/aggregationUtils.d.ts +192 -0
- package/dist/utils/aggregationUtils.d.ts.map +1 -0
- package/dist/utils/aggregationUtils.js +450 -0
- package/dist/utils/aggregationUtils.js.map +1 -0
- package/dist/utils/auth.d.ts +93 -0
- package/dist/utils/auth.d.ts.map +1 -0
- package/dist/utils/auth.js +557 -0
- package/dist/utils/auth.js.map +1 -0
- package/dist/utils/cache.d.ts +64 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +464 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/common.d.ts +53 -0
- package/dist/utils/common.d.ts.map +1 -0
- package/dist/utils/common.js +162 -0
- package/dist/utils/common.js.map +1 -0
- package/dist/utils/db.d.ts +101 -0
- package/dist/utils/db.d.ts.map +1 -0
- package/dist/utils/db.js +413 -0
- package/dist/utils/db.js.map +1 -0
- package/dist/utils/dirname.d.ts +30 -0
- package/dist/utils/dirname.d.ts.map +1 -0
- package/dist/utils/dirname.js +95 -0
- package/dist/utils/dirname.js.map +1 -0
- package/dist/utils/dynamicVariableResolver.d.ts +17 -0
- package/dist/utils/dynamicVariableResolver.d.ts.map +1 -0
- package/dist/utils/dynamicVariableResolver.js +262 -0
- package/dist/utils/dynamicVariableResolver.js.map +1 -0
- package/dist/utils/env.d.ts +38 -0
- package/dist/utils/env.d.ts.map +1 -0
- package/dist/utils/env.js +80 -0
- package/dist/utils/env.js.map +1 -0
- package/dist/utils/errorHandler.d.ts +14 -0
- package/dist/utils/errorHandler.d.ts.map +1 -0
- package/dist/utils/errorHandler.js +79 -0
- package/dist/utils/errorHandler.js.map +1 -0
- package/dist/utils/fieldExpansion.d.ts +30 -0
- package/dist/utils/fieldExpansion.d.ts.map +1 -0
- package/dist/utils/fieldExpansion.js +145 -0
- package/dist/utils/fieldExpansion.js.map +1 -0
- package/dist/utils/fieldUtils.d.ts +179 -0
- package/dist/utils/fieldUtils.d.ts.map +1 -0
- package/dist/utils/fieldUtils.js +424 -0
- package/dist/utils/fieldUtils.js.map +1 -0
- package/dist/utils/filterOperators.d.ts +472 -0
- package/dist/utils/filterOperators.d.ts.map +1 -0
- package/dist/utils/filterOperators.js +1229 -0
- package/dist/utils/filterOperators.js.map +1 -0
- package/dist/utils/importUtils.d.ts +127 -0
- package/dist/utils/importUtils.d.ts.map +1 -0
- package/dist/utils/importUtils.js +437 -0
- package/dist/utils/importUtils.js.map +1 -0
- package/dist/utils/index.d.ts +75 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +101 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +41 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +217 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/orderUtils.d.ts +117 -0
- package/dist/utils/orderUtils.d.ts.map +1 -0
- package/dist/utils/orderUtils.js +249 -0
- package/dist/utils/orderUtils.js.map +1 -0
- package/dist/utils/queryBuilder.d.ts +118 -0
- package/dist/utils/queryBuilder.d.ts.map +1 -0
- package/dist/utils/queryBuilder.js +489 -0
- package/dist/utils/queryBuilder.js.map +1 -0
- package/dist/utils/relationLoader.d.ts +65 -0
- package/dist/utils/relationLoader.d.ts.map +1 -0
- package/dist/utils/relationLoader.js +1081 -0
- package/dist/utils/relationLoader.js.map +1 -0
- package/dist/utils/relationPathResolver.d.ts +30 -0
- package/dist/utils/relationPathResolver.d.ts.map +1 -0
- package/dist/utils/relationPathResolver.js +173 -0
- package/dist/utils/relationPathResolver.js.map +1 -0
- package/dist/utils/relationUtils.d.ts +139 -0
- package/dist/utils/relationUtils.d.ts.map +1 -0
- package/dist/utils/relationUtils.js +711 -0
- package/dist/utils/relationUtils.js.map +1 -0
- package/dist/utils/router.d.ts +6 -0
- package/dist/utils/router.d.ts.map +1 -0
- package/dist/utils/router.js +95 -0
- package/dist/utils/router.js.map +1 -0
- package/dist/utils/schema.d.ts +88 -0
- package/dist/utils/schema.d.ts.map +1 -0
- package/dist/utils/schema.js +24 -0
- package/dist/utils/schema.js.map +1 -0
- package/dist/utils/schemaManager.d.ts +238 -0
- package/dist/utils/schemaManager.d.ts.map +1 -0
- package/dist/utils/schemaManager.js +1992 -0
- package/dist/utils/schemaManager.js.map +1 -0
- package/dist/utils/schemaValidator.d.ts +83 -0
- package/dist/utils/schemaValidator.d.ts.map +1 -0
- package/dist/utils/schemaValidator.js +491 -0
- package/dist/utils/schemaValidator.js.map +1 -0
- package/dist/utils/seed.d.ts +45 -0
- package/dist/utils/seed.d.ts.map +1 -0
- package/dist/utils/seed.js +248 -0
- package/dist/utils/seed.js.map +1 -0
- package/dist/utils/sessionCleanup.d.ts +10 -0
- package/dist/utils/sessionCleanup.d.ts.map +1 -0
- package/dist/utils/sessionCleanup.js +49 -0
- package/dist/utils/sessionCleanup.js.map +1 -0
- package/dist/utils/sortUtils.d.ts +117 -0
- package/dist/utils/sortUtils.d.ts.map +1 -0
- package/dist/utils/sortUtils.js +232 -0
- package/dist/utils/sortUtils.js.map +1 -0
- package/dist/utils/spatialUtils.d.ts +244 -0
- package/dist/utils/spatialUtils.d.ts.map +1 -0
- package/dist/utils/spatialUtils.js +359 -0
- package/dist/utils/spatialUtils.js.map +1 -0
- package/dist/utils/systemschema.d.ts +11040 -0
- package/dist/utils/systemschema.d.ts.map +1 -0
- package/dist/utils/systemschema.js +1777 -0
- package/dist/utils/systemschema.js.map +1 -0
- package/dist/utils/tenantUtils.d.ts +34 -0
- package/dist/utils/tenantUtils.d.ts.map +1 -0
- package/dist/utils/tenantUtils.js +124 -0
- package/dist/utils/tenantUtils.js.map +1 -0
- package/dist/utils/typeMapper.d.ts +25 -0
- package/dist/utils/typeMapper.d.ts.map +1 -0
- package/dist/utils/typeMapper.js +282 -0
- package/dist/utils/typeMapper.js.map +1 -0
- package/dist/utils/valueValidator.d.ts +60 -0
- package/dist/utils/valueValidator.d.ts.map +1 -0
- package/dist/utils/valueValidator.js +303 -0
- package/dist/utils/valueValidator.js.map +1 -0
- package/dist/utils/workflow.d.ts +87 -0
- package/dist/utils/workflow.d.ts.map +1 -0
- package/dist/utils/workflow.js +205 -0
- package/dist/utils/workflow.js.map +1 -0
- package/package.json +115 -0
|
@@ -0,0 +1,787 @@
|
|
|
1
|
+
import { APIError } from "../utils/errorHandler.js";
|
|
2
|
+
import workflowService from "../services/WorkflowService.js";
|
|
3
|
+
import ItemsService from "../services/ItemsService.js";
|
|
4
|
+
import fileUpload from "express-fileupload";
|
|
5
|
+
import { fetchWorkflowForExecution, validateWorkflowAccess } from "../utils/workflow.js";
|
|
6
|
+
const registerEndpoint = (app) => {
|
|
7
|
+
/**
|
|
8
|
+
* Execute a workflow manually
|
|
9
|
+
*/
|
|
10
|
+
app.post("/workflows/:id/execute", async (req, res, next) => {
|
|
11
|
+
try {
|
|
12
|
+
if (!req.accountability?.user?.id) {
|
|
13
|
+
throw new APIError("Authentication required", 401);
|
|
14
|
+
}
|
|
15
|
+
const { id } = req.params;
|
|
16
|
+
const triggerData = req.body || {};
|
|
17
|
+
// Fetch workflow and validate access
|
|
18
|
+
const workflow = await fetchWorkflowForExecution(id);
|
|
19
|
+
validateWorkflowAccess(workflow, req.accountability);
|
|
20
|
+
// Create execution record first and return immediately
|
|
21
|
+
const executionRecord = await workflowService.createExecutionRecord(id, req.accountability.user.id, req.accountability.tenant?.id);
|
|
22
|
+
console.log(`📝 Created execution record: ${executionRecord.id}`);
|
|
23
|
+
// Return execution ID immediately so frontend can join socket room
|
|
24
|
+
res.json({
|
|
25
|
+
message: "Workflow execution started",
|
|
26
|
+
execution: executionRecord,
|
|
27
|
+
});
|
|
28
|
+
console.log(`⏱️ Waiting 500ms for frontend to join socket room...`);
|
|
29
|
+
// Give frontend time to join socket room before starting execution (500ms)
|
|
30
|
+
setTimeout(() => {
|
|
31
|
+
console.log(`🚀 Starting workflow execution: ${executionRecord.id}`);
|
|
32
|
+
// Execute workflow asynchronously in background (don't await)
|
|
33
|
+
workflowService.executeWorkflowAsync(id, triggerData, req.accountability.user.id, req.accountability.tenant?.id, executionRecord.id).catch((error) => {
|
|
34
|
+
console.error("Workflow execution error:", error);
|
|
35
|
+
});
|
|
36
|
+
}, 500);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
next(error);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
/**
|
|
43
|
+
* Execute a single node (for testing individual steps)
|
|
44
|
+
*/
|
|
45
|
+
app.post("/workflows/:id/nodes/:nodeId/execute", async (req, res, next) => {
|
|
46
|
+
try {
|
|
47
|
+
if (!req.accountability?.user?.id) {
|
|
48
|
+
throw new APIError("Authentication required", 401);
|
|
49
|
+
}
|
|
50
|
+
const { id, nodeId } = req.params;
|
|
51
|
+
const { inputData } = req.body;
|
|
52
|
+
// Fetch workflow with flow_data for execution
|
|
53
|
+
const workflow = await fetchWorkflowForExecution(id, true);
|
|
54
|
+
validateWorkflowAccess(workflow, req.accountability);
|
|
55
|
+
// Execute node, passing the already-fetched workflow to avoid re-fetching
|
|
56
|
+
const result = await workflowService.executeSingleNodeFromAPI(id, nodeId, inputData || {}, req.accountability.user.id, req.accountability.tenant?.id, workflow // Pass workflow to avoid re-fetching
|
|
57
|
+
);
|
|
58
|
+
res.json({
|
|
59
|
+
message: "Node executed successfully",
|
|
60
|
+
result,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
next(error);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
/**
|
|
68
|
+
* Get workflow execution status
|
|
69
|
+
*/
|
|
70
|
+
app.get("/workflows/:id/executions/:executionId", async (req, res, next) => {
|
|
71
|
+
try {
|
|
72
|
+
if (!req.accountability?.user?.id) {
|
|
73
|
+
throw new APIError("Authentication required", 401);
|
|
74
|
+
}
|
|
75
|
+
const { executionId } = req.params;
|
|
76
|
+
const itemsService = new ItemsService("baasix_WorkflowExecution", {
|
|
77
|
+
accountability: req.accountability,
|
|
78
|
+
});
|
|
79
|
+
const execution = await itemsService.readOne(executionId, {
|
|
80
|
+
fields: ["*", "logs.*"],
|
|
81
|
+
});
|
|
82
|
+
res.json({ data: execution });
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
next(error);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
/**
|
|
89
|
+
* Get workflow executions with filtering and pagination
|
|
90
|
+
*/
|
|
91
|
+
app.get("/workflows/:id/executions", async (req, res, next) => {
|
|
92
|
+
try {
|
|
93
|
+
if (!req.accountability?.user?.id) {
|
|
94
|
+
throw new APIError("Authentication required", 401);
|
|
95
|
+
}
|
|
96
|
+
const { id } = req.params;
|
|
97
|
+
// Parse query parameters
|
|
98
|
+
const query = {
|
|
99
|
+
filter: {},
|
|
100
|
+
limit: req.query.limit ? parseInt(req.query.limit) : 25,
|
|
101
|
+
page: req.query.page ? parseInt(req.query.page) : 1,
|
|
102
|
+
};
|
|
103
|
+
if (req.query.sort) {
|
|
104
|
+
query.sort = req.query.sort;
|
|
105
|
+
}
|
|
106
|
+
const itemsService = new ItemsService("baasix_WorkflowExecution", {
|
|
107
|
+
accountability: req.accountability,
|
|
108
|
+
});
|
|
109
|
+
// Add workflow filter
|
|
110
|
+
let filter = { workflow_Id: id };
|
|
111
|
+
if (req.query.filter) {
|
|
112
|
+
try {
|
|
113
|
+
const userFilter = JSON.parse(req.query.filter);
|
|
114
|
+
filter = { AND: [userFilter, { workflow_Id: id }] };
|
|
115
|
+
}
|
|
116
|
+
catch (e) {
|
|
117
|
+
filter = { workflow_Id: id };
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
query.filter = filter;
|
|
121
|
+
const executions = await itemsService.readByQuery(query);
|
|
122
|
+
res.json(executions);
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
next(error);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
/**
|
|
129
|
+
* Cancel a running workflow execution
|
|
130
|
+
*/
|
|
131
|
+
app.post("/workflows/:id/executions/:executionId/cancel", async (req, res, next) => {
|
|
132
|
+
try {
|
|
133
|
+
if (!req.accountability?.user?.id) {
|
|
134
|
+
throw new APIError("Authentication required", 401);
|
|
135
|
+
}
|
|
136
|
+
const { executionId } = req.params;
|
|
137
|
+
const itemsService = new ItemsService("baasix_WorkflowExecution", {
|
|
138
|
+
accountability: req.accountability,
|
|
139
|
+
});
|
|
140
|
+
await itemsService.updateOne(executionId, {
|
|
141
|
+
status: "cancelled",
|
|
142
|
+
completedAt: new Date(),
|
|
143
|
+
});
|
|
144
|
+
const execution = await itemsService.readOne(executionId);
|
|
145
|
+
res.json({
|
|
146
|
+
message: "Workflow execution cancelled",
|
|
147
|
+
execution,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
next(error);
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
/**
|
|
155
|
+
* Test a workflow with sample data (doesn't save execution)
|
|
156
|
+
*/
|
|
157
|
+
app.post("/workflows/:id/test", async (req, res, next) => {
|
|
158
|
+
try {
|
|
159
|
+
if (!req.accountability?.user?.id) {
|
|
160
|
+
throw new APIError("Authentication required", 401);
|
|
161
|
+
}
|
|
162
|
+
const { id } = req.params;
|
|
163
|
+
const { triggerData = {}, saveExecution = false } = req.body;
|
|
164
|
+
const workflowItemsService = new ItemsService("baasix_Workflow", {
|
|
165
|
+
accountability: req.accountability,
|
|
166
|
+
});
|
|
167
|
+
const workflow = await workflowItemsService.readOne(id);
|
|
168
|
+
if (!workflow) {
|
|
169
|
+
throw new APIError("Workflow not found", 404);
|
|
170
|
+
}
|
|
171
|
+
// Execute workflow
|
|
172
|
+
const execution = await workflowService.executeWorkflow(id, triggerData, req.accountability.user.id, req.accountability.tenant?.id);
|
|
173
|
+
// If not saving execution, mark it for deletion after returning
|
|
174
|
+
if (!saveExecution) {
|
|
175
|
+
const executionService = new ItemsService("baasix_WorkflowExecution", {
|
|
176
|
+
accountability: req.accountability,
|
|
177
|
+
});
|
|
178
|
+
// Schedule deletion after 5 minutes
|
|
179
|
+
setTimeout(async () => {
|
|
180
|
+
try {
|
|
181
|
+
await executionService.deleteOne(execution.id);
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
console.error("Error deleting test execution:", error);
|
|
185
|
+
}
|
|
186
|
+
}, 5 * 60 * 1000);
|
|
187
|
+
}
|
|
188
|
+
res.json({
|
|
189
|
+
message: "Workflow test execution started",
|
|
190
|
+
execution,
|
|
191
|
+
note: saveExecution ? "Execution will be saved" : "Execution will be deleted after 5 minutes",
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
next(error);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
/**
|
|
199
|
+
* Get workflow execution logs
|
|
200
|
+
*/
|
|
201
|
+
app.get("/workflows/:id/executions/:executionId/logs", async (req, res, next) => {
|
|
202
|
+
try {
|
|
203
|
+
if (!req.accountability?.user?.id) {
|
|
204
|
+
throw new APIError("Authentication required", 401);
|
|
205
|
+
}
|
|
206
|
+
const { executionId } = req.params;
|
|
207
|
+
const itemsService = new ItemsService("baasix_WorkflowExecutionLog", {
|
|
208
|
+
accountability: req.accountability,
|
|
209
|
+
});
|
|
210
|
+
const logs = await itemsService.readByQuery({
|
|
211
|
+
filter: { execution_Id: executionId },
|
|
212
|
+
});
|
|
213
|
+
res.json(logs);
|
|
214
|
+
}
|
|
215
|
+
catch (error) {
|
|
216
|
+
next(error);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
/**
|
|
220
|
+
* Get workflow statistics
|
|
221
|
+
*/
|
|
222
|
+
app.get("/workflows/:id/stats", async (req, res, next) => {
|
|
223
|
+
try {
|
|
224
|
+
if (!req.accountability?.user?.id) {
|
|
225
|
+
throw new APIError("Authentication required", 401);
|
|
226
|
+
}
|
|
227
|
+
const { id } = req.params;
|
|
228
|
+
const itemsService = new ItemsService("baasix_WorkflowExecution", {
|
|
229
|
+
accountability: req.accountability,
|
|
230
|
+
});
|
|
231
|
+
// Get execution counts by status
|
|
232
|
+
const executions = await itemsService.readByQuery({
|
|
233
|
+
filter: { workflow_Id: id },
|
|
234
|
+
fields: ["status", "durationMs", "createdAt"],
|
|
235
|
+
limit: -1,
|
|
236
|
+
});
|
|
237
|
+
const stats = {
|
|
238
|
+
total: executions.data.length,
|
|
239
|
+
byStatus: {
|
|
240
|
+
queued: 0,
|
|
241
|
+
running: 0,
|
|
242
|
+
completed: 0,
|
|
243
|
+
failed: 0,
|
|
244
|
+
cancelled: 0,
|
|
245
|
+
},
|
|
246
|
+
avgDuration: 0,
|
|
247
|
+
totalDuration: 0,
|
|
248
|
+
lastExecution: null,
|
|
249
|
+
};
|
|
250
|
+
let totalDuration = 0;
|
|
251
|
+
let durationCount = 0;
|
|
252
|
+
for (const exec of executions.data) {
|
|
253
|
+
stats.byStatus[exec.status]++;
|
|
254
|
+
if (exec.durationMs) {
|
|
255
|
+
totalDuration += exec.durationMs;
|
|
256
|
+
durationCount++;
|
|
257
|
+
}
|
|
258
|
+
if (!stats.lastExecution || new Date(exec.createdAt) > new Date(stats.lastExecution)) {
|
|
259
|
+
stats.lastExecution = exec.createdAt;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
stats.avgDuration = durationCount > 0 ? Math.round(totalDuration / durationCount) : 0;
|
|
263
|
+
stats.totalDuration = totalDuration;
|
|
264
|
+
res.json(stats);
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
next(error);
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
/**
|
|
271
|
+
* Trigger webhook workflow with custom path
|
|
272
|
+
* Catch-all route for custom webhook paths
|
|
273
|
+
*/
|
|
274
|
+
app.all("/webhook/*", async (req, res, next) => {
|
|
275
|
+
try {
|
|
276
|
+
// Extract the webhook path (everything after /webhook)
|
|
277
|
+
const webhookPath = req.path.replace(/^\/webhook/, "") || "/";
|
|
278
|
+
const method = req.method.toUpperCase();
|
|
279
|
+
const triggerData = {
|
|
280
|
+
body: req.body,
|
|
281
|
+
query: req.query,
|
|
282
|
+
headers: req.headers,
|
|
283
|
+
method: req.method,
|
|
284
|
+
path: webhookPath,
|
|
285
|
+
};
|
|
286
|
+
// Fetch workflow by webhook path and method
|
|
287
|
+
const itemsService = new ItemsService("baasix_Workflow");
|
|
288
|
+
const workflowsResult = await itemsService.readByQuery({
|
|
289
|
+
filter: {
|
|
290
|
+
status: "active",
|
|
291
|
+
trigger_type: "webhook",
|
|
292
|
+
trigger_webhook_path: webhookPath,
|
|
293
|
+
trigger_webhook_method: method,
|
|
294
|
+
},
|
|
295
|
+
fields: ["id", "status", "trigger_type", "allowed_roles"],
|
|
296
|
+
limit: 1,
|
|
297
|
+
});
|
|
298
|
+
if (!workflowsResult.data || workflowsResult.data.length === 0) {
|
|
299
|
+
throw new APIError(`Webhook not found for ${method} ${webhookPath} or workflow is not active`, 404);
|
|
300
|
+
}
|
|
301
|
+
const workflow = workflowsResult.data[0];
|
|
302
|
+
// Validate role-based access
|
|
303
|
+
validateWorkflowAccess(workflow, req.accountability);
|
|
304
|
+
const execution = await workflowService.executeWorkflow(workflow.id, triggerData, req.accountability?.user?.id, req.accountability?.tenant?.id);
|
|
305
|
+
res.json({
|
|
306
|
+
message: "Workflow triggered successfully",
|
|
307
|
+
execution: {
|
|
308
|
+
id: execution.id,
|
|
309
|
+
status: execution.status,
|
|
310
|
+
},
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
catch (error) {
|
|
314
|
+
next(error);
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
/**
|
|
318
|
+
* Validate workflow configuration
|
|
319
|
+
*/
|
|
320
|
+
app.post("/workflows/validate", async (req, res, next) => {
|
|
321
|
+
try {
|
|
322
|
+
if (!req.accountability?.user?.id) {
|
|
323
|
+
throw new APIError("Authentication required", 401);
|
|
324
|
+
}
|
|
325
|
+
const { flow_data } = req.body;
|
|
326
|
+
if (!flow_data || !flow_data.nodes || !flow_data.edges) {
|
|
327
|
+
throw new APIError("Invalid workflow data", 400);
|
|
328
|
+
}
|
|
329
|
+
const errors = [];
|
|
330
|
+
const warnings = [];
|
|
331
|
+
// Check for trigger node
|
|
332
|
+
const triggerNodes = flow_data.nodes.filter((n) => n.type === "trigger");
|
|
333
|
+
if (triggerNodes.length === 0) {
|
|
334
|
+
errors.push("Workflow must have exactly one trigger node");
|
|
335
|
+
}
|
|
336
|
+
else if (triggerNodes.length > 1) {
|
|
337
|
+
errors.push("Workflow can only have one trigger node");
|
|
338
|
+
}
|
|
339
|
+
// Check trigger node has only one outgoing edge
|
|
340
|
+
if (triggerNodes.length === 1) {
|
|
341
|
+
const triggerOutgoingEdges = flow_data.edges.filter((e) => e.source === triggerNodes[0].id);
|
|
342
|
+
if (triggerOutgoingEdges.length === 0) {
|
|
343
|
+
errors.push("Trigger node must have at least one outgoing connection");
|
|
344
|
+
}
|
|
345
|
+
else if (triggerOutgoingEdges.length > 1) {
|
|
346
|
+
errors.push("Trigger node can only have one outgoing connection");
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
// Check that all non-trigger nodes have at least one incoming edge
|
|
350
|
+
for (const node of flow_data.nodes) {
|
|
351
|
+
if (node.type !== "trigger") {
|
|
352
|
+
const incomingEdges = flow_data.edges.filter((e) => e.target === node.id);
|
|
353
|
+
if (incomingEdges.length === 0) {
|
|
354
|
+
errors.push(`Node "${node.data?.label || node.type}" (${node.id}) has no incoming connection`);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
// Build connected nodes set
|
|
359
|
+
const connectedNodes = new Set();
|
|
360
|
+
for (const edge of flow_data.edges) {
|
|
361
|
+
connectedNodes.add(edge.source);
|
|
362
|
+
connectedNodes.add(edge.target);
|
|
363
|
+
}
|
|
364
|
+
const orphanedNodes = flow_data.nodes.filter((n) => n.type !== "trigger" && !connectedNodes.has(n.id));
|
|
365
|
+
if (orphanedNodes.length > 0) {
|
|
366
|
+
errors.push(`Found ${orphanedNodes.length} disconnected nodes that will not be executed`);
|
|
367
|
+
}
|
|
368
|
+
// Check for circular dependencies (simplified check)
|
|
369
|
+
const visited = new Set();
|
|
370
|
+
const recursionStack = new Set();
|
|
371
|
+
const hasCycle = (nodeId) => {
|
|
372
|
+
if (recursionStack.has(nodeId))
|
|
373
|
+
return true;
|
|
374
|
+
if (visited.has(nodeId))
|
|
375
|
+
return false;
|
|
376
|
+
visited.add(nodeId);
|
|
377
|
+
recursionStack.add(nodeId);
|
|
378
|
+
const outgoingEdges = flow_data.edges.filter((e) => e.source === nodeId);
|
|
379
|
+
for (const edge of outgoingEdges) {
|
|
380
|
+
if (hasCycle(edge.target))
|
|
381
|
+
return true;
|
|
382
|
+
}
|
|
383
|
+
recursionStack.delete(nodeId);
|
|
384
|
+
return false;
|
|
385
|
+
};
|
|
386
|
+
if (triggerNodes.length > 0 && hasCycle(triggerNodes[0].id)) {
|
|
387
|
+
errors.push("Workflow contains circular dependencies");
|
|
388
|
+
}
|
|
389
|
+
// Check node configurations
|
|
390
|
+
for (const node of flow_data.nodes) {
|
|
391
|
+
const nodeLabel = node.data?.label || node.type;
|
|
392
|
+
if (node.type === "http" && !node.data?.url) {
|
|
393
|
+
errors.push(`HTTP node "${nodeLabel}" is missing URL configuration`);
|
|
394
|
+
}
|
|
395
|
+
if (node.type === "service" && !node.data?.collection) {
|
|
396
|
+
errors.push(`Service node "${nodeLabel}" is missing collection configuration`);
|
|
397
|
+
}
|
|
398
|
+
if (node.type === "condition" && (!node.data?.conditions || node.data.conditions.length === 0)) {
|
|
399
|
+
errors.push(`Condition node "${nodeLabel}" has no conditions defined`);
|
|
400
|
+
}
|
|
401
|
+
if (node.type === "email") {
|
|
402
|
+
if (!node.data?.to) {
|
|
403
|
+
errors.push(`Email node "${nodeLabel}" is missing recipient email(s)`);
|
|
404
|
+
}
|
|
405
|
+
if (!node.data?.subject) {
|
|
406
|
+
errors.push(`Email node "${nodeLabel}" is missing subject`);
|
|
407
|
+
}
|
|
408
|
+
if (!node.data?.body) {
|
|
409
|
+
errors.push(`Email node "${nodeLabel}" is missing email body`);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (node.type === "workflow" && !node.data?.workflowId) {
|
|
413
|
+
errors.push(`Workflow node "${nodeLabel}" is missing target workflow ID`);
|
|
414
|
+
}
|
|
415
|
+
if (node.type === "loop" && !node.data?.array) {
|
|
416
|
+
errors.push(`Loop node "${nodeLabel}" is missing array source`);
|
|
417
|
+
}
|
|
418
|
+
if (node.type === "stats") {
|
|
419
|
+
if (!node.data?.collection) {
|
|
420
|
+
errors.push(`Stats node "${nodeLabel}" is missing collection`);
|
|
421
|
+
}
|
|
422
|
+
if (!node.data?.operation) {
|
|
423
|
+
errors.push(`Stats node "${nodeLabel}" is missing operation type`);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
if (node.type === "file") {
|
|
427
|
+
if (!node.data?.operation) {
|
|
428
|
+
errors.push(`File node "${nodeLabel}" is missing operation type`);
|
|
429
|
+
}
|
|
430
|
+
if ((node.data?.operation === "info" || node.data?.operation === "delete") && !node.data?.fileId) {
|
|
431
|
+
errors.push(`File node "${nodeLabel}" is missing file ID for ${node.data.operation} operation`);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
if (node.type === "variable") {
|
|
435
|
+
if (!node.data?.variables || Object.keys(node.data.variables).length === 0) {
|
|
436
|
+
warnings.push(`Variable node "${nodeLabel}" has no variables defined`);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
if (node.type === "script" && !node.data?.script) {
|
|
440
|
+
errors.push(`Script node "${nodeLabel}" is missing script code`);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
res.json({
|
|
444
|
+
valid: errors.length === 0,
|
|
445
|
+
errors,
|
|
446
|
+
warnings,
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
catch (error) {
|
|
450
|
+
next(error);
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
/**
|
|
454
|
+
* Export workflow(s) as JSON
|
|
455
|
+
*/
|
|
456
|
+
app.post("/workflows/export", async (req, res, next) => {
|
|
457
|
+
try {
|
|
458
|
+
if (!req.accountability?.user?.id) {
|
|
459
|
+
throw new APIError("Authentication required", 401);
|
|
460
|
+
}
|
|
461
|
+
// Only administrators can export workflows
|
|
462
|
+
if (req.accountability.role?.name !== 'administrator' && req.accountability.role?.name !== 'Administrator') {
|
|
463
|
+
throw new APIError("Only administrators can export workflows", 403);
|
|
464
|
+
}
|
|
465
|
+
const { workflowIds } = req.body;
|
|
466
|
+
if (!workflowIds || !Array.isArray(workflowIds) || workflowIds.length === 0) {
|
|
467
|
+
throw new APIError("workflowIds array is required", 400);
|
|
468
|
+
}
|
|
469
|
+
const itemsService = new ItemsService("baasix_Workflow", {
|
|
470
|
+
accountability: req.accountability,
|
|
471
|
+
});
|
|
472
|
+
const workflows = await itemsService.readByQuery({
|
|
473
|
+
filter: { "id": { in: workflowIds } },
|
|
474
|
+
fields: [
|
|
475
|
+
"id",
|
|
476
|
+
"name",
|
|
477
|
+
"description",
|
|
478
|
+
"status",
|
|
479
|
+
"trigger_type",
|
|
480
|
+
"trigger_cron",
|
|
481
|
+
"trigger_webhook_path",
|
|
482
|
+
"trigger_webhook_method",
|
|
483
|
+
"trigger_hook_collection",
|
|
484
|
+
"trigger_hook_action",
|
|
485
|
+
"allowed_roles",
|
|
486
|
+
"flow_data",
|
|
487
|
+
"variables",
|
|
488
|
+
"options",
|
|
489
|
+
],
|
|
490
|
+
limit: -1,
|
|
491
|
+
});
|
|
492
|
+
// Create export data with metadata
|
|
493
|
+
const exportData = {
|
|
494
|
+
version: "1.0",
|
|
495
|
+
exportedAt: new Date().toISOString(),
|
|
496
|
+
exportedBy: req.accountability.user.id,
|
|
497
|
+
workflows: workflows.data,
|
|
498
|
+
};
|
|
499
|
+
res.json({
|
|
500
|
+
message: `Exported ${workflows.data.length} workflow(s)`,
|
|
501
|
+
data: exportData,
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
catch (error) {
|
|
505
|
+
next(error);
|
|
506
|
+
}
|
|
507
|
+
});
|
|
508
|
+
/**
|
|
509
|
+
* Import workflow(s) from JSON
|
|
510
|
+
* Supports overwriting existing workflows with confirmation
|
|
511
|
+
*/
|
|
512
|
+
app.post("/workflows/import", fileUpload(), async (req, res, next) => {
|
|
513
|
+
try {
|
|
514
|
+
if (!req.accountability?.user?.id) {
|
|
515
|
+
throw new APIError("Authentication required", 401);
|
|
516
|
+
}
|
|
517
|
+
// Only administrators can import workflows
|
|
518
|
+
if (req.accountability.role?.name !== 'administrator' && req.accountability.role?.name !== 'Administrator') {
|
|
519
|
+
throw new APIError("Only administrators can import workflows", 403);
|
|
520
|
+
}
|
|
521
|
+
// Check if data is coming from file upload or direct JSON
|
|
522
|
+
let workflows;
|
|
523
|
+
let overwrite = false;
|
|
524
|
+
if (req.files && req.files.file) {
|
|
525
|
+
// Handle file upload
|
|
526
|
+
const file = req.files.file;
|
|
527
|
+
const fileContent = file.data.toString('utf8');
|
|
528
|
+
const importData = JSON.parse(fileContent);
|
|
529
|
+
// Handle both formats: direct workflows array or nested in data.workflows
|
|
530
|
+
if (importData.data && importData.data.workflows) {
|
|
531
|
+
workflows = importData.data.workflows;
|
|
532
|
+
}
|
|
533
|
+
else if (importData.workflows) {
|
|
534
|
+
workflows = importData.workflows;
|
|
535
|
+
}
|
|
536
|
+
else {
|
|
537
|
+
throw new APIError("Invalid import file format", 400);
|
|
538
|
+
}
|
|
539
|
+
overwrite = req.body.overwrite === 'true' || req.body.overwrite === true;
|
|
540
|
+
}
|
|
541
|
+
else if (req.body.workflows) {
|
|
542
|
+
// Handle direct JSON
|
|
543
|
+
workflows = req.body.workflows;
|
|
544
|
+
overwrite = req.body.overwrite === 'true' || req.body.overwrite === true;
|
|
545
|
+
}
|
|
546
|
+
else {
|
|
547
|
+
throw new APIError("workflows array or file is required", 400);
|
|
548
|
+
}
|
|
549
|
+
if (!workflows || !Array.isArray(workflows) || workflows.length === 0) {
|
|
550
|
+
throw new APIError("workflows array is required", 400);
|
|
551
|
+
}
|
|
552
|
+
const itemsService = new ItemsService("baasix_Workflow", {
|
|
553
|
+
accountability: req.accountability,
|
|
554
|
+
});
|
|
555
|
+
const results = {
|
|
556
|
+
created: [],
|
|
557
|
+
updated: [],
|
|
558
|
+
skipped: [],
|
|
559
|
+
errors: [],
|
|
560
|
+
};
|
|
561
|
+
// Check for existing workflows
|
|
562
|
+
const workflowIds = workflows.map((w) => w.id).filter(Boolean);
|
|
563
|
+
// Check for existing workflows including soft-deleted ones
|
|
564
|
+
const existingWorkflows = workflowIds.length > 0
|
|
565
|
+
? await itemsService.readByQuery({
|
|
566
|
+
filter: { id: { in: workflowIds } },
|
|
567
|
+
fields: ["id", "name", "deletedAt"],
|
|
568
|
+
paranoid: false, // Include soft-deleted records
|
|
569
|
+
})
|
|
570
|
+
: { data: [] };
|
|
571
|
+
const existingMap = new Map(existingWorkflows.data.map((w) => [w.id, w]));
|
|
572
|
+
for (const workflow of workflows) {
|
|
573
|
+
try {
|
|
574
|
+
const workflowData = {
|
|
575
|
+
id: workflow.id,
|
|
576
|
+
name: workflow.name,
|
|
577
|
+
description: workflow.description,
|
|
578
|
+
status: workflow.status || "draft", // Import as draft by default for safety
|
|
579
|
+
trigger_type: workflow.trigger_type,
|
|
580
|
+
trigger_cron: workflow.trigger_cron,
|
|
581
|
+
trigger_webhook_path: workflow.trigger_webhook_path,
|
|
582
|
+
trigger_webhook_method: workflow.trigger_webhook_method,
|
|
583
|
+
trigger_hook_collection: workflow.trigger_hook_collection,
|
|
584
|
+
trigger_hook_action: workflow.trigger_hook_action,
|
|
585
|
+
allowed_roles: workflow.allowed_roles || [],
|
|
586
|
+
flow_data: workflow.flow_data,
|
|
587
|
+
variables: workflow.variables || {},
|
|
588
|
+
options: workflow.options || {},
|
|
589
|
+
deletedAt: null, // Explicitly restore if previously deleted
|
|
590
|
+
};
|
|
591
|
+
const existingWorkflow = existingMap.get(workflow.id);
|
|
592
|
+
const exists = !!existingWorkflow;
|
|
593
|
+
if (exists && !overwrite) {
|
|
594
|
+
results.skipped.push({
|
|
595
|
+
id: workflow.id,
|
|
596
|
+
name: workflow.name,
|
|
597
|
+
reason: "Workflow already exists (use overwrite=true to replace)",
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
else if (exists && overwrite) {
|
|
601
|
+
// Update existing workflow (including restoring if deleted)
|
|
602
|
+
if (existingWorkflow.deletedAt) {
|
|
603
|
+
// For soft-deleted records, restore first
|
|
604
|
+
await itemsService.updateOne(workflow.id, { deletedAt: null });
|
|
605
|
+
}
|
|
606
|
+
await itemsService.updateOne(workflow.id, workflowData);
|
|
607
|
+
results.updated.push({
|
|
608
|
+
id: workflow.id,
|
|
609
|
+
name: workflow.name,
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
else {
|
|
613
|
+
// Create new workflow - createOne returns only ID in Drizzle
|
|
614
|
+
const createdId = await itemsService.createOne(workflowData);
|
|
615
|
+
results.created.push({
|
|
616
|
+
id: createdId,
|
|
617
|
+
name: workflowData.name,
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
catch (error) {
|
|
622
|
+
results.errors.push({
|
|
623
|
+
workflow: workflow.id || workflow.name,
|
|
624
|
+
error: error.message,
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
res.json({
|
|
629
|
+
message: "Import completed",
|
|
630
|
+
results,
|
|
631
|
+
summary: {
|
|
632
|
+
total: workflows.length,
|
|
633
|
+
created: results.created.length,
|
|
634
|
+
updated: results.updated.length,
|
|
635
|
+
skipped: results.skipped.length,
|
|
636
|
+
errors: results.errors.length,
|
|
637
|
+
},
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
catch (error) {
|
|
641
|
+
next(error);
|
|
642
|
+
}
|
|
643
|
+
});
|
|
644
|
+
/**
|
|
645
|
+
* Export single workflow by ID
|
|
646
|
+
*/
|
|
647
|
+
app.get("/workflows/:id/export", async (req, res, next) => {
|
|
648
|
+
try {
|
|
649
|
+
if (!req.accountability?.user?.id) {
|
|
650
|
+
throw new APIError("Authentication required", 401);
|
|
651
|
+
}
|
|
652
|
+
// Only administrators can export workflows
|
|
653
|
+
if (req.accountability.role?.name !== 'administrator' && req.accountability.role?.name !== 'Administrator') {
|
|
654
|
+
throw new APIError("Only administrators can export workflows", 403);
|
|
655
|
+
}
|
|
656
|
+
const { id } = req.params;
|
|
657
|
+
const itemsService = new ItemsService("baasix_Workflow", {
|
|
658
|
+
accountability: req.accountability,
|
|
659
|
+
});
|
|
660
|
+
const workflow = await itemsService.readOne(id, {
|
|
661
|
+
fields: [
|
|
662
|
+
"id",
|
|
663
|
+
"name",
|
|
664
|
+
"description",
|
|
665
|
+
"status",
|
|
666
|
+
"trigger_type",
|
|
667
|
+
"trigger_cron",
|
|
668
|
+
"trigger_webhook_path",
|
|
669
|
+
"trigger_webhook_method",
|
|
670
|
+
"trigger_hook_collection",
|
|
671
|
+
"trigger_hook_action",
|
|
672
|
+
"allowed_roles",
|
|
673
|
+
"flow_data",
|
|
674
|
+
"variables",
|
|
675
|
+
"options",
|
|
676
|
+
],
|
|
677
|
+
});
|
|
678
|
+
// Create export data with metadata
|
|
679
|
+
const exportData = {
|
|
680
|
+
version: "1.0",
|
|
681
|
+
exportedAt: new Date().toISOString(),
|
|
682
|
+
exportedBy: req.accountability.user.id,
|
|
683
|
+
workflows: [workflow],
|
|
684
|
+
};
|
|
685
|
+
res.json({
|
|
686
|
+
message: "Workflow exported",
|
|
687
|
+
data: exportData,
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
catch (error) {
|
|
691
|
+
next(error);
|
|
692
|
+
}
|
|
693
|
+
});
|
|
694
|
+
/**
|
|
695
|
+
* Check for existing workflows before import (preview)
|
|
696
|
+
*/
|
|
697
|
+
app.post("/workflows/import/preview", fileUpload(), async (req, res, next) => {
|
|
698
|
+
try {
|
|
699
|
+
if (!req.accountability?.user?.id) {
|
|
700
|
+
throw new APIError("Authentication required", 401);
|
|
701
|
+
}
|
|
702
|
+
// Only administrators can preview workflow imports
|
|
703
|
+
if (req.accountability.role?.name !== 'administrator' && req.accountability.role?.name !== 'Administrator') {
|
|
704
|
+
throw new APIError("Only administrators can import workflows", 403);
|
|
705
|
+
}
|
|
706
|
+
// Check if data is coming from file upload or direct JSON
|
|
707
|
+
let workflows;
|
|
708
|
+
if (req.files && req.files.file) {
|
|
709
|
+
// Handle file upload
|
|
710
|
+
const file = req.files.file;
|
|
711
|
+
const fileContent = file.data.toString('utf8');
|
|
712
|
+
const importData = JSON.parse(fileContent);
|
|
713
|
+
// Handle both formats: direct workflows array or nested in data.workflows
|
|
714
|
+
if (importData.data && importData.data.workflows) {
|
|
715
|
+
workflows = importData.data.workflows;
|
|
716
|
+
}
|
|
717
|
+
else if (importData.workflows) {
|
|
718
|
+
workflows = importData.workflows;
|
|
719
|
+
}
|
|
720
|
+
else {
|
|
721
|
+
throw new APIError("Invalid import file format", 400);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
else if (req.body.workflows) {
|
|
725
|
+
// Handle direct JSON
|
|
726
|
+
workflows = req.body.workflows;
|
|
727
|
+
}
|
|
728
|
+
else {
|
|
729
|
+
throw new APIError("workflows array or file is required", 400);
|
|
730
|
+
}
|
|
731
|
+
if (!workflows || !Array.isArray(workflows) || workflows.length === 0) {
|
|
732
|
+
throw new APIError("workflows array is required", 400);
|
|
733
|
+
}
|
|
734
|
+
// Check for existing workflows including soft-deleted ones
|
|
735
|
+
const workflowIds = workflows.map((w) => w.id).filter(Boolean);
|
|
736
|
+
const itemsService = new ItemsService("baasix_Workflow", {
|
|
737
|
+
accountability: req.accountability,
|
|
738
|
+
});
|
|
739
|
+
const existingWorkflows = workflowIds.length > 0
|
|
740
|
+
? await itemsService.readByQuery({
|
|
741
|
+
filter: { id: { in: workflowIds } },
|
|
742
|
+
fields: ["id", "name", "status", "updatedAt", "deletedAt"],
|
|
743
|
+
paranoid: false, // Include soft-deleted records
|
|
744
|
+
})
|
|
745
|
+
: { data: [] };
|
|
746
|
+
const existingMap = new Map(existingWorkflows.data.map((w) => [w.id, w]));
|
|
747
|
+
const conflicts = [];
|
|
748
|
+
const newWorkflows = [];
|
|
749
|
+
workflows.forEach((workflow) => {
|
|
750
|
+
const existing = existingMap.get(workflow.id);
|
|
751
|
+
if (existing) {
|
|
752
|
+
conflicts.push({
|
|
753
|
+
id: workflow.id,
|
|
754
|
+
name: workflow.name,
|
|
755
|
+
trigger_type: workflow.trigger_type,
|
|
756
|
+
existing: {
|
|
757
|
+
name: existing.name,
|
|
758
|
+
status: existing.status,
|
|
759
|
+
lastUpdated: existing.updatedAt,
|
|
760
|
+
isDeleted: !!existing.deletedAt,
|
|
761
|
+
},
|
|
762
|
+
});
|
|
763
|
+
}
|
|
764
|
+
else {
|
|
765
|
+
newWorkflows.push({
|
|
766
|
+
id: workflow.id,
|
|
767
|
+
name: workflow.name,
|
|
768
|
+
trigger_type: workflow.trigger_type,
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
});
|
|
772
|
+
res.json({
|
|
773
|
+
total: workflows.length,
|
|
774
|
+
new: newWorkflows.length,
|
|
775
|
+
conflicts: conflicts,
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
catch (error) {
|
|
779
|
+
next(error);
|
|
780
|
+
}
|
|
781
|
+
});
|
|
782
|
+
};
|
|
783
|
+
export default {
|
|
784
|
+
id: "workflows",
|
|
785
|
+
handler: registerEndpoint,
|
|
786
|
+
};
|
|
787
|
+
//# sourceMappingURL=workflow.route.js.map
|