@xeplr/workflow 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +352 -0
  3. package/bin/www +7 -0
  4. package/db/xcfgSetup.js +8 -0
  5. package/env.required.js +41 -0
  6. package/index.js +313 -0
  7. package/lib/actionCatalog.js +193 -0
  8. package/lib/actions/jobRun.js +149 -0
  9. package/lib/actions/screenShow.js +55 -0
  10. package/lib/db.js +82 -0
  11. package/lib/envExposed.js +87 -0
  12. package/lib/flows.js +832 -0
  13. package/lib/flowsRouter.js +113 -0
  14. package/lib/router.js +260 -0
  15. package/lib/workflowRunner.js +649 -0
  16. package/migrations/0001_companies.sql +23 -0
  17. package/migrations/0002_workspaces.sql +22 -0
  18. package/migrations/0003_workflows.sql +35 -0
  19. package/migrations/0004_workflow_steps.sql +79 -0
  20. package/migrations/0005_workflow_runs.sql +49 -0
  21. package/migrations/0006_workflow_step_runs.sql +42 -0
  22. package/migrations/0007_workflow_resume_keys.sql +42 -0
  23. package/migrations/0008_workflow_run_edges.sql +43 -0
  24. package/migrations/0009_workflow_steps_layout.sql +11 -0
  25. package/migrations/0010_workflow_steps_sample_output.sql +17 -0
  26. package/migrations/0011_workflow_steps_params.sql +27 -0
  27. package/migrations/0012_workflows_kind.sql +27 -0
  28. package/migrations/0013_workflows_key.sql +48 -0
  29. package/migrations-auth/0001_workflow_access.sql +129 -0
  30. package/migrations-auth/0003_nav_menus.sql +62 -0
  31. package/migrations-auth/0004_flows_access.sql +76 -0
  32. package/models/Company.js +82 -0
  33. package/models/Workflow.js +63 -0
  34. package/models/WorkflowResumeKey.js +32 -0
  35. package/models/WorkflowRun.js +64 -0
  36. package/models/WorkflowRunEdge.js +49 -0
  37. package/models/WorkflowStep.js +66 -0
  38. package/models/WorkflowStepRun.js +49 -0
  39. package/models/Workspace.js +75 -0
  40. package/models/index.js +25 -0
  41. package/orchestration/standalone.js +123 -0
  42. package/package.json +69 -0
@@ -0,0 +1,123 @@
1
+ // The ONLY file in this package that reads development.env or process.env
2
+ // directly. Everything downstream of here (lib/, models/, index.js) takes
3
+ // config as arguments — this file's entire job is turning env vars into that
4
+ // config, then calling the exact same registerWorkflow() a host app would
5
+ // call itself. Running workflow standalone (`npm run start-api`) is this
6
+ // package consuming its own public API, not a separate code path.
7
+
8
+ require('dotenv').config({ path: require('path').join(__dirname, '..', (process.env.NODE_ENV || 'development') + '.env') });
9
+
10
+ require('@xeplr/base-apis').checkEnv(require('../env.required.js'), { appName: 'api' });
11
+
12
+ var path = require('path');
13
+ var { resolveConfig, mtMiddleware, resolveDbConnection, registerApplication } = require('@xeplr/db');
14
+
15
+ // WORKFLOW_CONNECTION is an OVERRIDE now — the connection normally comes from
16
+ // the shared XEPLR_DB_CONNECTION that every xeplr service reads, so rotating
17
+ // the database password is one edit rather than one per service. DB_API (which
18
+ // database) is untouched and stays workflow's own.
19
+ function workflowConnection() { return resolveDbConnection('WORKFLOW_CONNECTION'); }
20
+ var { up } = require('@xeplr/db').sqlMigrator;
21
+ var { authMiddleware, mtMembershipMiddleware } = require('@xeplr/auth');
22
+ var xcfgSetup = require('../db/xcfgSetup');
23
+ var actionCatalog = require('../lib/actionCatalog');
24
+ var { registerWorkflow } = require('../index');
25
+
26
+
27
+ async function start() {
28
+ // This process runs workflow as its own product, so the package name is the
29
+ // application name — the one case where they coincide (an embedded mount
30
+ // inherits its host's id instead; see registerWorkflow).
31
+ //
32
+ // Declared BEFORE xcfgSetup.ready() below, which resolves its applicationId
33
+ // from this registry: the rows this process writes into the SHARED
34
+ // xeplr_configs have to be attributed to workflow rather than falling back
35
+ // to a default that happens to be right here and would hide the mistake
36
+ // from anyone copying this file. Workflow's OWN tables need none of this —
37
+ // they live in this deployment's own database.
38
+ var APPLICATION_ID = process.env.WORKFLOW_APPLICATION_ID || 'xeplr-workflow';
39
+ registerApplication(APPLICATION_ID);
40
+ console.log('[api] application: ' + APPLICATION_ID);
41
+
42
+ await resolveConfig('api', workflowConnection());
43
+
44
+ var result = await up({
45
+ db: process.env.DB_API,
46
+ dir: path.join(__dirname, '..', 'migrations'),
47
+ connectionName: 'api'
48
+ });
49
+ console.log(result.migrations.length
50
+ ? '[api] ran ' + result.migrations.length + ' migrations'
51
+ : '[api] migrations up to date');
52
+
53
+ // xeplr_configs — shared control-plane DB. Required, fail-fast: several
54
+ // built-in actions write movement metadata through it, and starting
55
+ // without it would run workflows that silently record nothing.
56
+ await xcfgSetup.ready();
57
+ console.log('[api] xeplr_configs ready');
58
+
59
+ var registered = actionCatalog.registerAll();
60
+ console.log('[api] registered ' + registered.length + ' actions: ' + registered.join(', '));
61
+
62
+ // This process's own auth — connects to whatever AUTH_DB_NAME /
63
+ // AUTH_DB_CONNECTION_INFO_ENCRYPTED point at. A HOST app embedding
64
+ // workflow via registerWorkflow({ app, ... }) supplies its own
65
+ // already-built mtMembershipGate/authMiddleware instead of any of this —
66
+ // this file exists only for running workflow entirely on its own.
67
+ var auth = require('@xeplr/auth').attach();
68
+ require('@xeplr/email').configureFromEnv();
69
+
70
+ // The TEMPLATE STORE — its own database (xeplr_email), created on first
71
+ // boot. Best-effort: an install with no XEPLR_DB_CONNECTION reachable still
72
+ // runs, it just cannot use templated email. Failing the whole API over a
73
+ // feature a workflow may never touch would be the wrong trade.
74
+ try {
75
+ await require('@xeplr/email').initTemplates();
76
+ console.log('[api] email templates ready');
77
+ } catch (err) {
78
+ console.warn('[api] email templates unavailable (' + err.message + ') — steps using templateName will fail until this is fixed');
79
+ }
80
+ await auth.ready();
81
+ var mtMembershipGate = mtMembershipMiddleware({ userTenantsMapping: auth.model('UserTenantsMapping') });
82
+
83
+ await registerWorkflow({
84
+ // Already registered at the top of start(); passed again only to keep
85
+ // this call self-describing. Idempotent under the same value.
86
+ applicationId: APPLICATION_ID,
87
+ db: {
88
+ name: process.env.DB_API,
89
+ connection: workflowConnection(),
90
+ // Two tenancy levels, l1 = companyId / l2 = workspaceId — mirrored in
91
+ // @xeplr/ui-workflow's src/main.jsx's own registerMTs() call for the standalone UI.
92
+ mts: {
93
+ l1: { name: 'companyId', header: 'x-company-id' },
94
+ l2: { name: 'workspaceId', header: 'x-workspace-id' }
95
+ }
96
+ },
97
+ port: process.env.WORKFLOW_PORT,
98
+ mountPath: '/', // preserves today's URLs — no /workflow prefix standalone
99
+ appName: 'xeplr_workflow_api',
100
+ log: { logDir: process.env.LOG_DIR || './logs' },
101
+ // THE GATE, in the slot createApp reserves for it — and createApp's OWN
102
+ // gate, not a JWT check private to this process. One implementation of
103
+ // "is this caller authenticated" across every service, so a change to how
104
+ // a token is validated lands in one place instead of in each app's copy.
105
+ //
106
+ // publicPaths replaces what gatedAuth did by hand: /public/* is open by
107
+ // design (see lib/router.js on POST /public/resume/:key — a resume link is
108
+ // followed from an email client, with no token to send), and /events would
109
+ // be too if this process ever mounts an SSE stream, since EventSource
110
+ // cannot set an Authorization header.
111
+ auth: { publicPaths: ['/public/', '/events'] },
112
+ middleware: [mtMiddleware()],
113
+ mtMembershipGate: mtMembershipGate,
114
+ authMiddleware: authMiddleware
115
+ });
116
+ }
117
+
118
+ start().catch(function(err) {
119
+ console.error('[api] startup failed:', err.stack || err.message);
120
+ process.exit(1);
121
+ });
122
+
123
+ module.exports = start;
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@xeplr/workflow",
3
+ "version": "1.0.1",
4
+ "description": "Workflows over @xeplr/actions — steps that bind inputs to earlier outputs, branch on conditions, fan out over lists and wait for a person or a job. registerWorkflow() mounts it into a host Express app, or it runs on its own.",
5
+ "main": "index.js",
6
+ "bin": {
7
+ "xeplr-workflow-server": "./bin/www"
8
+ },
9
+ "files": [
10
+ "index.js",
11
+ "env.required.js",
12
+ "lib/",
13
+ "models/",
14
+ "migrations/",
15
+ "migrations-auth/",
16
+ "orchestration/",
17
+ "db/",
18
+ "bin/"
19
+ ],
20
+ "scripts": {
21
+ "check-env": "dotenv -e development.env -- xeplr-check-env",
22
+ "db:create": "dotenv -e development.env -- xeplr-migrate create-db --connectionName api --connection-env WORKFLOW_CONNECTION",
23
+ "db:encrypt": "dotenv -e development.env -- xeplr-db-encrypt",
24
+ "start-api": "NODE_ENV=development node ./bin/www",
25
+ "migrate:up": "dotenv -e development.env -- xeplr-migrate up --dir ./migrations --connectionName api --connection-env WORKFLOW_CONNECTION",
26
+ "migrate:status": "dotenv -e development.env -- xeplr-migrate status --dir ./migrations --connectionName api --connection-env WORKFLOW_CONNECTION",
27
+ "test": "node test/run.mjs"
28
+ },
29
+ "keywords": [
30
+ "workflow",
31
+ "orchestration",
32
+ "actions",
33
+ "engine",
34
+ "express",
35
+ "xeplr"
36
+ ],
37
+ "author": "xeplr",
38
+ "license": "MIT",
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "https://github.com/Xeplr/x-flow"
42
+ },
43
+ "publishConfig": {
44
+ "access": "public"
45
+ },
46
+ "dependencies": {
47
+ "@xeplr/actions": "^1.1.0",
48
+ "@xeplr/auth": "^1.0.0",
49
+ "@xeplr/base-apis": "^2.0.2",
50
+ "@xeplr/db": "^1.0.0",
51
+ "@xeplr/email": "^1.0.0",
52
+ "@xeplr/expression-handler": "^1.0.0",
53
+ "@xeplr/schema-handler": "^1.0.0",
54
+ "@xeplr/utils": "^1.0.0",
55
+ "dotenv": "^17.4.2",
56
+ "express": "^5.2.0",
57
+ "pg": "^8.20.0"
58
+ },
59
+ "devDependencies": {
60
+ "dotenv-cli": "^8.0.0"
61
+ },
62
+ "xeplr": {
63
+ "tagPrefix": "workflow-v",
64
+ "releasePaths": [
65
+ ".",
66
+ ":(exclude)ui"
67
+ ]
68
+ }
69
+ }