@doufunao123/asset-gateway 0.3.0 → 0.5.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 +110 -13
- 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 Command8 } 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.4.0";
|
|
74
74
|
var CLI_DESCRIPTION = "Universal asset generation gateway CLI";
|
|
75
75
|
var DEFAULT_GATEWAY_URL = "https://assets.xiaomao.chat";
|
|
76
76
|
|
|
@@ -527,7 +527,7 @@ async function saveOutput(result, assetType, outputDir) {
|
|
|
527
527
|
function createGenerateCommand() {
|
|
528
528
|
const command = new Command3("generate").description("Generate assets via the gateway");
|
|
529
529
|
command.addCommand(
|
|
530
|
-
new Command3("image").description("Generate an image from a text prompt").requiredOption("--prompt <text>", "Image description prompt").option("--provider <id>", "Provider to use").option("--transparent", "Request transparent background").option("--model <model>", "Model to use").option("--size <size>", "Image size (e.g. 1024x1024)").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
530
|
+
new Command3("image").description("Generate an image from a text prompt").requiredOption("--prompt <text>", "Image description prompt").option("--provider <id>", "Provider to use").option("--transparent", "Request transparent background").option("--model <model>", "Model to use").option("--size <size>", "Image size (e.g. 1024x1024)").option("--input <url>", "Input image URL for editing (Gemini/Grok)").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
531
531
|
try {
|
|
532
532
|
const ctx = createContext(this);
|
|
533
533
|
const body = {
|
|
@@ -538,6 +538,7 @@ function createGenerateCommand() {
|
|
|
538
538
|
if (options.transparent) body.transparent = true;
|
|
539
539
|
if (options.model) body.model = options.model;
|
|
540
540
|
if (options.size) body.size = options.size;
|
|
541
|
+
if (options.input) body.input_file = options.input;
|
|
541
542
|
const data = await ctx.client.post("/api/generate", body);
|
|
542
543
|
const localPath = await saveOutput(data, "image", options.outputDir);
|
|
543
544
|
if (localPath) data.local_path = localPath;
|
|
@@ -694,12 +695,107 @@ function createJobCommand() {
|
|
|
694
695
|
return command;
|
|
695
696
|
}
|
|
696
697
|
|
|
697
|
-
// src/commands/
|
|
698
|
+
// src/commands/process.ts
|
|
699
|
+
import { mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
700
|
+
import { existsSync as existsSync3 } from "fs";
|
|
701
|
+
import { join as join3 } from "path";
|
|
698
702
|
import { Command as Command5 } from "commander";
|
|
703
|
+
function readInputAsBase64(input) {
|
|
704
|
+
if (existsSync3(input)) {
|
|
705
|
+
const bytes = readFileSync2(input);
|
|
706
|
+
return `data:image/png;base64,${bytes.toString("base64")}`;
|
|
707
|
+
}
|
|
708
|
+
return input;
|
|
709
|
+
}
|
|
710
|
+
function saveProcessOutput(data, outputDir) {
|
|
711
|
+
const outputData = data.output_data;
|
|
712
|
+
if (typeof outputData !== "string" || !outputData) return null;
|
|
713
|
+
mkdirSync3(outputDir, { recursive: true });
|
|
714
|
+
const timestamp = Date.now();
|
|
715
|
+
const filePath = join3(outputDir, `processed_${timestamp}.png`);
|
|
716
|
+
writeFileSync3(filePath, Buffer.from(outputData, "base64"));
|
|
717
|
+
delete data.output_data;
|
|
718
|
+
return filePath;
|
|
719
|
+
}
|
|
720
|
+
function createProcessCommand() {
|
|
721
|
+
const command = new Command5("process").description("Post-process images (remove-bg, crop, resize, upscale)");
|
|
722
|
+
command.addCommand(
|
|
723
|
+
new Command5("remove-bg").description("Remove background from an image (AI-powered, BiRefNet)").requiredOption("--input <path>", "Input image (file path or URL)").option("--smart-crop", "Also crop to power-of-2 after removing background").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
724
|
+
try {
|
|
725
|
+
const ctx = createContext(this);
|
|
726
|
+
const ops = [{ op: "remove_bg" }];
|
|
727
|
+
if (options.smartCrop) {
|
|
728
|
+
ops.push({ op: "smart_crop", mode: "power_of2" });
|
|
729
|
+
}
|
|
730
|
+
const data = await ctx.client.post("/api/process", {
|
|
731
|
+
input: readInputAsBase64(options.input),
|
|
732
|
+
operations: ops
|
|
733
|
+
});
|
|
734
|
+
const localPath = saveProcessOutput(data, options.outputDir);
|
|
735
|
+
if (localPath) data.local_path = localPath;
|
|
736
|
+
printSuccess("process.remove-bg", data, ctx);
|
|
737
|
+
} catch (error2) {
|
|
738
|
+
printError("process.remove-bg", error2);
|
|
739
|
+
}
|
|
740
|
+
})
|
|
741
|
+
);
|
|
742
|
+
command.addCommand(
|
|
743
|
+
new Command5("crop").description("Smart crop an image (trim transparent borders)").requiredOption("--input <path>", "Input image (file path or URL)").option("--mode <mode>", "Crop mode: tightest or power_of2", "tightest").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
744
|
+
try {
|
|
745
|
+
const ctx = createContext(this);
|
|
746
|
+
const data = await ctx.client.post("/api/process", {
|
|
747
|
+
input: readInputAsBase64(options.input),
|
|
748
|
+
operations: [{ op: "smart_crop", mode: options.mode }]
|
|
749
|
+
});
|
|
750
|
+
const localPath = saveProcessOutput(data, options.outputDir);
|
|
751
|
+
if (localPath) data.local_path = localPath;
|
|
752
|
+
printSuccess("process.crop", data, ctx);
|
|
753
|
+
} catch (error2) {
|
|
754
|
+
printError("process.crop", error2);
|
|
755
|
+
}
|
|
756
|
+
})
|
|
757
|
+
);
|
|
758
|
+
command.addCommand(
|
|
759
|
+
new Command5("resize").description("Resize an image to exact dimensions").requiredOption("--input <path>", "Input image (file path or URL)").requiredOption("--width <n>", "Target width").requiredOption("--height <n>", "Target height").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
760
|
+
try {
|
|
761
|
+
const ctx = createContext(this);
|
|
762
|
+
const data = await ctx.client.post("/api/process", {
|
|
763
|
+
input: readInputAsBase64(options.input),
|
|
764
|
+
operations: [{ op: "resize", width: Number(options.width), height: Number(options.height) }]
|
|
765
|
+
});
|
|
766
|
+
const localPath = saveProcessOutput(data, options.outputDir);
|
|
767
|
+
if (localPath) data.local_path = localPath;
|
|
768
|
+
printSuccess("process.resize", data, ctx);
|
|
769
|
+
} catch (error2) {
|
|
770
|
+
printError("process.resize", error2);
|
|
771
|
+
}
|
|
772
|
+
})
|
|
773
|
+
);
|
|
774
|
+
command.addCommand(
|
|
775
|
+
new Command5("upscale").description("AI upscale an image (2x or 4x via Real-ESRGAN)").requiredOption("--input <path>", "Input image (file path or URL)").option("--scale <n>", "Scale factor (2 or 4)", "4").option("--output-dir <dir>", "Directory to save output", ".").action(async function(options) {
|
|
776
|
+
try {
|
|
777
|
+
const ctx = createContext(this);
|
|
778
|
+
const data = await ctx.client.post("/api/process", {
|
|
779
|
+
input: readInputAsBase64(options.input),
|
|
780
|
+
operations: [{ op: "upscale", scale: Number(options.scale) }]
|
|
781
|
+
});
|
|
782
|
+
const localPath = saveProcessOutput(data, options.outputDir);
|
|
783
|
+
if (localPath) data.local_path = localPath;
|
|
784
|
+
printSuccess("process.upscale", data, ctx);
|
|
785
|
+
} catch (error2) {
|
|
786
|
+
printError("process.upscale", error2);
|
|
787
|
+
}
|
|
788
|
+
})
|
|
789
|
+
);
|
|
790
|
+
return command;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
// src/commands/provider.ts
|
|
794
|
+
import { Command as Command6 } from "commander";
|
|
699
795
|
function createProviderCommand() {
|
|
700
|
-
const command = new
|
|
796
|
+
const command = new Command6("provider").description("Provider management");
|
|
701
797
|
command.addCommand(
|
|
702
|
-
new
|
|
798
|
+
new Command6("list").description("List available providers").action(async function() {
|
|
703
799
|
try {
|
|
704
800
|
const ctx = createContext(this);
|
|
705
801
|
const data = await ctx.client.get("/api/providers");
|
|
@@ -710,7 +806,7 @@ function createProviderCommand() {
|
|
|
710
806
|
})
|
|
711
807
|
);
|
|
712
808
|
command.addCommand(
|
|
713
|
-
new
|
|
809
|
+
new Command6("health").description("Check provider health").argument("[name]", "Specific provider name").action(async function(name) {
|
|
714
810
|
try {
|
|
715
811
|
const ctx = createContext(this);
|
|
716
812
|
const path = name ? `/api/providers/${encodeURIComponent(name)}/health` : "/api/providers/health";
|
|
@@ -725,11 +821,11 @@ function createProviderCommand() {
|
|
|
725
821
|
}
|
|
726
822
|
|
|
727
823
|
// src/commands/upload.ts
|
|
728
|
-
import { Command as
|
|
824
|
+
import { Command as Command7 } from "commander";
|
|
729
825
|
function createUploadCommand() {
|
|
730
|
-
const command = new
|
|
826
|
+
const command = new Command7("upload").description("Upload and manage assets");
|
|
731
827
|
command.addCommand(
|
|
732
|
-
new
|
|
828
|
+
new Command7("file").description("Upload a file and get a public URL").argument("<path>", "Path to file to upload").action(async function(filePath) {
|
|
733
829
|
const ctx = createContext(this);
|
|
734
830
|
try {
|
|
735
831
|
const data = await ctx.client.uploadFile(filePath);
|
|
@@ -740,7 +836,7 @@ function createUploadCommand() {
|
|
|
740
836
|
})
|
|
741
837
|
);
|
|
742
838
|
command.addCommand(
|
|
743
|
-
new
|
|
839
|
+
new Command7("list").description("List uploaded assets").action(async function() {
|
|
744
840
|
const ctx = createContext(this);
|
|
745
841
|
try {
|
|
746
842
|
const data = await ctx.client.get("/api/assets");
|
|
@@ -751,7 +847,7 @@ function createUploadCommand() {
|
|
|
751
847
|
})
|
|
752
848
|
);
|
|
753
849
|
command.addCommand(
|
|
754
|
-
new
|
|
850
|
+
new Command7("delete").description("Delete an uploaded asset (admin only)").argument("<filename>", "Filename to delete").action(async function(filename) {
|
|
755
851
|
const ctx = createContext(this);
|
|
756
852
|
try {
|
|
757
853
|
const data = await ctx.client.delete(`/api/assets/${encodeURIComponent(filename)}`);
|
|
@@ -765,12 +861,13 @@ function createUploadCommand() {
|
|
|
765
861
|
}
|
|
766
862
|
|
|
767
863
|
// src/index.ts
|
|
768
|
-
var program = new
|
|
864
|
+
var program = new Command8().name("asset-gateway").description("Universal asset generation gateway CLI").version(CLI_VERSION).option(
|
|
769
865
|
"--gateway-url <url>",
|
|
770
866
|
`Gateway URL (default: $ASSET_GATEWAY_URL, auth config, or ${DEFAULT_GATEWAY_URL})`
|
|
771
867
|
).option("--token <token>", "API token for authentication").option("--human", "Human-readable output instead of JSON").option("--fields <fields>", "Comma-separated list of output fields");
|
|
772
868
|
program.addCommand(createAuthCommand());
|
|
773
869
|
program.addCommand(createGenerateCommand());
|
|
870
|
+
program.addCommand(createProcessCommand());
|
|
774
871
|
program.addCommand(createProviderCommand());
|
|
775
872
|
program.addCommand(createUploadCommand());
|
|
776
873
|
program.addCommand(createJobCommand());
|