@cyberismo/backend 0.0.21 → 0.0.22

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 (126) hide show
  1. package/dist/app.d.ts +5 -2
  2. package/dist/app.js +22 -9
  3. package/dist/app.js.map +1 -1
  4. package/dist/auth/index.d.ts +16 -0
  5. package/dist/auth/index.js +15 -0
  6. package/dist/auth/index.js.map +1 -0
  7. package/dist/auth/keycloak.d.ts +27 -0
  8. package/dist/auth/keycloak.js +81 -0
  9. package/dist/auth/keycloak.js.map +1 -0
  10. package/dist/auth/mock.d.ts +23 -0
  11. package/dist/auth/mock.js +28 -0
  12. package/dist/auth/mock.js.map +1 -0
  13. package/dist/auth/types.d.ts +16 -0
  14. package/dist/auth/types.js +14 -0
  15. package/dist/auth/types.js.map +1 -0
  16. package/dist/domain/auth/index.d.ts +14 -0
  17. package/dist/domain/auth/index.js +30 -0
  18. package/dist/domain/auth/index.js.map +1 -0
  19. package/dist/domain/calculations/index.js +3 -1
  20. package/dist/domain/calculations/index.js.map +1 -1
  21. package/dist/domain/calculations/service.js +13 -11
  22. package/dist/domain/calculations/service.js.map +1 -1
  23. package/dist/domain/cardTypes/index.js +5 -3
  24. package/dist/domain/cardTypes/index.js.map +1 -1
  25. package/dist/domain/cardTypes/service.js +24 -72
  26. package/dist/domain/cardTypes/service.js.map +1 -1
  27. package/dist/domain/cards/index.js +19 -15
  28. package/dist/domain/cards/index.js.map +1 -1
  29. package/dist/domain/cards/lib.js +95 -93
  30. package/dist/domain/cards/lib.js.map +1 -1
  31. package/dist/domain/cards/service.d.ts +2 -1
  32. package/dist/domain/cards/service.js +60 -87
  33. package/dist/domain/cards/service.js.map +1 -1
  34. package/dist/domain/fieldTypes/index.js +4 -2
  35. package/dist/domain/fieldTypes/index.js.map +1 -1
  36. package/dist/domain/graphModels/index.js +3 -1
  37. package/dist/domain/graphModels/index.js.map +1 -1
  38. package/dist/domain/graphViews/index.js +3 -1
  39. package/dist/domain/graphViews/index.js.map +1 -1
  40. package/dist/domain/labels/index.js +4 -2
  41. package/dist/domain/labels/index.js.map +1 -1
  42. package/dist/domain/labels/service.d.ts +1 -1
  43. package/dist/domain/labels/service.js +2 -2
  44. package/dist/domain/labels/service.js.map +1 -1
  45. package/dist/domain/linkTypes/index.js +4 -2
  46. package/dist/domain/linkTypes/index.js.map +1 -1
  47. package/dist/domain/logicPrograms/index.js +3 -1
  48. package/dist/domain/logicPrograms/index.js.map +1 -1
  49. package/dist/domain/mcp/index.d.ts +15 -0
  50. package/dist/domain/mcp/index.js +127 -0
  51. package/dist/domain/mcp/index.js.map +1 -0
  52. package/dist/domain/project/index.js +7 -5
  53. package/dist/domain/project/index.js.map +1 -1
  54. package/dist/domain/project/service.js +18 -14
  55. package/dist/domain/project/service.js.map +1 -1
  56. package/dist/domain/reports/index.js +3 -1
  57. package/dist/domain/reports/index.js.map +1 -1
  58. package/dist/domain/resources/index.js +6 -4
  59. package/dist/domain/resources/index.js.map +1 -1
  60. package/dist/domain/resources/service.js +66 -64
  61. package/dist/domain/resources/service.js.map +1 -1
  62. package/dist/domain/templates/index.js +5 -3
  63. package/dist/domain/templates/index.js.map +1 -1
  64. package/dist/domain/tree/index.js +3 -1
  65. package/dist/domain/tree/index.js.map +1 -1
  66. package/dist/domain/workflows/index.js +3 -1
  67. package/dist/domain/workflows/index.js.map +1 -1
  68. package/dist/export.d.ts +6 -5
  69. package/dist/export.js +15 -11
  70. package/dist/export.js.map +1 -1
  71. package/dist/index.d.ts +8 -2
  72. package/dist/index.js +5 -3
  73. package/dist/index.js.map +1 -1
  74. package/dist/main.js +29 -2
  75. package/dist/main.js.map +1 -1
  76. package/dist/middleware/auth.d.ts +40 -0
  77. package/dist/middleware/auth.js +68 -0
  78. package/dist/middleware/auth.js.map +1 -0
  79. package/dist/middleware/commandManager.d.ts +2 -2
  80. package/dist/middleware/commandManager.js +9 -11
  81. package/dist/middleware/commandManager.js.map +1 -1
  82. package/dist/public/THIRD-PARTY.txt +37 -11
  83. package/dist/public/assets/index-B_lh6qtv.css +1 -0
  84. package/dist/public/assets/{index-Ca10XaMv.js → index-CEol8Bfi.js} +43823 -43030
  85. package/dist/public/config.json +1 -0
  86. package/dist/public/index.html +2 -2
  87. package/dist/types.d.ts +25 -0
  88. package/dist/types.js +13 -1
  89. package/dist/types.js.map +1 -1
  90. package/package.json +8 -5
  91. package/src/app.ts +34 -14
  92. package/src/auth/index.ts +17 -0
  93. package/src/auth/keycloak.ts +109 -0
  94. package/src/auth/mock.ts +38 -0
  95. package/src/auth/types.ts +18 -0
  96. package/src/domain/auth/index.ts +35 -0
  97. package/src/domain/calculations/index.ts +13 -6
  98. package/src/domain/calculations/service.ts +16 -14
  99. package/src/domain/cardTypes/index.ts +24 -16
  100. package/src/domain/cardTypes/service.ts +41 -95
  101. package/src/domain/cards/index.ts +62 -44
  102. package/src/domain/cards/lib.ts +105 -100
  103. package/src/domain/cards/service.ts +73 -89
  104. package/src/domain/fieldTypes/index.ts +23 -16
  105. package/src/domain/graphModels/index.ts +13 -6
  106. package/src/domain/graphViews/index.ts +13 -6
  107. package/src/domain/labels/index.ts +5 -2
  108. package/src/domain/labels/service.ts +2 -2
  109. package/src/domain/linkTypes/index.ts +14 -7
  110. package/src/domain/logicPrograms/index.ts +3 -0
  111. package/src/domain/mcp/index.ts +159 -0
  112. package/src/domain/project/index.ts +17 -8
  113. package/src/domain/project/service.ts +20 -16
  114. package/src/domain/reports/index.ts +13 -6
  115. package/src/domain/resources/index.ts +6 -1
  116. package/src/domain/resources/service.ts +102 -97
  117. package/src/domain/templates/index.ts +31 -19
  118. package/src/domain/tree/index.ts +3 -1
  119. package/src/domain/workflows/index.ts +13 -6
  120. package/src/export.ts +16 -13
  121. package/src/index.ts +10 -3
  122. package/src/main.ts +44 -2
  123. package/src/middleware/auth.ts +90 -0
  124. package/src/middleware/commandManager.ts +11 -14
  125. package/src/types.ts +27 -0
  126. package/dist/public/assets/index-CRSBseQM.css +0 -1
@@ -50,17 +50,19 @@ async function toModuleInfo(
50
50
  export async function getProject(
51
51
  commands: CommandManager,
52
52
  ): Promise<ProjectInfo> {
53
- const project = await commands.showCmd.showProject();
54
- const modules = await commands.showCmd.showModules();
55
- const moduleDetails = await Promise.all(
56
- modules.map((mod) => toModuleInfo(commands, mod)),
57
- );
53
+ return commands.consistent(async () => {
54
+ const project = await commands.showCmd.showProject();
55
+ const modules = await commands.showCmd.showModules();
56
+ const moduleDetails = await Promise.all(
57
+ modules.map((mod) => toModuleInfo(commands, mod)),
58
+ );
58
59
 
59
- return {
60
- name: project.name,
61
- cardKeyPrefix: project.prefix,
62
- modules: moduleDetails,
63
- };
60
+ return {
61
+ name: project.name,
62
+ cardKeyPrefix: project.prefix,
63
+ modules: moduleDetails,
64
+ };
65
+ });
64
66
  }
65
67
 
66
68
  export async function updateProject(
@@ -69,12 +71,14 @@ export async function updateProject(
69
71
  ): Promise<ProjectInfo> {
70
72
  const { name, cardKeyPrefix } = updates;
71
73
 
72
- if (cardKeyPrefix) {
73
- await commands.renameCmd.rename(cardKeyPrefix);
74
- }
75
- if (name) {
76
- await commands.project.configuration.setProjectName(name);
77
- }
74
+ await commands.atomic(async () => {
75
+ if (cardKeyPrefix) {
76
+ await commands.renameCmd.rename(cardKeyPrefix);
77
+ }
78
+ if (name) {
79
+ await commands.project.configuration.setProjectName(name);
80
+ }
81
+ }, 'Update project settings');
78
82
 
79
83
  return getProject(commands);
80
84
  }
@@ -15,6 +15,8 @@ import { Hono } from 'hono';
15
15
  import * as reportService from './service.js';
16
16
  import { createReportSchema } from './schema.js';
17
17
  import { zValidator } from '../../middleware/zvalidator.js';
18
+ import { UserRole } from '../../types.js';
19
+ import { requireRole } from '../../middleware/auth.js';
18
20
 
19
21
  const router = new Hono();
20
22
 
@@ -43,12 +45,17 @@ const router = new Hono();
43
45
  * 500:
44
46
  * description: Server error
45
47
  */
46
- router.post('/', zValidator('json', createReportSchema), async (c) => {
47
- const commands = c.get('commands');
48
- const { identifier } = c.req.valid('json');
48
+ router.post(
49
+ '/',
50
+ requireRole(UserRole.Admin),
51
+ zValidator('json', createReportSchema),
52
+ async (c) => {
53
+ const commands = c.get('commands');
54
+ const { identifier } = c.req.valid('json');
49
55
 
50
- await reportService.createReport(commands, identifier);
51
- return c.json({ message: 'Report created successfully' });
52
- });
56
+ await reportService.createReport(commands, identifier);
57
+ return c.json({ message: 'Report created successfully' });
58
+ },
59
+ );
53
60
 
54
61
  export default router;
@@ -14,12 +14,14 @@
14
14
  import { Hono } from 'hono';
15
15
  import * as resourceService from './service.js';
16
16
  import type { ResourceValidationResponse } from '../../types.js';
17
+ import { UserRole } from '../../types.js';
17
18
  import { resourceParamsSchema } from '../../common/validationSchemas.js';
18
19
  import { zValidator } from '../../middleware/zvalidator.js';
19
20
  import {
20
21
  validateResourceParamsSchema,
21
22
  updateOperationBodySchema,
22
23
  } from './schema.js';
24
+ import { requireRole } from '../../middleware/auth.js';
23
25
 
24
26
  const router = new Hono();
25
27
 
@@ -35,7 +37,7 @@ const router = new Hono();
35
37
  * 500:
36
38
  * description: project_path not set or other internal error
37
39
  */
38
- router.get('/tree', async (c) => {
40
+ router.get('/tree', requireRole(UserRole.Reader), async (c) => {
39
41
  const commands = c.get('commands');
40
42
 
41
43
  try {
@@ -97,6 +99,7 @@ router.get('/tree', async (c) => {
97
99
  */
98
100
  router.get(
99
101
  '/:prefix/:type/:identifier/validate',
102
+ requireRole(UserRole.Reader),
100
103
  zValidator('param', validateResourceParamsSchema),
101
104
  async (c) => {
102
105
  const commands = c.get('commands');
@@ -117,6 +120,7 @@ router.get(
117
120
 
118
121
  router.delete(
119
122
  '/:prefix/:type/:identifier',
123
+ requireRole(UserRole.Admin),
120
124
  zValidator('param', resourceParamsSchema),
121
125
  async (c) => {
122
126
  const commands = c.get('commands');
@@ -130,6 +134,7 @@ router.delete(
130
134
 
131
135
  router.post(
132
136
  '/:prefix/:type/:identifier/operation',
137
+ requireRole(UserRole.Admin),
133
138
  zValidator('param', resourceParamsSchema),
134
139
  zValidator('json', updateOperationBodySchema),
135
140
  async (c) => {
@@ -42,7 +42,7 @@ const resourceTypes: ResourceFolderType[] = [
42
42
 
43
43
  async function getModules(commands: CommandManager) {
44
44
  try {
45
- const moduleNames = commands.showCmd.showModules();
45
+ const moduleNames = await commands.showCmd.showModules();
46
46
  return Promise.all(
47
47
  moduleNames.map(async (moduleName) => {
48
48
  try {
@@ -77,102 +77,104 @@ function sortTemplateCardsByRank(
77
77
  }
78
78
 
79
79
  export async function buildResourceTree(commands: CommandManager) {
80
- const project = await commands.showCmd.showProject();
81
- const tree: unknown[] = [];
82
-
83
- const sortByDisplayName = (
84
- nodes: { data: { displayName: string; name: string } }[],
85
- ) =>
86
- nodes.sort((a, b) =>
87
- (a.data.displayName || a.data.name.split('/')[2] || '').localeCompare(
88
- b.data.displayName || b.data.name.split('/')[2] || '',
89
- ),
90
- );
91
-
92
- const modules = await getModules(commands);
93
-
94
- // General section first (single node with project + modules metadata)
95
- tree.push({
96
- id: 'general-project',
97
- type: 'general',
98
- name: 'project',
99
- data: {
100
- name: project.name,
101
- cardKeyPrefix: project.prefix,
102
- modules,
103
- },
104
- readOnly: false,
105
- });
106
-
107
- // Process each resource type
108
- for (const resourceType of resourceTypes) {
109
- let rootResources: unknown[];
110
- let moduleResources: { [prefix: string]: unknown[] };
111
-
112
- if (resourceType === 'templates') {
113
- ({ rootResources, moduleResources } = await processTemplates(
114
- commands,
115
- project.prefix,
116
- ));
117
- } else {
118
- ({ rootResources, moduleResources } = await groupResourcesByPrefix(
119
- commands,
120
- resourceType,
121
- project.prefix,
122
- ));
123
- }
80
+ return commands.consistent(async () => {
81
+ const project = await commands.showCmd.showProject();
82
+ const tree: unknown[] = [];
83
+
84
+ const sortByDisplayName = (
85
+ nodes: { data: { displayName: string; name: string } }[],
86
+ ) =>
87
+ nodes.sort((a, b) =>
88
+ (a.data.displayName || a.data.name.split('/')[2] || '').localeCompare(
89
+ b.data.displayName || b.data.name.split('/')[2] || '',
90
+ ),
91
+ );
124
92
 
125
- // Sort resources by display name if present
126
- sortByDisplayName(
127
- rootResources as { data: { displayName: string; name: string } }[],
128
- );
93
+ const modules = await getModules(commands);
94
+
95
+ // General section first (single node with project + modules metadata)
96
+ tree.push({
97
+ id: 'general-project',
98
+ type: 'general',
99
+ name: 'project',
100
+ data: {
101
+ name: project.name,
102
+ cardKeyPrefix: project.prefix,
103
+ modules,
104
+ },
105
+ readOnly: false,
106
+ });
107
+
108
+ // Process each resource type
109
+ for (const resourceType of resourceTypes) {
110
+ let rootResources: unknown[];
111
+ let moduleResources: { [prefix: string]: unknown[] };
112
+
113
+ if (resourceType === 'templates') {
114
+ ({ rootResources, moduleResources } = await processTemplates(
115
+ commands,
116
+ project.prefix,
117
+ ));
118
+ } else {
119
+ ({ rootResources, moduleResources } = await groupResourcesByPrefix(
120
+ commands,
121
+ resourceType,
122
+ project.prefix,
123
+ ));
124
+ }
129
125
 
130
- Object.values(moduleResources).forEach((resources) =>
126
+ // Sort resources by display name if present
131
127
  sortByDisplayName(
132
- resources as { data: { displayName: string; name: string } }[],
133
- ),
134
- );
128
+ rootResources as { data: { displayName: string; name: string } }[],
129
+ );
130
+
131
+ Object.values(moduleResources).forEach((resources) =>
132
+ sortByDisplayName(
133
+ resources as { data: { displayName: string; name: string } }[],
134
+ ),
135
+ );
135
136
 
136
- const projectNode =
137
- rootResources.length > 0
138
- ? [
139
- {
140
- id: `${resourceType}-project`,
141
- type: 'module',
142
- name: 'project',
143
- children: rootResources,
144
- readOnly: false,
145
- },
146
- ]
147
- : [];
148
-
149
- const moduleNodes = Object.entries(moduleResources)
150
- .map(([prefix, resources]) => ({
151
- id: `${resourceType}-module-${prefix}`,
152
- type: 'module',
153
- name:
154
- modules.find((module) => module.cardKeyPrefix === prefix)?.name ||
137
+ const projectNode =
138
+ rootResources.length > 0
139
+ ? [
140
+ {
141
+ id: `${resourceType}-project`,
142
+ type: 'module',
143
+ name: 'project',
144
+ children: rootResources,
145
+ readOnly: false,
146
+ },
147
+ ]
148
+ : [];
149
+
150
+ const moduleNodes = Object.entries(moduleResources)
151
+ .map(([prefix, resources]) => ({
152
+ id: `${resourceType}-module-${prefix}`,
153
+ type: 'module',
154
+ name:
155
+ modules.find((module) => module.cardKeyPrefix === prefix)?.name ||
156
+ prefix,
155
157
  prefix,
156
- prefix,
157
- children: resources,
158
- readOnly: true,
159
- }))
160
- .sort((a, b) => a.name.localeCompare(b.name));
161
-
162
- const allResources = [...projectNode, ...moduleNodes];
163
-
164
- // Add combined resources (project + modules nested under module nodes) under the same group
165
- if (allResources.length > 0) {
166
- tree.push({
167
- id: resourceType,
168
- type: 'resourceGroup',
169
- name: resourceType,
170
- children: allResources,
171
- });
158
+ children: resources,
159
+ readOnly: true,
160
+ }))
161
+ .sort((a, b) => a.name.localeCompare(b.name));
162
+
163
+ const allResources = [...projectNode, ...moduleNodes];
164
+
165
+ // Add combined resources (project + modules nested under module nodes) under the same group
166
+ if (allResources.length > 0) {
167
+ tree.push({
168
+ id: resourceType,
169
+ type: 'resourceGroup',
170
+ name: resourceType,
171
+ children: allResources,
172
+ });
173
+ }
172
174
  }
173
- }
174
175
 
175
- return tree;
176
+ return tree;
177
+ });
176
178
  }
177
179
 
178
180
  // Helper function to parse resource prefix
@@ -456,9 +458,8 @@ export async function validateResource(
456
458
  commands: CommandManager,
457
459
  resource: ValidateResourceParams,
458
460
  ) {
459
- const errors = await commands.validateCmd.validateResource(
460
- resource,
461
- commands.project,
461
+ const errors = await commands.consistent(() =>
462
+ commands.validateCmd.validateResource(resource, commands.project),
462
463
  );
463
464
 
464
465
  return {
@@ -476,9 +477,13 @@ export async function updateResourceWithOperation(
476
477
  body: UpdateOperationBody,
477
478
  ) {
478
479
  const { updateKey, operation } = body;
479
- await commands.updateCmd.applyResourceOperation(
480
- resourceNameToString(resource),
481
- updateKey,
482
- operation,
480
+ await commands.atomic(
481
+ () =>
482
+ commands.updateCmd.applyResourceOperation(
483
+ resourceNameToString(resource),
484
+ updateKey,
485
+ operation,
486
+ ),
487
+ `Update ${resource.type} ${resource.identifier}`,
483
488
  );
484
489
  }
@@ -16,6 +16,8 @@ import * as templateService from './service.js';
16
16
  import { createTemplateSchema, addTemplateCardSchema } from './schema.js';
17
17
  import { zValidator } from '../../middleware/zvalidator.js';
18
18
  import { isSSGContext } from 'hono/ssg';
19
+ import { UserRole } from '../../types.js';
20
+ import { requireRole } from '../../middleware/auth.js';
19
21
 
20
22
  const router = new Hono();
21
23
 
@@ -33,7 +35,7 @@ const router = new Hono();
33
35
  * 500:
34
36
  * description: project_path not set or other internal error
35
37
  */
36
- router.get('/', async (c) => {
38
+ router.get('/', requireRole(UserRole.Reader), async (c) => {
37
39
  // We do not need templates in ssg context
38
40
  if (isSSGContext(c)) {
39
41
  return c.json([]);
@@ -78,13 +80,18 @@ router.get('/', async (c) => {
78
80
  * 500:
79
81
  * description: Server error
80
82
  */
81
- router.post('/', zValidator('json', createTemplateSchema), async (c) => {
82
- const commands = c.get('commands');
83
- const { identifier } = c.req.valid('json');
83
+ router.post(
84
+ '/',
85
+ requireRole(UserRole.Admin),
86
+ zValidator('json', createTemplateSchema),
87
+ async (c) => {
88
+ const commands = c.get('commands');
89
+ const { identifier } = c.req.valid('json');
84
90
 
85
- await templateService.createTemplate(commands, identifier);
86
- return c.json({ message: 'Template created successfully' });
87
- });
91
+ await templateService.createTemplate(commands, identifier);
92
+ return c.json({ message: 'Template created successfully' });
93
+ },
94
+ );
88
95
 
89
96
  /**
90
97
  * @swagger
@@ -119,18 +126,23 @@ router.post('/', zValidator('json', createTemplateSchema), async (c) => {
119
126
  * 500:
120
127
  * description: Server error
121
128
  */
122
- router.post('/card', zValidator('json', addTemplateCardSchema), async (c) => {
123
- const commands = c.get('commands');
124
- const { template, cardType, parentKey, count } = c.req.valid('json');
129
+ router.post(
130
+ '/card',
131
+ requireRole(UserRole.Admin),
132
+ zValidator('json', addTemplateCardSchema),
133
+ async (c) => {
134
+ const commands = c.get('commands');
135
+ const { template, cardType, parentKey, count } = c.req.valid('json');
125
136
 
126
- const added = await templateService.addTemplateCard(
127
- commands,
128
- template,
129
- cardType,
130
- parentKey,
131
- count,
132
- );
133
- return c.json({ cards: added });
134
- });
137
+ const added = await templateService.addTemplateCard(
138
+ commands,
139
+ template,
140
+ cardType,
141
+ parentKey,
142
+ count,
143
+ );
144
+ return c.json({ cards: added });
145
+ },
146
+ );
135
147
 
136
148
  export default router;
@@ -15,6 +15,8 @@ import { Hono } from 'hono';
15
15
  import * as treeService from './service.js';
16
16
  import { isSSGContext } from 'hono/ssg';
17
17
  import type { AppContext } from '../../types.js';
18
+ import { UserRole } from '../../types.js';
19
+ import { requireRole } from '../../middleware/auth.js';
18
20
 
19
21
  const router = new Hono();
20
22
 
@@ -32,7 +34,7 @@ const router = new Hono();
32
34
  * 500:
33
35
  * description: project_path not set or other internal error
34
36
  */
35
- router.get('/', async (c: AppContext) => {
37
+ router.get('/', requireRole(UserRole.Reader), async (c: AppContext) => {
36
38
  const commands = c.get('commands');
37
39
  const tree = c.get('tree');
38
40
 
@@ -15,6 +15,8 @@ import { Hono } from 'hono';
15
15
  import * as workflowService from './service.js';
16
16
  import { createWorkflowSchema } from './schema.js';
17
17
  import { zValidator } from '../../middleware/zvalidator.js';
18
+ import { UserRole } from '../../types.js';
19
+ import { requireRole } from '../../middleware/auth.js';
18
20
 
19
21
  const router = new Hono();
20
22
 
@@ -43,12 +45,17 @@ const router = new Hono();
43
45
  * 500:
44
46
  * description: Server error
45
47
  */
46
- router.post('/', zValidator('json', createWorkflowSchema), async (c) => {
47
- const commands = c.get('commands');
48
- const { identifier } = c.req.valid('json');
48
+ router.post(
49
+ '/',
50
+ requireRole(UserRole.Admin),
51
+ zValidator('json', createWorkflowSchema),
52
+ async (c) => {
53
+ const commands = c.get('commands');
54
+ const { identifier } = c.req.valid('json');
49
55
 
50
- await workflowService.createWorkflow(commands, identifier);
51
- return c.json({ message: 'Workflow created successfully' });
52
- });
56
+ await workflowService.createWorkflow(commands, identifier);
57
+ return c.json({ message: 'Workflow created successfully' });
58
+ },
59
+ );
53
60
 
54
61
  export default router;
package/src/export.ts CHANGED
@@ -15,8 +15,9 @@ import path from 'node:path';
15
15
 
16
16
  import fs, { readFile } from 'node:fs/promises';
17
17
 
18
- import { CommandManager } from '@cyberismo/data-handler';
18
+ import type { CommandManager } from '@cyberismo/data-handler';
19
19
  import { createApp } from './app.js';
20
+ import { MockAuthProvider } from './auth/mock.js';
20
21
  import { cp, writeFile } from 'node:fs/promises';
21
22
  import { staticFrontendDirRelative } from './utils.js';
22
23
  import type { QueryResult } from '@cyberismo/data-handler/types/queries';
@@ -41,16 +42,15 @@ export function reset() {
41
42
  /**
42
43
  * Get the card query result for a given card key. Should only be called during
43
44
  * static site generation
44
- * @param projectPath - Path to the project.
45
+ * @param commands - CommandManager instance for the project.
45
46
  * @param cardKey - Key of the card to get the query result for.
46
47
  * @returns The card query result for the given card key.
47
48
  */
48
49
  export async function getCardQueryResult(
49
- projectPath: string,
50
+ commands: CommandManager,
50
51
  cardKey?: string,
51
52
  ): Promise<QueryResult<'card'>[]> {
52
53
  if (!_cardQueryPromise) {
53
- const commands = await CommandManager.getInstance(projectPath);
54
54
  // fetch all cards
55
55
  _cardQueryPromise = commands.project.calculationEngine.runQuery(
56
56
  'card',
@@ -73,20 +73,19 @@ export async function getCardQueryResult(
73
73
  /**
74
74
  * Export the site to a given directory.
75
75
  * Note: Do not call this function in parallel.
76
- * @param projectPath - Path to the project.
76
+ * @param commands - CommandManager instance for the project.
77
+ * @param exportDir - Directory to export to.
77
78
  * @param options - Export options.
78
79
  * @param options.recursive - Whether to export cards recursively.
79
80
  * @param options.cardKey - Key of the card to export. If not provided, all cards will be exported.
80
- * @param exportDir - Directory to export to.
81
81
  * @param level - Log level for the operation.
82
82
  * @param onProgress - Optional progress callback function.
83
83
  * @returns An object containing any errors that occurred during export.
84
84
  */
85
85
  export async function exportSite(
86
- projectPath: string,
86
+ commands: CommandManager,
87
87
  exportDir?: string,
88
88
  options?: TreeOptions,
89
- level?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal',
90
89
  onProgress?: (current: number, total: number) => void,
91
90
  ): Promise<{ errors: string[] }> {
92
91
  exportDir = exportDir || 'static';
@@ -96,7 +95,7 @@ export async function exportSite(
96
95
  ...options,
97
96
  };
98
97
 
99
- const app = createApp(projectPath, opts);
98
+ const app = createApp(new MockAuthProvider(), commands, opts);
100
99
 
101
100
  // copy whole frontend to the same directory
102
101
  await cp(staticFrontendDirRelative, exportDir, { recursive: true });
@@ -109,10 +108,6 @@ export async function exportSite(
109
108
  JSON.stringify(configJson),
110
109
  );
111
110
 
112
- const commands = await CommandManager.getInstance(projectPath, {
113
- logLevel: level,
114
- });
115
-
116
111
  reset();
117
112
  await commands.project.calculationEngine.generate();
118
113
 
@@ -130,6 +125,14 @@ export async function exportSite(
130
125
  concurrency: 5,
131
126
  plugins: [
132
127
  {
128
+ beforeRequestHook: (req) => {
129
+ const url = new URL(req.url);
130
+ // Skip MCP routes — they require session state and are not part of the static site
131
+ if (url.pathname.startsWith('/mcp')) {
132
+ return false;
133
+ }
134
+ return req;
135
+ },
133
136
  afterResponseHook: async (response) => {
134
137
  if (![200, 201, 204].includes(response.status)) {
135
138
  const error = await response.json();
package/src/index.ts CHANGED
@@ -16,8 +16,13 @@ import { Hono } from 'hono';
16
16
  import { serveStatic } from '@hono/node-server/serve-static';
17
17
  import path from 'node:path';
18
18
  import { readFile } from 'node:fs/promises';
19
+ import type { CommandManager } from '@cyberismo/data-handler';
19
20
  import { findFreePort } from './utils.js';
20
21
  import { createApp } from './app.js';
22
+ import type { AuthProvider } from './auth/types.js';
23
+ export { MockAuthProvider } from './auth/mock.js';
24
+ export type { MockUserConfig } from './auth/mock.js';
25
+ export type { AuthProvider } from './auth/types.js';
21
26
  export { exportSite } from './export.js';
22
27
 
23
28
  const DEFAULT_PORT = 3000;
@@ -47,11 +52,13 @@ export async function previewSite(dir: string, findPort: boolean = true) {
47
52
 
48
53
  /**
49
54
  * Start the server
50
- * @param projectPath - Path to the project
55
+ * @param authProvider - Authentication provider
56
+ * @param commands - CommandManager instance for the project
51
57
  * @param findPort - If true, find a free port
52
58
  */
53
59
  export async function startServer(
54
- projectPath?: string,
60
+ authProvider: AuthProvider,
61
+ commands: CommandManager,
55
62
  findPort: boolean = true,
56
63
  ) {
57
64
  let port = parseInt(process.env.PORT || DEFAULT_PORT.toString(), 10);
@@ -59,7 +66,7 @@ export async function startServer(
59
66
  if (findPort) {
60
67
  port = await findFreePort(port, DEFAULT_MAX_PORT);
61
68
  }
62
- const app = createApp(projectPath);
69
+ const app = createApp(authProvider, commands);
63
70
  startApp(app, port);
64
71
  }
65
72