@mymj/midjourney
Version:
Node.js client for the unofficial MidJourney API.
238 lines • 8.18 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.base64ToBlob = exports.toRemixCustom = exports.custom2Type = exports.content2prompt = exports.content2progress = exports.filenameToHash = exports.uriToHash = exports.formatSubscribe = exports.formatInfo = exports.componentsToHash = exports.formatOptions = exports.formatPrompts = exports.nextNonce = exports.random = exports.sleep = void 0;
const snowyflake_1 = require("snowyflake");
const sleep = async (ms) => await new Promise((resolve) => setTimeout(resolve, ms));
exports.sleep = sleep;
const random = (min, max) => Math.floor(Math.random() * (max - min) + min);
exports.random = random;
const snowflake = new snowyflake_1.Snowyflake({
workerId: 0n,
processId: 0n,
epoch: snowyflake_1.Epoch.Discord, // BigInt timestamp
});
const nextNonce = () => snowflake.nextId().toString();
exports.nextNonce = nextNonce;
const formatPrompts = (prompts) => {
const regex = /(\d️⃣ .+)/g;
const matches = prompts.match(regex);
if (matches) {
const shortenedPrompts = matches.map((match) => match.trim());
return shortenedPrompts;
}
else {
return [];
}
};
exports.formatPrompts = formatPrompts;
const formatOptions = (components) => {
var data = [];
for (var i = 0; i < components.length; i++) {
const component = components[i];
if (component.components && component.components.length > 0) {
const item = (0, exports.formatOptions)(component.components);
data = data.concat(item);
}
if (!component.custom_id)
continue;
data.push({
type: component.type,
style: component.style,
label: component.label || component.emoji?.name,
custom: component.custom_id,
});
}
return data;
};
exports.formatOptions = formatOptions;
const componentsToHash = (components) => {
const options = (0, exports.formatOptions)(components);
for (let i = 0; i < options.length; i++) {
const option = options[i];
const list = option.custom.split('::');
const hash = list.find(item => item.length === 36 && /^\w+(-\w+)+$/.test(item));
if (hash) {
return hash;
}
}
};
exports.componentsToHash = componentsToHash;
const formatInfo = (msg) => {
let jsonResult = {
subscription: "",
jobMode: "",
visibilityMode: "",
fastTimeRemaining: "",
lifetimeUsage: "",
relaxedUsage: "",
queuedJobsFast: "",
queuedJobsRelax: "",
runningJobs: "",
message: "",
}; // Initialize jsonResult with empty object
msg.split("\n").forEach(function (line) {
const colonIndex = line.indexOf(":");
if (colonIndex > -1) {
const key = line.substring(0, colonIndex).trim().replaceAll("**", "");
const value = line.substring(colonIndex + 1).trim();
switch (key) {
case "Subscription":
jsonResult.subscription = value;
break;
case "Job Mode":
jsonResult.jobMode = value;
break;
case "Visibility Mode":
jsonResult.visibilityMode = value;
break;
case "Fast Time Remaining":
jsonResult.fastTimeRemaining = value;
break;
case "Lifetime Usage":
jsonResult.lifetimeUsage = value;
break;
case "Relaxed Usage":
jsonResult.relaxedUsage = value;
break;
case "Queued Jobs (fast)":
jsonResult.queuedJobsFast = value;
break;
case "Queued Jobs (relax)":
jsonResult.queuedJobsRelax = value;
break;
case "Running Jobs":
jsonResult.runningJobs = value;
break;
default:
// Do nothing
}
}
});
if (!jsonResult.subscription) {
jsonResult.message = msg;
}
return jsonResult;
};
exports.formatInfo = formatInfo;
const formatSubscribe = (msg) => {
return msg;
};
exports.formatSubscribe = formatSubscribe;
// works for done png image
const uriToHash = (uri) => {
return uri.split("_").pop()?.split(".")[0] ?? "";
};
exports.uriToHash = uriToHash;
// works for progress webp image
const filenameToHash = (filename) => {
return filename.split("_")[0] ?? "";
};
exports.filenameToHash = filenameToHash;
const content2progress = (content) => {
if (!content)
return "";
const spcon = content.split("<@");
if (spcon.length < 2) {
return "";
}
content = spcon[1];
const regex = /\(([^)]+)\)/; // matches the value inside the first parenthesis
const match = content.match(regex);
let progress = "";
if (match) {
if (match[1].includes('fast') || match[1].includes('relax') || match[1].includes('turbo')) {
progress = 'done';
}
else {
progress = match[1];
}
}
return progress;
};
exports.content2progress = content2progress;
// 求最大公约数
const gcd = (a, b) => b ? gcd(b, a % b) : a;
// parseAr('--ar 1080:960', '1080:960')
// '--ar 9:8'
const parseAr = (ar, arNumber) => {
if (!ar)
return '';
const arr = arNumber.split(':');
const a = Number(arr[0]);
const b = Number(arr[1]);
const gb = gcd(a, b);
return `--ar ${a / gb}:${b / gb}`;
};
// mj will parse prompt like put url into shortlink <shorurl>, and transform ar
const parsePrompt = (prompt = '') => {
return prompt.replace(/^<[^<]+>\s/, '')
// --ar 40:20 will be transformed into --ar 2:1
.replace(/--ar ([\S]+)/i, parseAr);
};
const content2prompt = (content) => {
if (!content)
return "";
const pattern = /\*\*(.*?)\*\*/; // Match **middle content
const matches = content.match(pattern);
if (matches && matches.length > 1 && matches[1]) {
const prompt = matches[1]; // Get the matched content
// url will be transformed into <short url>
return parsePrompt(prompt);
}
else {
console.log("No match found.", content);
return parsePrompt(content);
}
};
exports.content2prompt = content2prompt;
function custom2Type(custom) {
if (custom.includes("upsample")) {
return "upscale";
}
else if (custom.includes("variation")) {
const list = custom.split('::');
return list[2] || "variation";
}
else if (custom.includes("reroll")) {
return "reroll";
}
else if (custom.includes("CustomZoom")) {
return "customZoom";
}
else if (custom.includes("Outpaint")) {
return "outpaint";
}
else if (custom.includes("remaster")) {
return "reroll";
}
else if (custom.includes("pan_")) {
return "pan";
}
else {
const list = custom.split('::');
return list[2];
}
}
exports.custom2Type = custom2Type;
const toRemixCustom = (customID) => {
const parts = customID.split("::");
const convertedString = `MJ::RemixModal::${parts[4]}::${parts[3]}::0`;
return convertedString;
};
exports.toRemixCustom = toRemixCustom;
async function base64ToBlob(base64Image) {
// 移除 base64 图像头部信息
const base64Data = base64Image.replace(/^data:image\/(png|jpeg|jpg);base64,/, "");
// 将 base64 数据解码为二进制数据
const binaryData = atob(base64Data);
// 创建一个 Uint8Array 来存储二进制数据
const arrayBuffer = new ArrayBuffer(binaryData.length);
const uint8Array = new Uint8Array(arrayBuffer);
for (let i = 0; i < binaryData.length; i++) {
uint8Array[i] = binaryData.charCodeAt(i);
}
// 使用 Uint8Array 创建 Blob 对象
return new Blob([uint8Array], { type: "image/png" }); // 替换为相应的 MIME 类型
}
exports.base64ToBlob = base64ToBlob;
//# sourceMappingURL=index.js.map