@geode/opengeodeweb-front 10.35.0 → 10.36.0-rc.2
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/.build/opengeodeweb_front_schemas.js +200 -21
- package/.build/server/utils/typed_handler.js +63 -0
- package/.build/shared/utils/validate_schema.js +2 -1
- package/app/components/CrsSelector.vue +5 -5
- package/app/components/ExtensionSelector.vue +6 -12
- package/app/components/FileSelector.vue +2 -4
- package/app/components/MissingFilesSelector.vue +1 -1
- package/app/components/ObjectSelector.vue +1 -1
- package/app/components/ThresholdFilter.vue +1 -1
- package/app/components/Viewer/Generic/Model/BlocksOptions.vue +1 -1
- package/app/components/Viewer/Generic/Model/CornersOptions.vue +1 -1
- package/app/components/Viewer/Generic/Model/LinesOptions.vue +1 -1
- package/app/components/Viewer/Generic/Model/SurfacesOptions.vue +1 -1
- package/app/components/Viewer/Options/ColoringTypeSelector.vue +1 -1
- package/app/components/Viewer/Options/TextureItem.vue +5 -7
- package/app/composables/global_attribute_style.ts +1 -1
- package/app/composables/project_manager.ts +1 -1
- package/app/stores/app.ts +19 -17
- package/app/stores/back.ts +27 -21
- package/app/stores/cloud.ts +1 -1
- package/app/stores/infra.ts +1 -1
- package/app/stores/viewer.ts +4 -6
- package/app/utils/extension.ts +4 -4
- package/app/utils/import_workflow.ts +1 -1
- package/internal/stores/hybrid_viewer/base64.ts +6 -0
- package/internal/stores/hybrid_viewer/scene.ts +5 -1
- package/internal/utils/api_fetch.ts +9 -8
- package/opengeodeweb_front_schemas.json +252 -19
- package/opengeodeweb_front_typed_schemas.d.ts +225 -0
- package/opengeodeweb_front_typed_schemas.js +4 -0
- package/package.json +7 -5
- package/server/api/cloud/extensions/run.post.ts +9 -21
- package/server/api/cloud/extensions/schemas/run.json +42 -3
- package/server/api/local/app/kill.post.ts +4 -2
- package/server/api/local/app/project_folder_path.post.ts +6 -22
- package/server/api/local/app/run_back.post.ts +8 -23
- package/server/api/local/app/run_viewer.post.ts +8 -23
- package/server/api/local/app/schemas/kill.json +7 -1
- package/server/api/local/app/schemas/project_folder_path.json +19 -2
- package/server/api/local/app/schemas/run_back.json +31 -4
- package/server/api/local/app/schemas/run_viewer.json +31 -4
- package/server/api/local/extensions/kill.post.ts +8 -23
- package/server/api/local/extensions/run.post.ts +8 -22
- package/server/api/local/extensions/schemas/kill.json +20 -4
- package/server/api/local/extensions/schemas/run.json +42 -3
- package/server/api/local/extensions/schemas/upload.json +11 -1
- package/server/api/local/extensions/upload.put.ts +37 -29
- package/server/api/microservice/app/get_is_app_ready.get.ts +7 -13
- package/server/api/microservice/app/schemas/get_is_app_ready.json +14 -1
- package/server/api/microservice/app/schemas/set_app_base_url.json +17 -2
- package/server/api/microservice/app/schemas/set_back_base_url.json +17 -2
- package/server/api/microservice/app/schemas/set_is_app_ready.json +17 -2
- package/server/api/microservice/app/schemas/set_viewer_base_url.json +17 -2
- package/server/api/microservice/app/set_app_base_url.post.ts +8 -17
- package/server/api/microservice/app/set_back_base_url.post.ts +8 -16
- package/server/api/microservice/app/set_is_app_ready.post.ts +8 -17
- package/server/api/microservice/app/set_viewer_base_url.post.ts +8 -16
- package/server/api/microservice/extensions/download.post.ts +8 -21
- package/server/api/microservice/extensions/schemas/download.json +21 -4
- package/server/utils/typed_handler.ts +114 -0
- package/shared/utils/types.ts +18 -3
- package/shared/utils/validate_schema.ts +1 -1
|
@@ -3,9 +3,48 @@
|
|
|
3
3
|
"methods": ["POST"],
|
|
4
4
|
"type": "object",
|
|
5
5
|
"properties": {
|
|
6
|
-
"projectFolderPath": {
|
|
7
|
-
|
|
6
|
+
"projectFolderPath": {
|
|
7
|
+
"type": "string"
|
|
8
|
+
},
|
|
9
|
+
"projectName": {
|
|
10
|
+
"type": "string"
|
|
11
|
+
}
|
|
8
12
|
},
|
|
9
13
|
"required": ["projectFolderPath", "projectName"],
|
|
10
|
-
"additionalProperties": false
|
|
14
|
+
"additionalProperties": false,
|
|
15
|
+
"response": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"properties": {
|
|
18
|
+
"statusCode": {
|
|
19
|
+
"type": "integer"
|
|
20
|
+
},
|
|
21
|
+
"extensionsArray": {
|
|
22
|
+
"type": "array",
|
|
23
|
+
"items": {
|
|
24
|
+
"type": "object",
|
|
25
|
+
"properties": {
|
|
26
|
+
"id": {
|
|
27
|
+
"type": "string"
|
|
28
|
+
},
|
|
29
|
+
"name": {
|
|
30
|
+
"type": "string"
|
|
31
|
+
},
|
|
32
|
+
"version": {
|
|
33
|
+
"type": "string"
|
|
34
|
+
},
|
|
35
|
+
"frontendContent": {
|
|
36
|
+
"type": "string"
|
|
37
|
+
},
|
|
38
|
+
"port": {
|
|
39
|
+
"type": "integer"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"required": ["id", "name", "version", "frontendContent", "port"],
|
|
43
|
+
"additionalProperties": false
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"required": ["statusCode", "extensionsArray"],
|
|
48
|
+
"additionalProperties": false
|
|
49
|
+
}
|
|
11
50
|
}
|
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
// Third party imports
|
|
4
4
|
import { consola } from "consola";
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
import { defineTypedEventHandler } from "@geode/opengeodeweb-front/server/utils/typed_handler.ts";
|
|
7
|
+
import schemas from "@geode/opengeodeweb-front/opengeodeweb_front_typed_schemas.js";
|
|
6
8
|
|
|
7
9
|
// Local imports
|
|
8
10
|
|
|
9
|
-
export default
|
|
11
|
+
export default defineTypedEventHandler(schemas.api.local.app.kill, () => {
|
|
10
12
|
consola.info("Killing node server process");
|
|
11
13
|
// oxlint-disable-next-line no-process-exit
|
|
12
14
|
process.exit();
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
// Node imports
|
|
2
2
|
|
|
3
3
|
// Third party imports
|
|
4
|
-
import { type H3Event, createError, defineEventHandler, readBody } from "h3";
|
|
5
|
-
import { consola } from "consola";
|
|
6
4
|
|
|
7
5
|
// Local imports
|
|
8
6
|
import {
|
|
@@ -10,25 +8,11 @@ import {
|
|
|
10
8
|
generateProjectFolderPath,
|
|
11
9
|
} from "@geode/opengeodeweb-front/server/utils/path.ts";
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
11
|
+
import { defineTypedEventHandler } from "@geode/opengeodeweb-front/server/utils/typed_handler.ts";
|
|
12
|
+
import schemas from "@geode/opengeodeweb-front/opengeodeweb_front_typed_schemas.js";
|
|
16
13
|
|
|
17
|
-
export default
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
createPath(projectFolderPath);
|
|
22
|
-
|
|
23
|
-
return {
|
|
24
|
-
statusCode: 200,
|
|
25
|
-
projectFolderPath,
|
|
26
|
-
};
|
|
27
|
-
} catch (error) {
|
|
28
|
-
consola.error(error);
|
|
29
|
-
throw createError({
|
|
30
|
-
statusCode: 500,
|
|
31
|
-
statusMessage: error instanceof Error ? error.message : String(error),
|
|
32
|
-
});
|
|
33
|
-
}
|
|
14
|
+
export default defineTypedEventHandler(schemas.api.local.app.project_folder_path, ({ PROJECT }) => {
|
|
15
|
+
const projectFolderPath = generateProjectFolderPath(PROJECT);
|
|
16
|
+
createPath(projectFolderPath);
|
|
17
|
+
return { statusCode: 200, projectFolderPath };
|
|
34
18
|
});
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
// Node imports
|
|
2
2
|
|
|
3
3
|
// Third party imports
|
|
4
|
-
import { type H3Event, createError, defineEventHandler, readBody } from "h3";
|
|
5
|
-
import { consola } from "consola";
|
|
6
4
|
|
|
7
5
|
// Local imports
|
|
8
6
|
import {
|
|
@@ -10,31 +8,18 @@ import {
|
|
|
10
8
|
runBack,
|
|
11
9
|
} from "@geode/opengeodeweb-front/server/utils/microservices.ts";
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
NUXT_ROOT_PATH: string;
|
|
16
|
-
args: { projectFolderPath: string; [key: string]: unknown };
|
|
17
|
-
}
|
|
11
|
+
import { defineTypedEventHandler } from "@geode/opengeodeweb-front/server/utils/typed_handler.ts";
|
|
12
|
+
import schemas from "@geode/opengeodeweb-front/opengeodeweb_front_typed_schemas.js";
|
|
18
13
|
|
|
19
|
-
export default
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
export default defineTypedEventHandler(
|
|
15
|
+
schemas.api.local.app.run_back,
|
|
16
|
+
async ({ COMMAND_BACK, NUXT_ROOT_PATH, args }) => {
|
|
22
17
|
const port = await runBack(COMMAND_BACK, NUXT_ROOT_PATH, args);
|
|
23
18
|
addMicroserviceMetadatas(args.projectFolderPath, {
|
|
24
19
|
type: "back",
|
|
25
20
|
name: COMMAND_BACK,
|
|
26
21
|
port,
|
|
27
22
|
});
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
port,
|
|
32
|
-
};
|
|
33
|
-
} catch (error) {
|
|
34
|
-
consola.error(error);
|
|
35
|
-
throw createError({
|
|
36
|
-
statusCode: 500,
|
|
37
|
-
statusMessage: error instanceof Error ? error.message : String(error),
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
});
|
|
23
|
+
return { statusCode: 200, port };
|
|
24
|
+
},
|
|
25
|
+
);
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
// Node imports
|
|
2
2
|
|
|
3
3
|
// Third party imports
|
|
4
|
-
import { type H3Event, createError, defineEventHandler, readBody } from "h3";
|
|
5
|
-
import { consola } from "consola";
|
|
6
4
|
|
|
7
5
|
// Local imports
|
|
8
6
|
import {
|
|
@@ -10,31 +8,18 @@ import {
|
|
|
10
8
|
runViewer,
|
|
11
9
|
} from "@geode/opengeodeweb-front/server/utils/microservices.ts";
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
NUXT_ROOT_PATH: string;
|
|
16
|
-
args: { projectFolderPath: string; [key: string]: unknown };
|
|
17
|
-
}
|
|
11
|
+
import { defineTypedEventHandler } from "@geode/opengeodeweb-front/server/utils/typed_handler.ts";
|
|
12
|
+
import schemas from "@geode/opengeodeweb-front/opengeodeweb_front_typed_schemas.js";
|
|
18
13
|
|
|
19
|
-
export default
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
export default defineTypedEventHandler(
|
|
15
|
+
schemas.api.local.app.run_viewer,
|
|
16
|
+
async ({ COMMAND_VIEWER, NUXT_ROOT_PATH, args }) => {
|
|
22
17
|
const port = await runViewer(COMMAND_VIEWER, NUXT_ROOT_PATH, args);
|
|
23
18
|
addMicroserviceMetadatas(args.projectFolderPath, {
|
|
24
19
|
type: "viewer",
|
|
25
20
|
name: COMMAND_VIEWER,
|
|
26
21
|
port,
|
|
27
22
|
});
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
port,
|
|
32
|
-
};
|
|
33
|
-
} catch (error) {
|
|
34
|
-
consola.error(error);
|
|
35
|
-
throw createError({
|
|
36
|
-
statusCode: 500,
|
|
37
|
-
statusMessage: error instanceof Error ? error.message : String(error),
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
});
|
|
23
|
+
return { statusCode: 200, port };
|
|
24
|
+
},
|
|
25
|
+
);
|
|
@@ -2,7 +2,24 @@
|
|
|
2
2
|
"route": "/project_folder_path",
|
|
3
3
|
"methods": ["POST"],
|
|
4
4
|
"type": "object",
|
|
5
|
-
"properties": {
|
|
5
|
+
"properties": {
|
|
6
|
+
"PROJECT": {
|
|
7
|
+
"type": "string"
|
|
8
|
+
}
|
|
9
|
+
},
|
|
6
10
|
"required": ["PROJECT"],
|
|
7
|
-
"additionalProperties": true
|
|
11
|
+
"additionalProperties": true,
|
|
12
|
+
"response": {
|
|
13
|
+
"type": "object",
|
|
14
|
+
"properties": {
|
|
15
|
+
"statusCode": {
|
|
16
|
+
"type": "integer"
|
|
17
|
+
},
|
|
18
|
+
"projectFolderPath": {
|
|
19
|
+
"type": "string"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"required": ["statusCode", "projectFolderPath"],
|
|
23
|
+
"additionalProperties": false
|
|
24
|
+
}
|
|
8
25
|
}
|
|
@@ -3,9 +3,36 @@
|
|
|
3
3
|
"methods": ["POST"],
|
|
4
4
|
"type": "object",
|
|
5
5
|
"properties": {
|
|
6
|
-
"COMMAND_BACK": {
|
|
7
|
-
|
|
6
|
+
"COMMAND_BACK": {
|
|
7
|
+
"type": "string"
|
|
8
|
+
},
|
|
9
|
+
"NUXT_ROOT_PATH": {
|
|
10
|
+
"type": "string"
|
|
11
|
+
},
|
|
12
|
+
"args": {
|
|
13
|
+
"type": "object",
|
|
14
|
+
"properties": {
|
|
15
|
+
"projectFolderPath": {
|
|
16
|
+
"type": "string"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"required": ["projectFolderPath"],
|
|
20
|
+
"additionalProperties": true
|
|
21
|
+
}
|
|
8
22
|
},
|
|
9
|
-
"required": ["COMMAND_BACK", "NUXT_ROOT_PATH"],
|
|
10
|
-
"additionalProperties": true
|
|
23
|
+
"required": ["COMMAND_BACK", "NUXT_ROOT_PATH", "args"],
|
|
24
|
+
"additionalProperties": true,
|
|
25
|
+
"response": {
|
|
26
|
+
"type": "object",
|
|
27
|
+
"properties": {
|
|
28
|
+
"statusCode": {
|
|
29
|
+
"type": "integer"
|
|
30
|
+
},
|
|
31
|
+
"port": {
|
|
32
|
+
"type": "integer"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"required": ["statusCode", "port"],
|
|
36
|
+
"additionalProperties": false
|
|
37
|
+
}
|
|
11
38
|
}
|
|
@@ -3,9 +3,36 @@
|
|
|
3
3
|
"methods": ["POST"],
|
|
4
4
|
"type": "object",
|
|
5
5
|
"properties": {
|
|
6
|
-
"COMMAND_VIEWER": {
|
|
7
|
-
|
|
6
|
+
"COMMAND_VIEWER": {
|
|
7
|
+
"type": "string"
|
|
8
|
+
},
|
|
9
|
+
"NUXT_ROOT_PATH": {
|
|
10
|
+
"type": "string"
|
|
11
|
+
},
|
|
12
|
+
"args": {
|
|
13
|
+
"type": "object",
|
|
14
|
+
"properties": {
|
|
15
|
+
"projectFolderPath": {
|
|
16
|
+
"type": "string"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"required": ["projectFolderPath"],
|
|
20
|
+
"additionalProperties": true
|
|
21
|
+
}
|
|
8
22
|
},
|
|
9
|
-
"required": ["COMMAND_VIEWER", "NUXT_ROOT_PATH"],
|
|
10
|
-
"additionalProperties": true
|
|
23
|
+
"required": ["COMMAND_VIEWER", "NUXT_ROOT_PATH", "args"],
|
|
24
|
+
"additionalProperties": true,
|
|
25
|
+
"response": {
|
|
26
|
+
"type": "object",
|
|
27
|
+
"properties": {
|
|
28
|
+
"statusCode": {
|
|
29
|
+
"type": "integer"
|
|
30
|
+
},
|
|
31
|
+
"port": {
|
|
32
|
+
"type": "integer"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"required": ["statusCode", "port"],
|
|
36
|
+
"additionalProperties": false
|
|
37
|
+
}
|
|
11
38
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Node imports
|
|
2
2
|
|
|
3
3
|
// Third party imports
|
|
4
|
-
import { type H3Event, createError, defineEventHandler, readBody } from "h3";
|
|
5
4
|
import { consola } from "consola";
|
|
6
5
|
|
|
7
6
|
// Local imports
|
|
@@ -14,17 +13,12 @@ import {
|
|
|
14
13
|
import { extensionFolderPath } from "@geode/opengeodeweb-front/server/utils/path.ts";
|
|
15
14
|
import { removeExtensionFromConf } from "@geode/opengeodeweb-front/server/utils/app_config.ts";
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
projectName: string;
|
|
20
|
-
extensionId: string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export default defineEventHandler(async (event: H3Event) => {
|
|
24
|
-
try {
|
|
25
|
-
const body = await readBody<KillExtensionBody>(event);
|
|
26
|
-
const { projectFolderPath, projectName, extensionId } = body;
|
|
16
|
+
import { defineTypedEventHandler } from "@geode/opengeodeweb-front/server/utils/typed_handler.ts";
|
|
17
|
+
import schemas from "@geode/opengeodeweb-front/opengeodeweb_front_typed_schemas.js";
|
|
27
18
|
|
|
19
|
+
export default defineTypedEventHandler(
|
|
20
|
+
schemas.api.local.extensions.kill,
|
|
21
|
+
async ({ projectFolderPath, projectName, extensionId }) => {
|
|
28
22
|
consola.debug({ projectFolderPath, projectName, extensionId });
|
|
29
23
|
|
|
30
24
|
const microservices = projectMicroservices(projectFolderPath);
|
|
@@ -37,15 +31,6 @@ export default defineEventHandler(async (event: H3Event) => {
|
|
|
37
31
|
await killMicroservice(microservice);
|
|
38
32
|
await deleteFolderRecursive(extensionFolderPath(projectFolderPath, extensionId));
|
|
39
33
|
|
|
40
|
-
return {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
} catch (error) {
|
|
44
|
-
consola.error("Error killing extension:", error);
|
|
45
|
-
throw createError({
|
|
46
|
-
statusCode: 500,
|
|
47
|
-
|
|
48
|
-
statusMessage: error instanceof Error ? error.message : String(error),
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
});
|
|
34
|
+
return { statusCode: 200 };
|
|
35
|
+
},
|
|
36
|
+
);
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
|
|
4
4
|
// Third party imports
|
|
5
|
-
import { type H3Event, createError, defineEventHandler, readBody } from "h3";
|
|
6
|
-
import { consola } from "consola";
|
|
7
5
|
|
|
8
6
|
// Local imports
|
|
9
7
|
import {
|
|
@@ -21,14 +19,12 @@ import {
|
|
|
21
19
|
import { extensionsConf } from "@geode/opengeodeweb-front/server/utils/app_config.ts";
|
|
22
20
|
import { unzipFile } from "@geode/opengeodeweb-front/server/utils/server.ts";
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
projectName: string;
|
|
27
|
-
}
|
|
22
|
+
import { defineTypedEventHandler } from "@geode/opengeodeweb-front/server/utils/typed_handler.ts";
|
|
23
|
+
import schemas from "@geode/opengeodeweb-front/opengeodeweb_front_typed_schemas.js";
|
|
28
24
|
|
|
29
|
-
export default
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
export default defineTypedEventHandler(
|
|
26
|
+
schemas.api.local.extensions.run,
|
|
27
|
+
async ({ projectFolderPath, projectName }) => {
|
|
32
28
|
const extensionsConfig = extensionsConf(projectName);
|
|
33
29
|
const extensionsArray = await Promise.all(
|
|
34
30
|
Object.entries(extensionsConfig).map(async ([extensionId, { path: extensionPath }]) => {
|
|
@@ -62,16 +58,6 @@ export default defineEventHandler(async (event: H3Event) => {
|
|
|
62
58
|
}),
|
|
63
59
|
);
|
|
64
60
|
|
|
65
|
-
return {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
};
|
|
69
|
-
} catch (error) {
|
|
70
|
-
consola.error("Error running extensions:", error);
|
|
71
|
-
throw createError({
|
|
72
|
-
statusCode: 500,
|
|
73
|
-
|
|
74
|
-
statusMessage: error instanceof Error ? error.message : String(error),
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
});
|
|
61
|
+
return { statusCode: 200, extensionsArray };
|
|
62
|
+
},
|
|
63
|
+
);
|
|
@@ -3,10 +3,26 @@
|
|
|
3
3
|
"methods": ["POST"],
|
|
4
4
|
"type": "object",
|
|
5
5
|
"properties": {
|
|
6
|
-
"extensionId": {
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
"extensionId": {
|
|
7
|
+
"type": "string"
|
|
8
|
+
},
|
|
9
|
+
"projectFolderPath": {
|
|
10
|
+
"type": "string"
|
|
11
|
+
},
|
|
12
|
+
"projectName": {
|
|
13
|
+
"type": "string"
|
|
14
|
+
}
|
|
9
15
|
},
|
|
10
16
|
"required": ["extensionId", "projectFolderPath", "projectName"],
|
|
11
|
-
"additionalProperties": false
|
|
17
|
+
"additionalProperties": false,
|
|
18
|
+
"response": {
|
|
19
|
+
"type": "object",
|
|
20
|
+
"properties": {
|
|
21
|
+
"statusCode": {
|
|
22
|
+
"type": "integer"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"required": ["statusCode"],
|
|
26
|
+
"additionalProperties": false
|
|
27
|
+
}
|
|
12
28
|
}
|
|
@@ -3,9 +3,48 @@
|
|
|
3
3
|
"methods": ["POST"],
|
|
4
4
|
"type": "object",
|
|
5
5
|
"properties": {
|
|
6
|
-
"projectFolderPath": {
|
|
7
|
-
|
|
6
|
+
"projectFolderPath": {
|
|
7
|
+
"type": "string"
|
|
8
|
+
},
|
|
9
|
+
"projectName": {
|
|
10
|
+
"type": "string"
|
|
11
|
+
}
|
|
8
12
|
},
|
|
9
13
|
"required": ["projectFolderPath", "projectName"],
|
|
10
|
-
"additionalProperties": false
|
|
14
|
+
"additionalProperties": false,
|
|
15
|
+
"response": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"properties": {
|
|
18
|
+
"statusCode": {
|
|
19
|
+
"type": "integer"
|
|
20
|
+
},
|
|
21
|
+
"extensionsArray": {
|
|
22
|
+
"type": "array",
|
|
23
|
+
"items": {
|
|
24
|
+
"type": "object",
|
|
25
|
+
"properties": {
|
|
26
|
+
"id": {
|
|
27
|
+
"type": "string"
|
|
28
|
+
},
|
|
29
|
+
"name": {
|
|
30
|
+
"type": "string"
|
|
31
|
+
},
|
|
32
|
+
"version": {
|
|
33
|
+
"type": "string"
|
|
34
|
+
},
|
|
35
|
+
"frontendContent": {
|
|
36
|
+
"type": "string"
|
|
37
|
+
},
|
|
38
|
+
"port": {
|
|
39
|
+
"type": "integer"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"required": ["id", "name", "version", "frontendContent", "port"],
|
|
43
|
+
"additionalProperties": false
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"required": ["statusCode", "extensionsArray"],
|
|
48
|
+
"additionalProperties": false
|
|
49
|
+
}
|
|
11
50
|
}
|
|
@@ -8,5 +8,15 @@
|
|
|
8
8
|
"minLength": 1
|
|
9
9
|
}
|
|
10
10
|
},
|
|
11
|
-
"additionalProperties": false
|
|
11
|
+
"additionalProperties": false,
|
|
12
|
+
"response": {
|
|
13
|
+
"type": "object",
|
|
14
|
+
"properties": {
|
|
15
|
+
"statusCode": {
|
|
16
|
+
"type": "integer"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"required": ["statusCode"],
|
|
20
|
+
"additionalProperties": false
|
|
21
|
+
}
|
|
12
22
|
}
|
|
@@ -4,7 +4,7 @@ import fs from "node:fs";
|
|
|
4
4
|
import { pipeline } from "node:stream/promises";
|
|
5
5
|
|
|
6
6
|
// Third party imports
|
|
7
|
-
import { type H3Event, createError,
|
|
7
|
+
import { type H3Event, createError, getQuery, getRequestWebStream } from "h3";
|
|
8
8
|
|
|
9
9
|
// Local imports
|
|
10
10
|
import {
|
|
@@ -14,6 +14,11 @@ import {
|
|
|
14
14
|
import { BYTES_PER_KIBIBYTE } from "@ogw_shared/utils/file.js";
|
|
15
15
|
import { toNodeWebStream } from "@geode/opengeodeweb-front/server/utils/stream.ts";
|
|
16
16
|
|
|
17
|
+
import schemas, {
|
|
18
|
+
type LocalExtensionsUploadResponse,
|
|
19
|
+
} from "@geode/opengeodeweb-front/opengeodeweb_front_typed_schemas.js";
|
|
20
|
+
import { defineRawEventHandler } from "@geode/opengeodeweb-front/server/utils/typed_handler.ts";
|
|
21
|
+
|
|
17
22
|
const CODE_200 = 200;
|
|
18
23
|
const CODE_201 = 201;
|
|
19
24
|
const MAX_FILE_MEGABYTES = 500;
|
|
@@ -36,36 +41,39 @@ function requiredQueryInt(event: H3Event, key: string): number {
|
|
|
36
41
|
}
|
|
37
42
|
|
|
38
43
|
// The file is sent as a raw (non-multipart) body, split into sequential chunks the client uploads in order (see OpenGeodeWeb-Front's upload_file.ts and OpenGeodeWeb-Back's upload_file route, which use the same protocol). Each chunk is appended to a `.part` file; the last one triggers the existing zip-metadata registration.
|
|
39
|
-
export default
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
export default defineRawEventHandler(
|
|
45
|
+
schemas.api.local.extensions.upload,
|
|
46
|
+
async (event: H3Event): Promise<LocalExtensionsUploadResponse> => {
|
|
47
|
+
const projectName = requiredQueryString(event, "projectName");
|
|
48
|
+
const filename = requiredQueryString(event, "filename");
|
|
49
|
+
const totalChunks = requiredQueryInt(event, "total_chunks");
|
|
50
|
+
const chunkIndex = requiredQueryInt(event, "chunk_index");
|
|
51
|
+
if (chunkIndex >= totalChunks) {
|
|
52
|
+
throw createError({ statusCode: 400, message: "chunk_index must be less than total_chunks" });
|
|
53
|
+
}
|
|
47
54
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
const webStream = getRequestWebStream(event);
|
|
56
|
+
if (!webStream) {
|
|
57
|
+
throw createError({ statusCode: 400, message: "No request body received" });
|
|
58
|
+
}
|
|
52
59
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
60
|
+
const targetPath = targetExtensionFilePath(projectName, filename);
|
|
61
|
+
const partPath = `${targetPath}.part`;
|
|
62
|
+
const writeStream = fs.createWriteStream(partPath, { flags: chunkIndex === 0 ? "w" : "a" });
|
|
63
|
+
await pipeline(Readable.fromWeb(toNodeWebStream(webStream)), writeStream);
|
|
57
64
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
65
|
+
const { size } = await fs.promises.stat(partPath);
|
|
66
|
+
if (size > FILE_SIZE_LIMIT) {
|
|
67
|
+
await fs.promises.unlink(partPath);
|
|
68
|
+
throw createError({ statusCode: 400, message: "File too large" });
|
|
69
|
+
}
|
|
63
70
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
71
|
+
if (chunkIndex < totalChunks - 1) {
|
|
72
|
+
return { statusCode: CODE_200 };
|
|
73
|
+
}
|
|
67
74
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
75
|
+
await fs.promises.rename(partPath, targetPath);
|
|
76
|
+
await registerExtensionFile(projectName, targetPath);
|
|
77
|
+
return { statusCode: CODE_201 };
|
|
78
|
+
},
|
|
79
|
+
);
|
|
@@ -1,20 +1,14 @@
|
|
|
1
1
|
// Third party imports
|
|
2
|
-
import { createError, defineEventHandler } from "h3";
|
|
3
2
|
import { consola } from "consola";
|
|
4
3
|
|
|
5
4
|
// Local imports
|
|
6
5
|
import { getIsAppReady } from "@geode/opengeodeweb-front/server/utils/server_config.ts";
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
throw createError({
|
|
16
|
-
statusCode: 500,
|
|
17
|
-
statusMessage: error instanceof Error ? error.message : String(error),
|
|
18
|
-
});
|
|
19
|
-
}
|
|
7
|
+
import { defineTypedEventHandler } from "@geode/opengeodeweb-front/server/utils/typed_handler.ts";
|
|
8
|
+
import schemas from "@geode/opengeodeweb-front/opengeodeweb_front_typed_schemas.js";
|
|
9
|
+
|
|
10
|
+
export default defineTypedEventHandler(schemas.api.microservice.app.get_is_app_ready, () => {
|
|
11
|
+
const isReady = getIsAppReady();
|
|
12
|
+
consola.info(`IS_APP_READY is ${isReady}`);
|
|
13
|
+
return { statusCode: 200, isReady };
|
|
20
14
|
});
|