@seam-rpc/server 1.0.3 → 1.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/dist/bin/gen-client.d.ts +1 -0
- package/dist/bin/gen-client.d.ts.map +1 -0
- package/dist/bin/gen-client.js +55 -74
- package/dist/bin/gen-config.d.ts +1 -0
- package/dist/bin/gen-config.d.ts.map +1 -0
- package/dist/bin/gen-config.js +37 -54
- package/dist/bin/index.d.ts +1 -0
- package/dist/bin/index.d.ts.map +1 -0
- package/dist/bin/index.js +4 -6
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -73
- package/package.json +41 -40
- package/dist/bin/bin.d.ts +0 -2
- package/dist/bin/bin.js +0 -19
package/dist/bin/gen-client.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gen-client.d.ts","sourceRoot":"","sources":["../../src/bin/gen-client.ts"],"names":[],"mappings":"AAMA,wBAAsB,SAAS,kBAwC9B"}
|
package/dist/bin/gen-client.js
CHANGED
|
@@ -1,87 +1,69 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
config = {
|
|
32
|
-
inputFiles: args[3],
|
|
33
|
-
outputFolder: args[4]
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
return console.error("Usage: seam-rpc gen-client <input-files> <output-folder>");
|
|
38
|
-
}
|
|
39
|
-
const inputFiles = yield (0, fast_glob_1.default)(config.inputFiles);
|
|
40
|
-
const outputPath = path_1.default.resolve(config.outputFolder);
|
|
41
|
-
const rootPath = path_1.default.resolve(".");
|
|
42
|
-
try {
|
|
43
|
-
const outputFiles = [];
|
|
44
|
-
for (const inputFile of inputFiles) {
|
|
45
|
-
const outputFile = generateClientFile(inputFile, outputPath);
|
|
46
|
-
outputFiles.push(removeRootPath(outputFile, rootPath));
|
|
47
|
-
}
|
|
48
|
-
console.log("\x1b[32m%s\x1b[0m\n\x1b[36m%s\x1b[0m", `✅ Successfully generated client files at ${removeRootPath(outputPath, rootPath)}`, `${outputFiles.join("\n")}`);
|
|
49
|
-
}
|
|
50
|
-
catch (err) {
|
|
51
|
-
console.error("❌ Failed to generate client file:", err.message);
|
|
52
|
-
process.exit(1);
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import ts from "typescript";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import fg from "fast-glob";
|
|
5
|
+
export async function genClient() {
|
|
6
|
+
const args = process.argv;
|
|
7
|
+
let config;
|
|
8
|
+
if (args.length == 3) {
|
|
9
|
+
if (!fs.existsSync("./seam-rpc.config.json"))
|
|
10
|
+
return console.error("\x1b[31mCommand arguments omitted and no config file found.\x1b[0m\n"
|
|
11
|
+
+ "Either define a config file with \x1b[36mseam-rpc gen-config\x1b[0m or generate the client files using \x1b[36mseam-rpc gen-client <input-files> <output-folder> [global-types-file]\x1b[0m.");
|
|
12
|
+
config = JSON.parse(fs.readFileSync("./seam-rpc.config.json", "utf-8"));
|
|
13
|
+
}
|
|
14
|
+
else if (args.length == 5 || args.length == 6) {
|
|
15
|
+
config = {
|
|
16
|
+
inputFiles: args[3],
|
|
17
|
+
outputFolder: args[4]
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
return console.error("Usage: seam-rpc gen-client <input-files> <output-folder>");
|
|
22
|
+
}
|
|
23
|
+
const inputFiles = await fg(config.inputFiles);
|
|
24
|
+
const outputPath = path.resolve(config.outputFolder);
|
|
25
|
+
const rootPath = path.resolve(".");
|
|
26
|
+
try {
|
|
27
|
+
const outputFiles = [];
|
|
28
|
+
for (const inputFile of inputFiles) {
|
|
29
|
+
const outputFile = generateClientFile(inputFile, outputPath);
|
|
30
|
+
outputFiles.push(removeRootPath(outputFile, rootPath));
|
|
53
31
|
}
|
|
54
|
-
|
|
32
|
+
console.log("\x1b[32m%s\x1b[0m\n\x1b[36m%s\x1b[0m", `✅ Successfully generated client files at ${removeRootPath(outputPath, rootPath)}`, `${outputFiles.join("\n")}`);
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
console.error("❌ Failed to generate client file:", err.message);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
55
38
|
}
|
|
56
39
|
function removeRootPath(path, rootPath) {
|
|
57
40
|
return "." + path.slice(rootPath.length);
|
|
58
41
|
}
|
|
59
42
|
function generateClientFile(inputFile, outputPath) {
|
|
60
|
-
const file =
|
|
61
|
-
if (!
|
|
43
|
+
const file = path.resolve(process.cwd(), inputFile);
|
|
44
|
+
if (!fs.existsSync(file)) {
|
|
62
45
|
console.error(`File ${file} not found`);
|
|
63
46
|
process.exit(1);
|
|
64
47
|
}
|
|
65
48
|
const imports = ["import { callApi, SeamFile, ISeamFile } from \"@seam-rpc/client\";"];
|
|
66
49
|
const apiDef = [];
|
|
67
50
|
const typeDefs = [];
|
|
68
|
-
const routerName =
|
|
69
|
-
const fileContent =
|
|
70
|
-
const sourceFile =
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (typescript_1.default.isImportDeclaration(node)) {
|
|
51
|
+
const routerName = path.basename(file, path.extname(file));
|
|
52
|
+
const fileContent = fs.readFileSync(file, "utf-8");
|
|
53
|
+
const sourceFile = ts.createSourceFile(file, fileContent, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
54
|
+
ts.forEachChild(sourceFile, (node) => {
|
|
55
|
+
if (ts.isImportDeclaration(node)) {
|
|
74
56
|
const moduleSpecifier = node.moduleSpecifier.getText().replace(/['"]/g, "");
|
|
75
57
|
if (moduleSpecifier.startsWith("./"))
|
|
76
58
|
imports.push(node.getText());
|
|
77
59
|
}
|
|
78
|
-
else if (
|
|
60
|
+
else if (ts.isFunctionDeclaration(node) && hasExportModifier(node)) {
|
|
79
61
|
if (!node.name) {
|
|
80
62
|
console.error("Missing function name.");
|
|
81
63
|
process.exit(1);
|
|
82
64
|
}
|
|
83
65
|
const funcName = node.name.getText();
|
|
84
|
-
const jsDoc =
|
|
66
|
+
const jsDoc = ts.getJSDocCommentsAndTags(node).map(e => e.getFullText()).filter(Boolean).join("\n");
|
|
85
67
|
let signature = `${jsDoc}\nexport function ${funcName}(`;
|
|
86
68
|
const paramsText = node.parameters
|
|
87
69
|
.map((p) => {
|
|
@@ -91,32 +73,31 @@ function generateClientFile(inputFile, outputPath) {
|
|
|
91
73
|
return `${paramName}${optional}: ${type}`;
|
|
92
74
|
})
|
|
93
75
|
.join(", ");
|
|
94
|
-
const returnTypeText =
|
|
76
|
+
const returnTypeText = node.type?.getText() ?? "any";
|
|
95
77
|
const finalReturnType = returnTypeText.startsWith("Promise<")
|
|
96
78
|
? returnTypeText
|
|
97
79
|
: `Promise<${returnTypeText}>`;
|
|
98
80
|
signature += `${paramsText}): ${finalReturnType} { return callApi("${routerName}", "${funcName}", [${node.parameters.map(e => e.name.getText()).join(", ")}]); }`;
|
|
99
81
|
apiDef.push(signature);
|
|
100
82
|
}
|
|
101
|
-
else if ((
|
|
102
|
-
|
|
103
|
-
|
|
83
|
+
else if ((ts.isInterfaceDeclaration(node) ||
|
|
84
|
+
ts.isTypeAliasDeclaration(node) ||
|
|
85
|
+
ts.isEnumDeclaration(node))
|
|
104
86
|
&& hasExportModifier(node)) {
|
|
105
87
|
const text = node.getFullText(sourceFile).trim();
|
|
106
88
|
typeDefs.push(text);
|
|
107
89
|
}
|
|
108
90
|
});
|
|
109
91
|
const content = [imports.join("\n"), typeDefs.join("\n"), apiDef.join("\n")].join("\n");
|
|
110
|
-
|
|
92
|
+
fs.writeFileSync(path.resolve(outputPath, path.basename(file)), content, "utf-8");
|
|
111
93
|
return file;
|
|
112
94
|
}
|
|
113
95
|
function hasExportModifier(node) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
return !!((_a = node.modifiers) === null || _a === void 0 ? void 0 : _a.some((m) => m.kind === typescript_1.default.SyntaxKind.ExportKeyword));
|
|
96
|
+
if (ts.isVariableStatement(node) ||
|
|
97
|
+
ts.isFunctionDeclaration(node) ||
|
|
98
|
+
ts.isClassDeclaration(node) ||
|
|
99
|
+
ts.isInterfaceDeclaration(node)) {
|
|
100
|
+
return !!node.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword);
|
|
120
101
|
}
|
|
121
102
|
return false;
|
|
122
103
|
}
|
package/dist/bin/gen-config.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gen-config.d.ts","sourceRoot":"","sources":["../../src/bin/gen-config.ts"],"names":[],"mappings":"AAIA,wBAAsB,SAAS,kBAsC9B"}
|
package/dist/bin/gen-config.js
CHANGED
|
@@ -1,55 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
process.exit(0);
|
|
39
|
-
}
|
|
40
|
-
rl.close();
|
|
41
|
-
const config = {
|
|
42
|
-
inputFiles,
|
|
43
|
-
outputFolder
|
|
44
|
-
};
|
|
45
|
-
try {
|
|
46
|
-
fs_1.default.writeFileSync("./seam-rpc.config.json", JSON.stringify(config, null, 4), "utf-8");
|
|
47
|
-
}
|
|
48
|
-
catch (e) {
|
|
49
|
-
console.log("\x1b[31mFailed to generate config file ./seam-rpc.config.json\x1b[0m\n" + e);
|
|
50
|
-
}
|
|
51
|
-
console.log(`\x1b[32mSuccessfully generated config file ./seam-rpc.config.json\x1b[0m`);
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
});
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import readline from "readline";
|
|
3
|
+
export async function genConfig() {
|
|
4
|
+
const args = process.argv;
|
|
5
|
+
let inputFiles = "./src/api/*";
|
|
6
|
+
let outputFolder = "../client/src/api";
|
|
7
|
+
if (args.length == 5) {
|
|
8
|
+
inputFiles = args[3];
|
|
9
|
+
outputFolder = args[4];
|
|
10
|
+
}
|
|
11
|
+
else if (args.length > 3) {
|
|
12
|
+
return console.error("Usage: seam-rpc gen-config [input-files] [output-folder]");
|
|
13
|
+
}
|
|
14
|
+
if (fs.existsSync("./seam-rpc.config.json")) {
|
|
15
|
+
const rl = readline.createInterface({
|
|
16
|
+
input: process.stdin,
|
|
17
|
+
output: process.stdout,
|
|
18
|
+
});
|
|
19
|
+
rl.question("Config file already exists. Do you want to overwrite it? [Y/n] ", answer => {
|
|
20
|
+
if (answer && answer.toLowerCase() != "y" && answer.toLowerCase() != "yes") {
|
|
21
|
+
console.log("Operation canceled.");
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
rl.close();
|
|
25
|
+
const config = {
|
|
26
|
+
inputFiles,
|
|
27
|
+
outputFolder
|
|
28
|
+
};
|
|
29
|
+
try {
|
|
30
|
+
fs.writeFileSync("./seam-rpc.config.json", JSON.stringify(config, null, 4), "utf-8");
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
console.log("\x1b[31mFailed to generate config file ./seam-rpc.config.json\x1b[0m\n" + e);
|
|
34
|
+
}
|
|
35
|
+
console.log(`\x1b[32mSuccessfully generated config file ./seam-rpc.config.json\x1b[0m`);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
55
38
|
}
|
package/dist/bin/index.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bin/index.ts"],"names":[],"mappings":";AAsBA,MAAM,WAAW,UAAU;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACxB"}
|
package/dist/bin/index.js
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const gen_client_1 = require("./gen-client");
|
|
5
|
-
const gen_config_1 = require("./gen-config");
|
|
2
|
+
import { genClient } from "./gen-client.js";
|
|
3
|
+
import { genConfig } from "./gen-config.js";
|
|
6
4
|
main();
|
|
7
5
|
function main() {
|
|
8
6
|
const args = process.argv;
|
|
9
7
|
switch (args[2]) {
|
|
10
8
|
case "gen-client":
|
|
11
|
-
|
|
9
|
+
genClient();
|
|
12
10
|
break;
|
|
13
11
|
case "gen-config":
|
|
14
|
-
|
|
12
|
+
genConfig();
|
|
15
13
|
break;
|
|
16
14
|
default:
|
|
17
15
|
console.log("Commands:\n- seam-rpc gen-client <input-files> <output-folder>\n- seam-rpc gen-config [input-files] [output-folder]");
|
package/dist/index.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAA6B,MAAM,gBAAgB,CAAC;AAChF,OAAgB,EAAE,OAAO,EAAyB,cAAc,EAAoB,MAAM,SAAS,CAAC;AAGpG,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AAE/B,MAAM,WAAW,gBAAgB;IAC7B,CAAC,QAAQ,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;CACxD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,cAAc,GAAG,SAAS,CAerF;AAED,qBAAa,SAAS;IAGN,OAAO,CAAC,GAAG;IAAW,OAAO,CAAC,WAAW;IAFrD,OAAO,CAAC,UAAU,CAAkB;gBAEhB,GAAG,EAAE,OAAO,EAAU,WAAW,EAAE,cAAc;IAE9D,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,gBAAgB,EAAE,gBAAgB,GAAG,IAAI;CA4E9E"}
|
package/dist/index.js
CHANGED
|
@@ -1,64 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
-
});
|
|
43
|
-
};
|
|
44
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
45
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
46
|
-
};
|
|
47
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
-
exports.SeamSpace = exports.SeamFile = void 0;
|
|
49
|
-
exports.createSeamSpace = createSeamSpace;
|
|
50
|
-
const core_1 = require("@seam-rpc/core");
|
|
51
|
-
Object.defineProperty(exports, "SeamFile", { enumerable: true, get: function () { return core_1.SeamFile; } });
|
|
52
|
-
const express_1 = __importStar(require("express"));
|
|
53
|
-
const form_data_1 = __importDefault(require("form-data"));
|
|
1
|
+
import { SeamFile, extractFiles, injectFiles } from "@seam-rpc/core";
|
|
2
|
+
import express, { Router } from "express";
|
|
3
|
+
import FormData from "form-data";
|
|
4
|
+
export { SeamFile };
|
|
54
5
|
;
|
|
55
|
-
function createSeamSpace(app, fileHandler) {
|
|
6
|
+
export function createSeamSpace(app, fileHandler) {
|
|
56
7
|
if (!fileHandler) {
|
|
57
8
|
let multer;
|
|
58
9
|
try {
|
|
59
10
|
multer = require("multer");
|
|
60
11
|
}
|
|
61
|
-
catch
|
|
12
|
+
catch {
|
|
62
13
|
throw new Error("Multer is required as default file handler. Install it or provide a custom fileHandler.");
|
|
63
14
|
}
|
|
64
15
|
const upload = multer();
|
|
@@ -66,25 +17,24 @@ function createSeamSpace(app, fileHandler) {
|
|
|
66
17
|
}
|
|
67
18
|
return new SeamSpace(app, fileHandler);
|
|
68
19
|
}
|
|
69
|
-
class SeamSpace {
|
|
20
|
+
export class SeamSpace {
|
|
70
21
|
constructor(app, fileHandler) {
|
|
71
22
|
this.app = app;
|
|
72
23
|
this.fileHandler = fileHandler;
|
|
73
|
-
this.jsonParser =
|
|
24
|
+
this.jsonParser = express.json();
|
|
74
25
|
}
|
|
75
26
|
createRouter(path, routerDefinition) {
|
|
76
|
-
const router =
|
|
77
|
-
router.post("/:funcName", (req, res, next) =>
|
|
78
|
-
var _a;
|
|
27
|
+
const router = Router();
|
|
28
|
+
router.post("/:funcName", async (req, res, next) => {
|
|
79
29
|
if (!(req.params.funcName in routerDefinition))
|
|
80
30
|
return res.sendStatus(404);
|
|
81
31
|
const contentType = req.headers["content-type"] || "";
|
|
82
32
|
const runMiddleware = (middleware) => new Promise((resolve, reject) => middleware(req, res, err => (err ? reject(err) : resolve())));
|
|
83
33
|
if (contentType.startsWith("application/json")) {
|
|
84
|
-
|
|
34
|
+
await runMiddleware(this.jsonParser);
|
|
85
35
|
}
|
|
86
36
|
else if (contentType.startsWith("multipart/form-data")) {
|
|
87
|
-
|
|
37
|
+
await runMiddleware(this.fileHandler);
|
|
88
38
|
}
|
|
89
39
|
else {
|
|
90
40
|
return res.status(415).send("Unsupported content type");
|
|
@@ -97,15 +47,15 @@ class SeamSpace {
|
|
|
97
47
|
// multipart/form-data
|
|
98
48
|
args = JSON.parse(req.body.json);
|
|
99
49
|
const paths = JSON.parse(req.body.paths);
|
|
100
|
-
const files = (
|
|
50
|
+
const files = (req.files ?? []).map((file, index) => ({
|
|
101
51
|
path: paths[index],
|
|
102
|
-
file: new
|
|
52
|
+
file: new SeamFile(file.buffer, file.originalname, file.mimetype),
|
|
103
53
|
}));
|
|
104
|
-
|
|
54
|
+
injectFiles(args, files);
|
|
105
55
|
}
|
|
106
56
|
let result;
|
|
107
57
|
try {
|
|
108
|
-
result =
|
|
58
|
+
result = await routerDefinition[req.params.funcName](...args);
|
|
109
59
|
}
|
|
110
60
|
catch (error) {
|
|
111
61
|
console.error(`Error at API function at router "${path}". Sent error to client.`, error);
|
|
@@ -113,17 +63,17 @@ class SeamSpace {
|
|
|
113
63
|
return;
|
|
114
64
|
}
|
|
115
65
|
try {
|
|
116
|
-
const { json, files, paths } =
|
|
66
|
+
const { json, files, paths } = extractFiles({ result });
|
|
117
67
|
if (files.length === 0) {
|
|
118
68
|
res.json(json);
|
|
119
69
|
return;
|
|
120
70
|
}
|
|
121
|
-
const form = new
|
|
71
|
+
const form = new FormData();
|
|
122
72
|
form.append("json", JSON.stringify(json));
|
|
123
73
|
form.append("paths", JSON.stringify(paths));
|
|
124
|
-
files.forEach((file,
|
|
125
|
-
form.append(`file-${
|
|
126
|
-
filename: file.fileName || `file-${
|
|
74
|
+
files.forEach((file, index) => {
|
|
75
|
+
form.append(`file-${index}`, Buffer.from(file.data), {
|
|
76
|
+
filename: file.fileName || `file-${index}`,
|
|
127
77
|
contentType: file.mimeType || "application/octet-stream",
|
|
128
78
|
});
|
|
129
79
|
});
|
|
@@ -134,8 +84,7 @@ class SeamSpace {
|
|
|
134
84
|
console.error(`Internal error at API function at router "${path}". Returned 500 Internal Server Error to client.`, error);
|
|
135
85
|
res.status(500).send({ error: String(error) });
|
|
136
86
|
}
|
|
137
|
-
})
|
|
87
|
+
});
|
|
138
88
|
this.app.use(path, router);
|
|
139
89
|
}
|
|
140
90
|
}
|
|
141
|
-
exports.SeamSpace = SeamSpace;
|
package/package.json
CHANGED
|
@@ -1,40 +1,41 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@seam-rpc/server",
|
|
3
|
-
"version": "1.0
|
|
4
|
-
"main": "dist/index.js",
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"@types/
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@seam-rpc/server",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"seam-rpc": "dist/bin/index.js"
|
|
8
|
+
},
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [],
|
|
17
|
+
"author": "Daniel Clímaco",
|
|
18
|
+
"license": "ISC",
|
|
19
|
+
"description": "",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/DanielC49/seam-rpc.git",
|
|
23
|
+
"directory": "packages/client"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://github.com/DanielC49/seam-rpc#readme",
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/DanielC49/seam-rpc/issues"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/express": "^5.0.3",
|
|
31
|
+
"@types/node": "^24.3.1",
|
|
32
|
+
"express": "^5.1.0",
|
|
33
|
+
"multer": "^2.0.2"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@seam-rpc/core": "^1.0.0",
|
|
37
|
+
"fast-glob": "^3.3.3",
|
|
38
|
+
"form-data": "^4.0.5",
|
|
39
|
+
"typescript": "^5.9.3"
|
|
40
|
+
}
|
|
41
|
+
}
|
package/dist/bin/bin.d.ts
DELETED
package/dist/bin/bin.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
const gen_client_1 = require("./gen-client");
|
|
5
|
-
const gen_config_1 = require("./gen-config");
|
|
6
|
-
main();
|
|
7
|
-
function main() {
|
|
8
|
-
const args = process.argv;
|
|
9
|
-
switch (args[3]) {
|
|
10
|
-
case "gen-client":
|
|
11
|
-
(0, gen_client_1.genClient)();
|
|
12
|
-
break;
|
|
13
|
-
case "gen-config":
|
|
14
|
-
(0, gen_config_1.genConfig)();
|
|
15
|
-
break;
|
|
16
|
-
default:
|
|
17
|
-
console.log("Commands:\n- seam-rpc gen-client <input-files> [output-folder]\n- seam-rpc gen-config [input-files] [output-folder]");
|
|
18
|
-
}
|
|
19
|
-
}
|