@doufunao123/asset-gateway 0.5.0 → 0.7.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/index.js +225 -20
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command9 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/commands/auth.ts
|
|
7
7
|
import { existsSync as existsSync2, unlinkSync } from "fs";
|
|
@@ -70,7 +70,7 @@ function normalizeError(error2) {
|
|
|
70
70
|
|
|
71
71
|
// src/meta.ts
|
|
72
72
|
var CLI_NAME = "asset-gateway";
|
|
73
|
-
var CLI_VERSION = "0.
|
|
73
|
+
var CLI_VERSION = "0.6.0";
|
|
74
74
|
var CLI_DESCRIPTION = "Universal asset generation gateway CLI";
|
|
75
75
|
var DEFAULT_GATEWAY_URL = "https://assets.xiaomao.chat";
|
|
76
76
|
|
|
@@ -586,20 +586,20 @@ function createGenerateCommand() {
|
|
|
586
586
|
})
|
|
587
587
|
);
|
|
588
588
|
command.addCommand(
|
|
589
|
-
new Command3("tts").description("Text-to-speech synthesis
|
|
589
|
+
new Command3("tts").description("Text-to-speech synthesis via Qwen3-TTS").requiredOption("--prompt <text>", "Text to synthesize").option("--voice <name>", "Voice name or custom voice ID", "Cherry").option("--language <lang>", "Language hint: Auto, Chinese, English, Japanese, etc.", "Auto").option("--model <model>", "Qwen3-TTS model", "qwen3-tts-flash").option("--instructions <text>", "Natural language speaking instructions (for instruct models)").option("--provider <id>", "Provider to use").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
590
590
|
try {
|
|
591
591
|
const ctx = createContext(this);
|
|
592
|
-
const params = {
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
if (options.
|
|
592
|
+
const params = {
|
|
593
|
+
voice: options.voice,
|
|
594
|
+
language_type: options.language
|
|
595
|
+
};
|
|
596
|
+
if (options.instructions) params.instructions = options.instructions;
|
|
597
597
|
const body = {
|
|
598
598
|
asset_type: "tts",
|
|
599
599
|
prompt: options.prompt,
|
|
600
|
+
model: options.model,
|
|
600
601
|
params
|
|
601
602
|
};
|
|
602
|
-
if (options.model) body.model = options.model;
|
|
603
603
|
if (options.provider) body.provider = options.provider;
|
|
604
604
|
const data = await ctx.client.post("/api/generate", body);
|
|
605
605
|
const localPath = await saveOutput(data, "tts", options.outputDir);
|
|
@@ -611,14 +611,25 @@ function createGenerateCommand() {
|
|
|
611
611
|
})
|
|
612
612
|
);
|
|
613
613
|
command.addCommand(
|
|
614
|
-
new Command3("model").description("Generate a 3D model").option("--image <url>", "Reference image URL").option("--prompt <text>", "Model description prompt").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
614
|
+
new Command3("model").description("Generate a 3D model").option("--image <url>", "Reference image URL").option("--prompt <text>", "Model description prompt").option("--model-version <v>", "Tripo model version (e.g. P1-20260311)").option("--face-limit <n>", "Max face count (48-20000)").option("--pbr", "Enable PBR textures").option("--texture-quality <q>", "Texture quality: standard or detailed").option("--auto-size", "Auto-scale to real-world dimensions").option("--negative-prompt <text>", "Negative prompt").option("--multiview <urls>", "4 image URLs comma-separated: front,left,back,right").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
615
615
|
try {
|
|
616
616
|
const ctx = createContext(this);
|
|
617
617
|
const body = {
|
|
618
618
|
asset_type: "model3d"
|
|
619
619
|
};
|
|
620
|
+
const params = {};
|
|
620
621
|
if (options.image) body.input_file = options.image;
|
|
621
622
|
if (options.prompt) body.prompt = options.prompt;
|
|
623
|
+
if (options.modelVersion) params.model_version = options.modelVersion;
|
|
624
|
+
if (options.faceLimit) params.face_limit = Number(options.faceLimit);
|
|
625
|
+
if (options.pbr) params.pbr = true;
|
|
626
|
+
if (options.textureQuality) params.texture_quality = options.textureQuality;
|
|
627
|
+
if (options.autoSize) params.auto_size = true;
|
|
628
|
+
if (options.negativePrompt) params.negative_prompt = options.negativePrompt;
|
|
629
|
+
if (options.multiview) {
|
|
630
|
+
params.multiview = String(options.multiview).split(",").map((value) => value.trim()).filter(Boolean);
|
|
631
|
+
}
|
|
632
|
+
if (Object.keys(params).length > 0) body.params = params;
|
|
622
633
|
const data = await ctx.client.post("/api/generate", body);
|
|
623
634
|
const localPath = await saveOutput(data, "model3d", options.outputDir);
|
|
624
635
|
if (localPath) data.local_path = localPath;
|
|
@@ -790,12 +801,205 @@ function createProcessCommand() {
|
|
|
790
801
|
return command;
|
|
791
802
|
}
|
|
792
803
|
|
|
793
|
-
// src/commands/
|
|
804
|
+
// src/commands/process3d.ts
|
|
805
|
+
import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
806
|
+
import { join as join4 } from "path";
|
|
794
807
|
import { Command as Command6 } from "commander";
|
|
808
|
+
function infer3dExtension(format) {
|
|
809
|
+
const map = {
|
|
810
|
+
fbx: "fbx",
|
|
811
|
+
usdz: "usdz",
|
|
812
|
+
obj: "obj",
|
|
813
|
+
stl: "stl",
|
|
814
|
+
gltf: "gltf",
|
|
815
|
+
"3mf": "3mf",
|
|
816
|
+
glb: "glb"
|
|
817
|
+
};
|
|
818
|
+
return map[String(format ?? "glb").toLowerCase()] ?? "glb";
|
|
819
|
+
}
|
|
820
|
+
async function saveProcess3dOutput(data, operation, outputDir, format) {
|
|
821
|
+
if (!data.output_url) {
|
|
822
|
+
return null;
|
|
823
|
+
}
|
|
824
|
+
const ext = infer3dExtension(format);
|
|
825
|
+
const timestamp = Date.now();
|
|
826
|
+
const filePath = join4(outputDir, `${operation}_${timestamp}.${ext}`);
|
|
827
|
+
mkdirSync4(outputDir, { recursive: true });
|
|
828
|
+
const response = await fetch(String(data.output_url));
|
|
829
|
+
if (!response.ok) {
|
|
830
|
+
return null;
|
|
831
|
+
}
|
|
832
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
833
|
+
writeFileSync4(filePath, buffer);
|
|
834
|
+
return filePath;
|
|
835
|
+
}
|
|
836
|
+
function createProcess3dCommand() {
|
|
837
|
+
const command = new Command6("process3d").description("3D model post-processing via Tripo pipeline");
|
|
838
|
+
command.addCommand(
|
|
839
|
+
new Command6("convert").description("Convert 3D model format (FBX/USDZ/OBJ/STL/GLTF/3MF)").requiredOption("--task-id <id>", "Tripo task ID from generate model").requiredOption("--format <fmt>", "Target format: FBX, USDZ, OBJ, STL, GLTF, 3MF").option("--quad", "Enable quad remeshing").option("--face-limit <n>", "Max face count").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
840
|
+
try {
|
|
841
|
+
const ctx = createContext(this);
|
|
842
|
+
const params = {
|
|
843
|
+
format: options.format
|
|
844
|
+
};
|
|
845
|
+
if (options.quad) params.quad = true;
|
|
846
|
+
if (options.faceLimit) params.face_limit = Number(options.faceLimit);
|
|
847
|
+
const data = await ctx.client.post("/api/process3d", {
|
|
848
|
+
task_id: options.taskId,
|
|
849
|
+
operation: "convert",
|
|
850
|
+
params
|
|
851
|
+
});
|
|
852
|
+
const localPath = await saveProcess3dOutput(data, "convert", options.outputDir, options.format);
|
|
853
|
+
if (localPath) data.local_path = localPath;
|
|
854
|
+
printSuccess("process3d.convert", data, ctx);
|
|
855
|
+
} catch (error2) {
|
|
856
|
+
printError("process3d.convert", error2);
|
|
857
|
+
}
|
|
858
|
+
})
|
|
859
|
+
);
|
|
860
|
+
command.addCommand(
|
|
861
|
+
new Command6("texture").description("Re-texture a 3D model with new materials").requiredOption("--task-id <id>", "Tripo task ID").option("--prompt <text>", "Texture description prompt").option("--pbr", "Enable PBR materials").option("--quality <q>", "Texture quality: standard or detailed").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
862
|
+
try {
|
|
863
|
+
const ctx = createContext(this);
|
|
864
|
+
const params = {};
|
|
865
|
+
if (options.prompt) params.prompt = options.prompt;
|
|
866
|
+
if (options.pbr) params.pbr = true;
|
|
867
|
+
if (options.quality) params.quality = options.quality;
|
|
868
|
+
const data = await ctx.client.post("/api/process3d", {
|
|
869
|
+
task_id: options.taskId,
|
|
870
|
+
operation: "texture",
|
|
871
|
+
params
|
|
872
|
+
});
|
|
873
|
+
const localPath = await saveProcess3dOutput(data, "texture", options.outputDir);
|
|
874
|
+
if (localPath) data.local_path = localPath;
|
|
875
|
+
printSuccess("process3d.texture", data, ctx);
|
|
876
|
+
} catch (error2) {
|
|
877
|
+
printError("process3d.texture", error2);
|
|
878
|
+
}
|
|
879
|
+
})
|
|
880
|
+
);
|
|
881
|
+
command.addCommand(
|
|
882
|
+
new Command6("rig").description("Auto-rig a 3D model (add skeleton for animation)").requiredOption("--task-id <id>", "Tripo task ID").option("--format <fmt>", "Output format: glb or fbx", "glb").option("--spec <spec>", "Rig spec: mixamo or tripo", "mixamo").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
883
|
+
try {
|
|
884
|
+
const ctx = createContext(this);
|
|
885
|
+
const data = await ctx.client.post("/api/process3d", {
|
|
886
|
+
task_id: options.taskId,
|
|
887
|
+
operation: "rig",
|
|
888
|
+
params: {
|
|
889
|
+
format: options.format,
|
|
890
|
+
spec: options.spec
|
|
891
|
+
}
|
|
892
|
+
});
|
|
893
|
+
const localPath = await saveProcess3dOutput(data, "rig", options.outputDir, options.format);
|
|
894
|
+
if (localPath) data.local_path = localPath;
|
|
895
|
+
printSuccess("process3d.rig", data, ctx);
|
|
896
|
+
} catch (error2) {
|
|
897
|
+
printError("process3d.rig", error2);
|
|
898
|
+
}
|
|
899
|
+
})
|
|
900
|
+
);
|
|
901
|
+
command.addCommand(
|
|
902
|
+
new Command6("animate").description("Apply preset animation to a rigged model").requiredOption("--task-id <id>", "Tripo task ID (from rig step)").requiredOption("--animation <preset>", "Animation preset (e.g. preset:walk, preset:idle, preset:run)").option("--format <fmt>", "Output format: glb or fbx", "glb").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
903
|
+
try {
|
|
904
|
+
const ctx = createContext(this);
|
|
905
|
+
const data = await ctx.client.post("/api/process3d", {
|
|
906
|
+
task_id: options.taskId,
|
|
907
|
+
operation: "animate",
|
|
908
|
+
params: {
|
|
909
|
+
animation: options.animation,
|
|
910
|
+
format: options.format
|
|
911
|
+
}
|
|
912
|
+
});
|
|
913
|
+
const localPath = await saveProcess3dOutput(data, "animate", options.outputDir, options.format);
|
|
914
|
+
if (localPath) data.local_path = localPath;
|
|
915
|
+
printSuccess("process3d.animate", data, ctx);
|
|
916
|
+
} catch (error2) {
|
|
917
|
+
printError("process3d.animate", error2);
|
|
918
|
+
}
|
|
919
|
+
})
|
|
920
|
+
);
|
|
921
|
+
command.addCommand(
|
|
922
|
+
new Command6("reduce").description("Reduce polygon count (high-poly to low-poly)").requiredOption("--task-id <id>", "Tripo task ID").option("--face-limit <n>", "Target face count").option("--quad", "Use quad topology").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
923
|
+
try {
|
|
924
|
+
const ctx = createContext(this);
|
|
925
|
+
const params = {};
|
|
926
|
+
if (options.faceLimit) params.face_limit = Number(options.faceLimit);
|
|
927
|
+
if (options.quad) params.quad = true;
|
|
928
|
+
const data = await ctx.client.post("/api/process3d", {
|
|
929
|
+
task_id: options.taskId,
|
|
930
|
+
operation: "reduce",
|
|
931
|
+
params
|
|
932
|
+
});
|
|
933
|
+
const localPath = await saveProcess3dOutput(data, "reduce", options.outputDir);
|
|
934
|
+
if (localPath) data.local_path = localPath;
|
|
935
|
+
printSuccess("process3d.reduce", data, ctx);
|
|
936
|
+
} catch (error2) {
|
|
937
|
+
printError("process3d.reduce", error2);
|
|
938
|
+
}
|
|
939
|
+
})
|
|
940
|
+
);
|
|
941
|
+
command.addCommand(
|
|
942
|
+
new Command6("stylize").description("Apply artistic style to a model").requiredOption("--task-id <id>", "Tripo task ID").requiredOption("--style <style>", "Style: lego, voxel, voronoi, minecraft").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
943
|
+
try {
|
|
944
|
+
const ctx = createContext(this);
|
|
945
|
+
const data = await ctx.client.post("/api/process3d", {
|
|
946
|
+
task_id: options.taskId,
|
|
947
|
+
operation: "stylize",
|
|
948
|
+
params: {
|
|
949
|
+
style: options.style
|
|
950
|
+
}
|
|
951
|
+
});
|
|
952
|
+
const localPath = await saveProcess3dOutput(data, "stylize", options.outputDir);
|
|
953
|
+
if (localPath) data.local_path = localPath;
|
|
954
|
+
printSuccess("process3d.stylize", data, ctx);
|
|
955
|
+
} catch (error2) {
|
|
956
|
+
printError("process3d.stylize", error2);
|
|
957
|
+
}
|
|
958
|
+
})
|
|
959
|
+
);
|
|
960
|
+
command.addCommand(
|
|
961
|
+
new Command6("segment").description("Segment mesh into logical parts").requiredOption("--task-id <id>", "Tripo task ID").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
962
|
+
try {
|
|
963
|
+
const ctx = createContext(this);
|
|
964
|
+
const data = await ctx.client.post("/api/process3d", {
|
|
965
|
+
task_id: options.taskId,
|
|
966
|
+
operation: "segment",
|
|
967
|
+
params: {}
|
|
968
|
+
});
|
|
969
|
+
const localPath = await saveProcess3dOutput(data, "segment", options.outputDir);
|
|
970
|
+
if (localPath) data.local_path = localPath;
|
|
971
|
+
printSuccess("process3d.segment", data, ctx);
|
|
972
|
+
} catch (error2) {
|
|
973
|
+
printError("process3d.segment", error2);
|
|
974
|
+
}
|
|
975
|
+
})
|
|
976
|
+
);
|
|
977
|
+
command.addCommand(
|
|
978
|
+
new Command6("prerigcheck").description("Check if a model can be rigged").requiredOption("--task-id <id>", "Tripo task ID").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
979
|
+
try {
|
|
980
|
+
const ctx = createContext(this);
|
|
981
|
+
const data = await ctx.client.post("/api/process3d", {
|
|
982
|
+
task_id: options.taskId,
|
|
983
|
+
operation: "prerigcheck",
|
|
984
|
+
params: {}
|
|
985
|
+
});
|
|
986
|
+
const localPath = await saveProcess3dOutput(data, "prerigcheck", options.outputDir);
|
|
987
|
+
if (localPath) data.local_path = localPath;
|
|
988
|
+
printSuccess("process3d.prerigcheck", data, ctx);
|
|
989
|
+
} catch (error2) {
|
|
990
|
+
printError("process3d.prerigcheck", error2);
|
|
991
|
+
}
|
|
992
|
+
})
|
|
993
|
+
);
|
|
994
|
+
return command;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
// src/commands/provider.ts
|
|
998
|
+
import { Command as Command7 } from "commander";
|
|
795
999
|
function createProviderCommand() {
|
|
796
|
-
const command = new
|
|
1000
|
+
const command = new Command7("provider").description("Provider management");
|
|
797
1001
|
command.addCommand(
|
|
798
|
-
new
|
|
1002
|
+
new Command7("list").description("List available providers").action(async function() {
|
|
799
1003
|
try {
|
|
800
1004
|
const ctx = createContext(this);
|
|
801
1005
|
const data = await ctx.client.get("/api/providers");
|
|
@@ -806,7 +1010,7 @@ function createProviderCommand() {
|
|
|
806
1010
|
})
|
|
807
1011
|
);
|
|
808
1012
|
command.addCommand(
|
|
809
|
-
new
|
|
1013
|
+
new Command7("health").description("Check provider health").argument("[name]", "Specific provider name").action(async function(name) {
|
|
810
1014
|
try {
|
|
811
1015
|
const ctx = createContext(this);
|
|
812
1016
|
const path = name ? `/api/providers/${encodeURIComponent(name)}/health` : "/api/providers/health";
|
|
@@ -821,11 +1025,11 @@ function createProviderCommand() {
|
|
|
821
1025
|
}
|
|
822
1026
|
|
|
823
1027
|
// src/commands/upload.ts
|
|
824
|
-
import { Command as
|
|
1028
|
+
import { Command as Command8 } from "commander";
|
|
825
1029
|
function createUploadCommand() {
|
|
826
|
-
const command = new
|
|
1030
|
+
const command = new Command8("upload").description("Upload and manage assets");
|
|
827
1031
|
command.addCommand(
|
|
828
|
-
new
|
|
1032
|
+
new Command8("file").description("Upload a file and get a public URL").argument("<path>", "Path to file to upload").action(async function(filePath) {
|
|
829
1033
|
const ctx = createContext(this);
|
|
830
1034
|
try {
|
|
831
1035
|
const data = await ctx.client.uploadFile(filePath);
|
|
@@ -836,7 +1040,7 @@ function createUploadCommand() {
|
|
|
836
1040
|
})
|
|
837
1041
|
);
|
|
838
1042
|
command.addCommand(
|
|
839
|
-
new
|
|
1043
|
+
new Command8("list").description("List uploaded assets").action(async function() {
|
|
840
1044
|
const ctx = createContext(this);
|
|
841
1045
|
try {
|
|
842
1046
|
const data = await ctx.client.get("/api/assets");
|
|
@@ -847,7 +1051,7 @@ function createUploadCommand() {
|
|
|
847
1051
|
})
|
|
848
1052
|
);
|
|
849
1053
|
command.addCommand(
|
|
850
|
-
new
|
|
1054
|
+
new Command8("delete").description("Delete an uploaded asset (admin only)").argument("<filename>", "Filename to delete").action(async function(filename) {
|
|
851
1055
|
const ctx = createContext(this);
|
|
852
1056
|
try {
|
|
853
1057
|
const data = await ctx.client.delete(`/api/assets/${encodeURIComponent(filename)}`);
|
|
@@ -861,13 +1065,14 @@ function createUploadCommand() {
|
|
|
861
1065
|
}
|
|
862
1066
|
|
|
863
1067
|
// src/index.ts
|
|
864
|
-
var program = new
|
|
1068
|
+
var program = new Command9().name("asset-gateway").description("Universal asset generation gateway CLI").version(CLI_VERSION).option(
|
|
865
1069
|
"--gateway-url <url>",
|
|
866
1070
|
`Gateway URL (default: $ASSET_GATEWAY_URL, auth config, or ${DEFAULT_GATEWAY_URL})`
|
|
867
1071
|
).option("--token <token>", "API token for authentication").option("--human", "Human-readable output instead of JSON").option("--fields <fields>", "Comma-separated list of output fields");
|
|
868
1072
|
program.addCommand(createAuthCommand());
|
|
869
1073
|
program.addCommand(createGenerateCommand());
|
|
870
1074
|
program.addCommand(createProcessCommand());
|
|
1075
|
+
program.addCommand(createProcess3dCommand());
|
|
871
1076
|
program.addCommand(createProviderCommand());
|
|
872
1077
|
program.addCommand(createUploadCommand());
|
|
873
1078
|
program.addCommand(createJobCommand());
|