@cyberismo/backend 0.0.16 → 0.0.18
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/dist/app.js +2 -0
- package/dist/app.js.map +1 -1
- package/dist/domain/project/index.d.ts +15 -0
- package/dist/domain/project/index.js +42 -0
- package/dist/domain/project/index.js.map +1 -0
- package/dist/domain/project/schema.d.ts +20 -0
- package/dist/domain/project/schema.js +21 -0
- package/dist/domain/project/schema.js.map +1 -0
- package/dist/domain/project/service.d.ts +30 -0
- package/dist/domain/project/service.js +54 -0
- package/dist/domain/project/service.js.map +1 -0
- package/dist/domain/resources/service.js +60 -31
- package/dist/domain/resources/service.js.map +1 -1
- package/dist/public/THIRD-PARTY.txt +25 -31
- package/dist/public/assets/index-CocN6Fmw.js +163200 -0
- package/dist/public/index.html +1 -1
- package/package.json +11 -5
- package/src/app.ts +2 -0
- package/src/domain/project/index.ts +58 -0
- package/src/domain/project/schema.ts +23 -0
- package/src/domain/project/service.ts +88 -0
- package/src/domain/resources/service.ts +84 -38
- package/dist/public/assets/index-D410yunq.js +0 -163998
package/dist/public/index.html
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
name="msapplication-TileImage"
|
|
12
12
|
content="/cropped-favicon-270x270.png"
|
|
13
13
|
/>
|
|
14
|
-
<script type="module" crossorigin src="/assets/index-
|
|
14
|
+
<script type="module" crossorigin src="/assets/index-CocN6Fmw.js"></script>
|
|
15
15
|
<link rel="stylesheet" crossorigin href="/assets/index-DnK7MBer.css">
|
|
16
16
|
</head>
|
|
17
17
|
<body>
|
package/package.json
CHANGED
|
@@ -1,21 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyberismo/backend",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.18",
|
|
4
4
|
"description": "Express backend for Cyberismo",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"keywords": [],
|
|
7
|
-
"author": "",
|
|
7
|
+
"author": "sami.merila@cyberismo.com",
|
|
8
8
|
"license": "AGPL-3.0",
|
|
9
|
+
"homepage": "https://github.com/CyberismoCom/cyberismo",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/CyberismoCom/cyberismo.git"
|
|
13
|
+
},
|
|
14
|
+
"bugs": "https://github.com/CyberismoCom/cyberismo/issues",
|
|
9
15
|
"dependencies": {
|
|
10
16
|
"@asciidoctor/core": "^3.0.4",
|
|
11
17
|
"@hono/node-server": "^1.19.2",
|
|
12
18
|
"@hono/zod-validator": "^0.7.5",
|
|
13
19
|
"@types/mime-types": "^3.0.1",
|
|
14
20
|
"dotenv": "^17.2.3",
|
|
15
|
-
"hono": "^4.10.
|
|
21
|
+
"hono": "^4.10.7",
|
|
16
22
|
"mime-types": "^3.0.2",
|
|
17
|
-
"zod": "^4.1.
|
|
18
|
-
"@cyberismo/data-handler": "0.0.
|
|
23
|
+
"zod": "^4.1.13",
|
|
24
|
+
"@cyberismo/data-handler": "0.0.18"
|
|
19
25
|
},
|
|
20
26
|
"devDependencies": {
|
|
21
27
|
"@cyberismo/app": "0.0.2"
|
package/src/app.ts
CHANGED
|
@@ -34,6 +34,7 @@ import logicProgramsRouter from './domain/logicPrograms/index.js';
|
|
|
34
34
|
import { isSSGContext } from 'hono/ssg';
|
|
35
35
|
import type { AppVars, TreeOptions } from './types.js';
|
|
36
36
|
import treeMiddleware from './middleware/tree.js';
|
|
37
|
+
import projectRouter from './domain/project/index.js';
|
|
37
38
|
|
|
38
39
|
/**
|
|
39
40
|
* Create the Hono app for the backend
|
|
@@ -70,6 +71,7 @@ export function createApp(projectPath?: string, opts?: TreeOptions) {
|
|
|
70
71
|
app.route('/api/resources', resourcesRouter);
|
|
71
72
|
app.route('/api/logicPrograms', logicProgramsRouter);
|
|
72
73
|
app.route('/api/labels', labelsRouter);
|
|
74
|
+
app.route('/api/project', projectRouter);
|
|
73
75
|
|
|
74
76
|
// serve index.html for all other routes
|
|
75
77
|
app.notFound(async (c) => {
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Cyberismo
|
|
3
|
+
Copyright © Cyberismo Ltd and contributors 2025
|
|
4
|
+
This program is free software: you can redistribute it and/or modify it under
|
|
5
|
+
the terms of the GNU Affero General Public License version 3 as published by
|
|
6
|
+
the Free Software Foundation.
|
|
7
|
+
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
8
|
+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
9
|
+
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
10
|
+
details. You should have received a copy of the GNU Affero General Public
|
|
11
|
+
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { Hono } from 'hono';
|
|
15
|
+
import { zValidator } from '../../middleware/zvalidator.js';
|
|
16
|
+
import { moduleParamSchema, updateProjectSchema } from './schema.js';
|
|
17
|
+
import * as projectService from './service.js';
|
|
18
|
+
|
|
19
|
+
const router = new Hono();
|
|
20
|
+
|
|
21
|
+
router.get('/', async (c) => {
|
|
22
|
+
const commands = c.get('commands');
|
|
23
|
+
|
|
24
|
+
const project = await projectService.getProject(commands);
|
|
25
|
+
return c.json(project);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
router.patch('/', zValidator('json', updateProjectSchema), async (c) => {
|
|
29
|
+
const commands = c.get('commands');
|
|
30
|
+
const updates = c.req.valid('json');
|
|
31
|
+
|
|
32
|
+
const project = await projectService.updateProject(commands, updates);
|
|
33
|
+
return c.json(project);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
router.post(
|
|
37
|
+
'/modules/:module/update',
|
|
38
|
+
zValidator('param', moduleParamSchema),
|
|
39
|
+
async (c) => {
|
|
40
|
+
const commands = c.get('commands');
|
|
41
|
+
const { module } = c.req.valid('param');
|
|
42
|
+
await projectService.updateModule(commands, module);
|
|
43
|
+
return c.json({ message: 'Module updated' });
|
|
44
|
+
},
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
router.delete(
|
|
48
|
+
'/modules/:module',
|
|
49
|
+
zValidator('param', moduleParamSchema),
|
|
50
|
+
async (c) => {
|
|
51
|
+
const commands = c.get('commands');
|
|
52
|
+
const { module } = c.req.valid('param');
|
|
53
|
+
await projectService.deleteModule(commands, module);
|
|
54
|
+
return c.json({ message: 'Module removed' });
|
|
55
|
+
},
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
export default router;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Cyberismo
|
|
3
|
+
Copyright © Cyberismo Ltd and contributors 2025
|
|
4
|
+
This program is free software: you can redistribute it and/or modify it under
|
|
5
|
+
the terms of the GNU Affero General Public License version 3 as published by
|
|
6
|
+
the Free Software Foundation.
|
|
7
|
+
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
8
|
+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
9
|
+
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
10
|
+
details. You should have received a copy of the GNU Affero General Public
|
|
11
|
+
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { z } from 'zod';
|
|
15
|
+
|
|
16
|
+
export const moduleParamSchema = z.object({
|
|
17
|
+
module: z.string().min(1),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export const updateProjectSchema = z.object({
|
|
21
|
+
name: z.string().optional(),
|
|
22
|
+
cardKeyPrefix: z.string().optional(),
|
|
23
|
+
});
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Cyberismo
|
|
3
|
+
Copyright © Cyberismo Ltd and contributors 2025
|
|
4
|
+
This program is free software: you can redistribute it and/or modify it under
|
|
5
|
+
the terms of the GNU Affero General Public License version 3 as published by
|
|
6
|
+
the Free Software Foundation.
|
|
7
|
+
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
8
|
+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
9
|
+
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
10
|
+
details. You should have received a copy of the GNU Affero General Public
|
|
11
|
+
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { type CommandManager } from '@cyberismo/data-handler';
|
|
15
|
+
|
|
16
|
+
export interface ProjectModule {
|
|
17
|
+
name: string;
|
|
18
|
+
cardKeyPrefix: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ProjectInfo {
|
|
22
|
+
name: string;
|
|
23
|
+
cardKeyPrefix: string;
|
|
24
|
+
modules: ProjectModule[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface ProjectUpdatePayload {
|
|
28
|
+
name?: string;
|
|
29
|
+
cardKeyPrefix?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function toModuleInfo(
|
|
33
|
+
commands: CommandManager,
|
|
34
|
+
moduleName: string,
|
|
35
|
+
): Promise<ProjectModule> {
|
|
36
|
+
try {
|
|
37
|
+
const data = await commands.showCmd.showModule(moduleName);
|
|
38
|
+
return {
|
|
39
|
+
name: data.name || moduleName,
|
|
40
|
+
cardKeyPrefix: data.cardKeyPrefix || moduleName,
|
|
41
|
+
};
|
|
42
|
+
} catch {
|
|
43
|
+
return {
|
|
44
|
+
name: moduleName,
|
|
45
|
+
cardKeyPrefix: moduleName,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export async function getProject(
|
|
51
|
+
commands: CommandManager,
|
|
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
|
+
);
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
name: project.name,
|
|
61
|
+
cardKeyPrefix: project.prefix,
|
|
62
|
+
modules: moduleDetails,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export async function updateProject(
|
|
67
|
+
commands: CommandManager,
|
|
68
|
+
updates: ProjectUpdatePayload,
|
|
69
|
+
): Promise<ProjectInfo> {
|
|
70
|
+
const { name, cardKeyPrefix } = updates;
|
|
71
|
+
|
|
72
|
+
if (cardKeyPrefix) {
|
|
73
|
+
await commands.renameCmd.rename(cardKeyPrefix);
|
|
74
|
+
}
|
|
75
|
+
if (name) {
|
|
76
|
+
await commands.project.configuration.setProjectName(name);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return getProject(commands);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export async function updateModule(commands: CommandManager, module: string) {
|
|
83
|
+
await commands.importCmd.updateModule(module);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export async function deleteModule(commands: CommandManager, module: string) {
|
|
87
|
+
await commands.removeCmd.remove('module', module);
|
|
88
|
+
}
|
|
@@ -40,12 +40,51 @@ const resourceTypes: ResourceFolderType[] = [
|
|
|
40
40
|
'workflows',
|
|
41
41
|
];
|
|
42
42
|
|
|
43
|
+
async function getModules(commands: CommandManager) {
|
|
44
|
+
try {
|
|
45
|
+
const moduleNames = commands.showCmd.showModules();
|
|
46
|
+
return Promise.all(
|
|
47
|
+
moduleNames.map(async (moduleName) => {
|
|
48
|
+
try {
|
|
49
|
+
const module = await commands.showCmd.showModule(moduleName);
|
|
50
|
+
return { name: module.name, cardKeyPrefix: module.cardKeyPrefix };
|
|
51
|
+
} catch (error) {
|
|
52
|
+
return { name: moduleName, cardKeyPrefix: moduleName };
|
|
53
|
+
}
|
|
54
|
+
}),
|
|
55
|
+
);
|
|
56
|
+
} catch {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
43
61
|
export async function buildResourceTree(commands: CommandManager) {
|
|
44
62
|
const project = await commands.showCmd.showProject();
|
|
45
63
|
const tree: unknown[] = [];
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
64
|
+
|
|
65
|
+
const sortByDisplayName = (
|
|
66
|
+
nodes: { data: { displayName: string; name: string } }[],
|
|
67
|
+
) =>
|
|
68
|
+
nodes.sort((a, b) =>
|
|
69
|
+
(a.data.displayName || a.data.name.split('/')[2] || '').localeCompare(
|
|
70
|
+
b.data.displayName || b.data.name.split('/')[2] || '',
|
|
71
|
+
),
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const modules = await getModules(commands);
|
|
75
|
+
|
|
76
|
+
// General section first (single node with project + modules metadata)
|
|
77
|
+
tree.push({
|
|
78
|
+
id: 'general-project',
|
|
79
|
+
type: 'general',
|
|
80
|
+
name: 'project',
|
|
81
|
+
data: {
|
|
82
|
+
name: project.name,
|
|
83
|
+
cardKeyPrefix: project.prefix,
|
|
84
|
+
modules,
|
|
85
|
+
},
|
|
86
|
+
readOnly: false,
|
|
87
|
+
});
|
|
49
88
|
|
|
50
89
|
// Process each resource type
|
|
51
90
|
for (const resourceType of resourceTypes) {
|
|
@@ -65,47 +104,54 @@ export async function buildResourceTree(commands: CommandManager) {
|
|
|
65
104
|
));
|
|
66
105
|
}
|
|
67
106
|
|
|
68
|
-
//
|
|
69
|
-
|
|
107
|
+
// Sort resources by display name if present
|
|
108
|
+
sortByDisplayName(
|
|
109
|
+
rootResources as { data: { displayName: string; name: string } }[],
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
Object.values(moduleResources).forEach((resources) =>
|
|
113
|
+
sortByDisplayName(
|
|
114
|
+
resources as { data: { displayName: string; name: string } }[],
|
|
115
|
+
),
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
const projectNode =
|
|
119
|
+
rootResources.length > 0
|
|
120
|
+
? [
|
|
121
|
+
{
|
|
122
|
+
id: `${resourceType}-project`,
|
|
123
|
+
type: 'module',
|
|
124
|
+
name: 'project',
|
|
125
|
+
children: rootResources,
|
|
126
|
+
readOnly: false,
|
|
127
|
+
},
|
|
128
|
+
]
|
|
129
|
+
: [];
|
|
130
|
+
|
|
131
|
+
const moduleNodes = Object.entries(moduleResources)
|
|
132
|
+
.map(([prefix, resources]) => ({
|
|
133
|
+
id: `${resourceType}-module-${prefix}`,
|
|
134
|
+
type: 'module',
|
|
135
|
+
name:
|
|
136
|
+
modules.find((module) => module.cardKeyPrefix === prefix)?.name ||
|
|
137
|
+
prefix,
|
|
138
|
+
prefix,
|
|
139
|
+
children: resources,
|
|
140
|
+
readOnly: true,
|
|
141
|
+
}))
|
|
142
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
143
|
+
|
|
144
|
+
const allResources = [...projectNode, ...moduleNodes];
|
|
145
|
+
|
|
146
|
+
// Add combined resources (project + modules nested under module nodes) under the same group
|
|
147
|
+
if (allResources.length > 0) {
|
|
70
148
|
tree.push({
|
|
71
149
|
id: resourceType,
|
|
72
150
|
type: 'resourceGroup',
|
|
73
151
|
name: resourceType,
|
|
74
|
-
children:
|
|
152
|
+
children: allResources,
|
|
75
153
|
});
|
|
76
154
|
}
|
|
77
|
-
|
|
78
|
-
// Collect module resources
|
|
79
|
-
Object.entries(moduleResources).forEach(([prefix, resources]) => {
|
|
80
|
-
if (!allModuleResources[prefix]) {
|
|
81
|
-
allModuleResources[prefix] = {};
|
|
82
|
-
}
|
|
83
|
-
allModuleResources[prefix][resourceType] = resources;
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Build modules section
|
|
88
|
-
if (Object.keys(allModuleResources).length > 0) {
|
|
89
|
-
const modules = Object.entries(allModuleResources).map(
|
|
90
|
-
([prefix, resourcesByType]) => ({
|
|
91
|
-
id: `modules-${prefix}`,
|
|
92
|
-
type: 'module',
|
|
93
|
-
name: prefix,
|
|
94
|
-
children: Object.entries(resourcesByType).map(([type, resources]) => ({
|
|
95
|
-
id: `modules-${prefix}-${type}`,
|
|
96
|
-
type: 'resourceGroup',
|
|
97
|
-
name: type,
|
|
98
|
-
children: resources,
|
|
99
|
-
})),
|
|
100
|
-
}),
|
|
101
|
-
);
|
|
102
|
-
|
|
103
|
-
tree.push({
|
|
104
|
-
id: 'modules',
|
|
105
|
-
type: 'modulesGroup',
|
|
106
|
-
name: 'modules',
|
|
107
|
-
children: modules,
|
|
108
|
-
});
|
|
109
155
|
}
|
|
110
156
|
|
|
111
157
|
return tree;
|