@anakonn/ankk 0.1.2 → 0.1.3
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 +238 -66
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2157,7 +2157,7 @@ var {
|
|
|
2157
2157
|
// package.json
|
|
2158
2158
|
var package_default = {
|
|
2159
2159
|
name: "@anakonn/ankk",
|
|
2160
|
-
version: "0.1.
|
|
2160
|
+
version: "0.1.3",
|
|
2161
2161
|
description: "Bun-first CLI for the ankk public API.",
|
|
2162
2162
|
private: false,
|
|
2163
2163
|
license: "UNLICENSED",
|
|
@@ -2697,12 +2697,171 @@ var configureCommanderOutput = (program2, io) => {
|
|
|
2697
2697
|
};
|
|
2698
2698
|
var isSuccessfulCommanderExit = (error) => typeof error === "object" && error !== null && ("exitCode" in error) && error.exitCode === 0;
|
|
2699
2699
|
|
|
2700
|
+
// src/brand-image-upload.ts
|
|
2701
|
+
import { readFile, stat } from "fs/promises";
|
|
2702
|
+
import { basename } from "path";
|
|
2703
|
+
|
|
2704
|
+
// src/output.ts
|
|
2705
|
+
var defaultIo = {
|
|
2706
|
+
stderr: process.stderr,
|
|
2707
|
+
stdout: process.stdout
|
|
2708
|
+
};
|
|
2709
|
+
var writeOutput = (io, mode, value, human) => {
|
|
2710
|
+
if (mode === "json") {
|
|
2711
|
+
io.stdout.write(`${JSON.stringify(value, null, 2)}
|
|
2712
|
+
`);
|
|
2713
|
+
return;
|
|
2714
|
+
}
|
|
2715
|
+
io.stdout.write(`${human}
|
|
2716
|
+
`);
|
|
2717
|
+
};
|
|
2718
|
+
var writeError = (io, error, mode = "human") => {
|
|
2719
|
+
if (mode === "json") {
|
|
2720
|
+
io.stderr.write(`${JSON.stringify(errorJson(error), null, 2)}
|
|
2721
|
+
`);
|
|
2722
|
+
return;
|
|
2723
|
+
}
|
|
2724
|
+
if (error instanceof CliHttpError) {
|
|
2725
|
+
io.stderr.write(`${error.message}
|
|
2726
|
+
`);
|
|
2727
|
+
return;
|
|
2728
|
+
}
|
|
2729
|
+
if (error instanceof Error) {
|
|
2730
|
+
io.stderr.write(`${error.message}
|
|
2731
|
+
`);
|
|
2732
|
+
return;
|
|
2733
|
+
}
|
|
2734
|
+
io.stderr.write(`Unexpected CLI error.
|
|
2735
|
+
`);
|
|
2736
|
+
};
|
|
2737
|
+
var errorJson = (error) => {
|
|
2738
|
+
if (error instanceof CliHttpError) {
|
|
2739
|
+
const body = error.body && typeof error.body === "object" && !Array.isArray(error.body) ? error.body : {};
|
|
2740
|
+
return {
|
|
2741
|
+
error: "http_error",
|
|
2742
|
+
message: error.message,
|
|
2743
|
+
...body,
|
|
2744
|
+
status: error.status
|
|
2745
|
+
};
|
|
2746
|
+
}
|
|
2747
|
+
if (error instanceof Error) {
|
|
2748
|
+
return {
|
|
2749
|
+
error: "cli_error",
|
|
2750
|
+
message: error.message
|
|
2751
|
+
};
|
|
2752
|
+
}
|
|
2753
|
+
return {
|
|
2754
|
+
error: "unexpected_cli_error",
|
|
2755
|
+
message: "Unexpected CLI error."
|
|
2756
|
+
};
|
|
2757
|
+
};
|
|
2758
|
+
|
|
2759
|
+
// src/brand-image-upload.ts
|
|
2760
|
+
var runBrandImageUploadCommand = async ({
|
|
2761
|
+
alt,
|
|
2762
|
+
brandRef,
|
|
2763
|
+
client,
|
|
2764
|
+
contentType,
|
|
2765
|
+
description,
|
|
2766
|
+
fetch,
|
|
2767
|
+
file,
|
|
2768
|
+
io,
|
|
2769
|
+
outputMode,
|
|
2770
|
+
type
|
|
2771
|
+
}) => {
|
|
2772
|
+
const upload = await readBrandImageUploadFile(file, contentType);
|
|
2773
|
+
const prepared = responseOrThrow(await client.POST("/v1/brand-images/uploads", {
|
|
2774
|
+
body: {
|
|
2775
|
+
brand_ref: brandRef,
|
|
2776
|
+
content_type: upload.contentType,
|
|
2777
|
+
filename: upload.filename,
|
|
2778
|
+
size: upload.size
|
|
2779
|
+
}
|
|
2780
|
+
}));
|
|
2781
|
+
const uploaded = await fetch(prepared.upload_url, {
|
|
2782
|
+
body: upload.data,
|
|
2783
|
+
headers: {
|
|
2784
|
+
"content-type": prepared.content_type
|
|
2785
|
+
},
|
|
2786
|
+
method: prepared.method
|
|
2787
|
+
});
|
|
2788
|
+
if (!uploaded.ok) {
|
|
2789
|
+
throw new Error(`Brand image upload failed with HTTP ${uploaded.status}.`);
|
|
2790
|
+
}
|
|
2791
|
+
const image = responseOrThrow(await client.POST("/v1/brand-images", {
|
|
2792
|
+
body: {
|
|
2793
|
+
brand_ref: brandRef,
|
|
2794
|
+
origin_url: prepared.origin_url,
|
|
2795
|
+
...type ? { type } : {},
|
|
2796
|
+
...alt !== undefined ? { alt } : {},
|
|
2797
|
+
...description !== undefined ? { description } : {}
|
|
2798
|
+
}
|
|
2799
|
+
}));
|
|
2800
|
+
writeOutput(io, outputMode, {
|
|
2801
|
+
...image,
|
|
2802
|
+
uploaded: true
|
|
2803
|
+
}, `image_ref: ${image.image_ref}
|
|
2804
|
+
url: ${image.url}`);
|
|
2805
|
+
};
|
|
2806
|
+
var brandImageUploadPolicies = {
|
|
2807
|
+
".gif": { contentType: "image/gif", maxSize: 20 * 1024 * 1024 },
|
|
2808
|
+
".jpeg": { contentType: "image/jpeg", maxSize: 20 * 1024 * 1024 },
|
|
2809
|
+
".jpg": { contentType: "image/jpeg", maxSize: 20 * 1024 * 1024 },
|
|
2810
|
+
".png": { contentType: "image/png", maxSize: 20 * 1024 * 1024 },
|
|
2811
|
+
".webp": { contentType: "image/webp", maxSize: 20 * 1024 * 1024 }
|
|
2812
|
+
};
|
|
2813
|
+
var readBrandImageUploadFile = async (file, contentTypeOverride) => {
|
|
2814
|
+
const filename = basename(file);
|
|
2815
|
+
const extension = brandImageExtension(filename);
|
|
2816
|
+
const extensionPolicy = brandImageUploadPolicies[extension];
|
|
2817
|
+
const contentType = contentTypeOverride?.trim().toLowerCase() || extensionPolicy.contentType;
|
|
2818
|
+
const contentTypePolicy = brandImageUploadPolicyForContentType(contentType);
|
|
2819
|
+
if (!contentTypePolicy) {
|
|
2820
|
+
throw new Error(`Unsupported brand image content type: ${contentType}`);
|
|
2821
|
+
}
|
|
2822
|
+
if (!contentTypePolicy.extensions.includes(extension)) {
|
|
2823
|
+
throw new Error(`Brand image file extension does not match content type: ${filename} (${contentType})`);
|
|
2824
|
+
}
|
|
2825
|
+
const info = await stat(file);
|
|
2826
|
+
if (!info.isFile()) {
|
|
2827
|
+
throw new Error(`Brand image path is not a file: ${file}`);
|
|
2828
|
+
}
|
|
2829
|
+
if (info.size <= 0) {
|
|
2830
|
+
throw new Error("Brand image file is empty.");
|
|
2831
|
+
}
|
|
2832
|
+
if (info.size > contentTypePolicy.maxSize) {
|
|
2833
|
+
throw new Error(`Brand image file exceeds ${contentTypePolicy.maxSize} bytes.`);
|
|
2834
|
+
}
|
|
2835
|
+
return {
|
|
2836
|
+
contentType,
|
|
2837
|
+
data: await readFile(file),
|
|
2838
|
+
filename,
|
|
2839
|
+
size: info.size
|
|
2840
|
+
};
|
|
2841
|
+
};
|
|
2842
|
+
var brandImageExtension = (filename) => {
|
|
2843
|
+
const index = filename.lastIndexOf(".");
|
|
2844
|
+
const extension = index > 0 ? filename.slice(index).toLowerCase() : "";
|
|
2845
|
+
if (extension in brandImageUploadPolicies)
|
|
2846
|
+
return extension;
|
|
2847
|
+
throw new Error(`Unsupported brand image file extension: ${filename}`);
|
|
2848
|
+
};
|
|
2849
|
+
var brandImageUploadPolicyForContentType = (contentType) => {
|
|
2850
|
+
const extensions = Object.entries(brandImageUploadPolicies).filter(([, policy]) => policy.contentType === contentType).map(([extension]) => extension);
|
|
2851
|
+
if (extensions.length === 0)
|
|
2852
|
+
return null;
|
|
2853
|
+
return {
|
|
2854
|
+
extensions,
|
|
2855
|
+
maxSize: brandImageUploadPolicies[extensions[0] ?? ".jpg"].maxSize
|
|
2856
|
+
};
|
|
2857
|
+
};
|
|
2858
|
+
|
|
2700
2859
|
// src/config-command.ts
|
|
2701
2860
|
import { createInterface } from "readline/promises";
|
|
2702
2861
|
import { Writable } from "stream";
|
|
2703
2862
|
|
|
2704
2863
|
// src/config.ts
|
|
2705
|
-
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
2864
|
+
import { mkdir, readFile as readFile2, writeFile } from "fs/promises";
|
|
2706
2865
|
import { dirname, join } from "path";
|
|
2707
2866
|
|
|
2708
2867
|
// ../../node_modules/.bun/zod@4.4.3/node_modules/zod/v4/classic/external.js
|
|
@@ -16999,7 +17158,7 @@ var defaultConfigPath = ({
|
|
|
16999
17158
|
};
|
|
17000
17159
|
var loadConfig = async (path) => {
|
|
17001
17160
|
try {
|
|
17002
|
-
const raw = await
|
|
17161
|
+
const raw = await readFile2(path, "utf8");
|
|
17003
17162
|
return configSchema.parse(JSON.parse(raw));
|
|
17004
17163
|
} catch (error51) {
|
|
17005
17164
|
if (isMissingFileError(error51))
|
|
@@ -17009,7 +17168,7 @@ var loadConfig = async (path) => {
|
|
|
17009
17168
|
};
|
|
17010
17169
|
var configFileExists = async (path) => {
|
|
17011
17170
|
try {
|
|
17012
|
-
await
|
|
17171
|
+
await readFile2(path, "utf8");
|
|
17013
17172
|
return true;
|
|
17014
17173
|
} catch (error51) {
|
|
17015
17174
|
if (isMissingFileError(error51))
|
|
@@ -17049,61 +17208,6 @@ var redactApiKey = (apiKey) => {
|
|
|
17049
17208
|
var normalizeBaseUrl = (value) => value.replace(/\/+$/, "");
|
|
17050
17209
|
var isMissingFileError = (error51) => typeof error51 === "object" && error51 !== null && ("code" in error51) && error51.code === "ENOENT";
|
|
17051
17210
|
|
|
17052
|
-
// src/output.ts
|
|
17053
|
-
var defaultIo = {
|
|
17054
|
-
stderr: process.stderr,
|
|
17055
|
-
stdout: process.stdout
|
|
17056
|
-
};
|
|
17057
|
-
var writeOutput = (io, mode, value, human) => {
|
|
17058
|
-
if (mode === "json") {
|
|
17059
|
-
io.stdout.write(`${JSON.stringify(value, null, 2)}
|
|
17060
|
-
`);
|
|
17061
|
-
return;
|
|
17062
|
-
}
|
|
17063
|
-
io.stdout.write(`${human}
|
|
17064
|
-
`);
|
|
17065
|
-
};
|
|
17066
|
-
var writeError = (io, error51, mode = "human") => {
|
|
17067
|
-
if (mode === "json") {
|
|
17068
|
-
io.stderr.write(`${JSON.stringify(errorJson(error51), null, 2)}
|
|
17069
|
-
`);
|
|
17070
|
-
return;
|
|
17071
|
-
}
|
|
17072
|
-
if (error51 instanceof CliHttpError) {
|
|
17073
|
-
io.stderr.write(`${error51.message}
|
|
17074
|
-
`);
|
|
17075
|
-
return;
|
|
17076
|
-
}
|
|
17077
|
-
if (error51 instanceof Error) {
|
|
17078
|
-
io.stderr.write(`${error51.message}
|
|
17079
|
-
`);
|
|
17080
|
-
return;
|
|
17081
|
-
}
|
|
17082
|
-
io.stderr.write(`Unexpected CLI error.
|
|
17083
|
-
`);
|
|
17084
|
-
};
|
|
17085
|
-
var errorJson = (error51) => {
|
|
17086
|
-
if (error51 instanceof CliHttpError) {
|
|
17087
|
-
const body = error51.body && typeof error51.body === "object" && !Array.isArray(error51.body) ? error51.body : {};
|
|
17088
|
-
return {
|
|
17089
|
-
error: "http_error",
|
|
17090
|
-
message: error51.message,
|
|
17091
|
-
...body,
|
|
17092
|
-
status: error51.status
|
|
17093
|
-
};
|
|
17094
|
-
}
|
|
17095
|
-
if (error51 instanceof Error) {
|
|
17096
|
-
return {
|
|
17097
|
-
error: "cli_error",
|
|
17098
|
-
message: error51.message
|
|
17099
|
-
};
|
|
17100
|
-
}
|
|
17101
|
-
return {
|
|
17102
|
-
error: "unexpected_cli_error",
|
|
17103
|
-
message: "Unexpected CLI error."
|
|
17104
|
-
};
|
|
17105
|
-
};
|
|
17106
|
-
|
|
17107
17211
|
// src/config-command.ts
|
|
17108
17212
|
var registerConfigCommands = ({
|
|
17109
17213
|
env,
|
|
@@ -17359,9 +17463,9 @@ var formatSnsContent = (response) => {
|
|
|
17359
17463
|
};
|
|
17360
17464
|
|
|
17361
17465
|
// src/json-input.ts
|
|
17362
|
-
import { readFile as
|
|
17466
|
+
import { readFile as readFile3 } from "fs/promises";
|
|
17363
17467
|
var readJsonInput = async (path, { readStdin = readProcessStdin } = {}) => {
|
|
17364
|
-
const raw = path === "-" ? await readStdin() : await
|
|
17468
|
+
const raw = path === "-" ? await readStdin() : await readFile3(path, "utf8");
|
|
17365
17469
|
try {
|
|
17366
17470
|
return JSON.parse(raw);
|
|
17367
17471
|
} catch (error51) {
|
|
@@ -17374,8 +17478,8 @@ var readJsonInput = async (path, { readStdin = readProcessStdin } = {}) => {
|
|
|
17374
17478
|
var readProcessStdin = async () => Bun.stdin.text();
|
|
17375
17479
|
|
|
17376
17480
|
// src/media-upload.ts
|
|
17377
|
-
import { readFile as
|
|
17378
|
-
import { basename } from "path";
|
|
17481
|
+
import { readFile as readFile4, stat as stat2 } from "fs/promises";
|
|
17482
|
+
import { basename as basename2 } from "path";
|
|
17379
17483
|
var runMediaUploadCommand = async ({
|
|
17380
17484
|
brandRef,
|
|
17381
17485
|
client,
|
|
@@ -17420,7 +17524,7 @@ var mediaUploadPolicies = {
|
|
|
17420
17524
|
".webp": { contentType: "image/webp", maxSize: 20 * 1024 * 1024 }
|
|
17421
17525
|
};
|
|
17422
17526
|
var readMediaUploadFile = async (file2, contentTypeOverride) => {
|
|
17423
|
-
const filename =
|
|
17527
|
+
const filename = basename2(file2);
|
|
17424
17528
|
const extension = mediaExtension(filename);
|
|
17425
17529
|
const extensionPolicy = mediaUploadPolicies[extension];
|
|
17426
17530
|
const contentType = contentTypeOverride?.trim().toLowerCase() || extensionPolicy.contentType;
|
|
@@ -17431,7 +17535,7 @@ var readMediaUploadFile = async (file2, contentTypeOverride) => {
|
|
|
17431
17535
|
if (!contentTypePolicy.extensions.includes(extension)) {
|
|
17432
17536
|
throw new Error(`Media file extension does not match content type: ${filename} (${contentType})`);
|
|
17433
17537
|
}
|
|
17434
|
-
const info = await
|
|
17538
|
+
const info = await stat2(file2);
|
|
17435
17539
|
if (!info.isFile()) {
|
|
17436
17540
|
throw new Error(`Media path is not a file: ${file2}`);
|
|
17437
17541
|
}
|
|
@@ -17443,7 +17547,7 @@ var readMediaUploadFile = async (file2, contentTypeOverride) => {
|
|
|
17443
17547
|
}
|
|
17444
17548
|
return {
|
|
17445
17549
|
contentType,
|
|
17446
|
-
data: await
|
|
17550
|
+
data: await readFile4(file2),
|
|
17447
17551
|
filename,
|
|
17448
17552
|
size: info.size
|
|
17449
17553
|
};
|
|
@@ -17639,6 +17743,68 @@ var createProgram = ({
|
|
|
17639
17743
|
outputMode: context.outputMode
|
|
17640
17744
|
});
|
|
17641
17745
|
});
|
|
17746
|
+
const brandImages = program2.command("brand-images").description("Manage brand images shown in the web brand image screen");
|
|
17747
|
+
withBrandRef(brandImages.command("list").description("List brand images")).option("--type <type>", "Image type filter: logo, banner, product, gallery, other").action(async (options) => {
|
|
17748
|
+
const context = await resolveCommandContext({ env, fetch, io, program: program2 });
|
|
17749
|
+
const type = options.type ? parseBrandImageType(options.type) : undefined;
|
|
17750
|
+
const result = responseOrThrow(await context.client.GET("/v1/brand-images", {
|
|
17751
|
+
params: {
|
|
17752
|
+
query: {
|
|
17753
|
+
brand_ref: options.brandRef,
|
|
17754
|
+
...type ? { type } : {}
|
|
17755
|
+
}
|
|
17756
|
+
}
|
|
17757
|
+
}));
|
|
17758
|
+
writeOutput(context.io, context.outputMode, result, formatGenericRead(result));
|
|
17759
|
+
});
|
|
17760
|
+
withBrandRef(brandImages.command("upload").description("Upload and register a brand image").argument("<file>", "Image file path")).option("--type <type>", "Image type: logo, banner, product, gallery, other").option("--alt <text>", "Alternative text").option("--description <text>", "Image description").option("--content-type <content_type>", "Override detected MIME type").action(async (file2, options) => {
|
|
17761
|
+
const context = await resolveCommandContext({ env, fetch, io, program: program2 });
|
|
17762
|
+
await runBrandImageUploadCommand({
|
|
17763
|
+
alt: options.alt,
|
|
17764
|
+
brandRef: options.brandRef,
|
|
17765
|
+
client: context.client,
|
|
17766
|
+
contentType: options.contentType,
|
|
17767
|
+
description: options.description,
|
|
17768
|
+
fetch,
|
|
17769
|
+
file: file2,
|
|
17770
|
+
io: context.io,
|
|
17771
|
+
outputMode: context.outputMode,
|
|
17772
|
+
type: options.type ? parseBrandImageType(options.type) : undefined
|
|
17773
|
+
});
|
|
17774
|
+
});
|
|
17775
|
+
withBrandRef(brandImages.command("update").description("Update brand image metadata").argument("<image_ref>", "Brand image reference")).option("--type <type>", "Image type: logo, banner, product, gallery, other").option("--alt <text>", "Alternative text").option("--description <text>", "Image description").action(async (imageRef, options) => {
|
|
17776
|
+
const context = await resolveCommandContext({ env, fetch, io, program: program2 });
|
|
17777
|
+
const result = responseOrThrow(await context.client.PATCH("/v1/brand-images/{image_ref}", {
|
|
17778
|
+
body: apiBody({
|
|
17779
|
+
...options.type ? { type: parseBrandImageType(options.type) } : {},
|
|
17780
|
+
...options.alt !== undefined ? { alt: options.alt } : {},
|
|
17781
|
+
...options.description !== undefined ? { description: options.description } : {}
|
|
17782
|
+
}),
|
|
17783
|
+
params: {
|
|
17784
|
+
path: {
|
|
17785
|
+
image_ref: imageRef
|
|
17786
|
+
},
|
|
17787
|
+
query: {
|
|
17788
|
+
brand_ref: options.brandRef
|
|
17789
|
+
}
|
|
17790
|
+
}
|
|
17791
|
+
}));
|
|
17792
|
+
writeOutput(context.io, context.outputMode, result, `Brand image updated: ${result.image_ref}`);
|
|
17793
|
+
});
|
|
17794
|
+
withBrandRef(brandImages.command("delete").description("Delete brand image metadata").argument("<image_ref>", "Brand image reference")).action(async (imageRef, options) => {
|
|
17795
|
+
const context = await resolveCommandContext({ env, fetch, io, program: program2 });
|
|
17796
|
+
const result = responseOrThrow(await context.client.DELETE("/v1/brand-images/{image_ref}", {
|
|
17797
|
+
params: {
|
|
17798
|
+
path: {
|
|
17799
|
+
image_ref: imageRef
|
|
17800
|
+
},
|
|
17801
|
+
query: {
|
|
17802
|
+
brand_ref: options.brandRef
|
|
17803
|
+
}
|
|
17804
|
+
}
|
|
17805
|
+
}));
|
|
17806
|
+
writeOutput(context.io, context.outputMode, result, `Brand image deleted: ${result.image_ref}`);
|
|
17807
|
+
});
|
|
17642
17808
|
withBrandRef(content.command("cancel").description("Cancel scheduled SNS content").argument("<content_id>", "Content id")).option("--file <path>", "JSON request body file, or - for stdin").action(async (contentId, options) => {
|
|
17643
17809
|
const context = await resolveCommandContext({ env, fetch, io, program: program2 });
|
|
17644
17810
|
const body = await readBodyOrBrandRef(options, "SNS content cancel body");
|
|
@@ -17998,6 +18164,12 @@ var readObjectBody = (value, name) => {
|
|
|
17998
18164
|
return value;
|
|
17999
18165
|
};
|
|
18000
18166
|
var apiBody = (body) => body;
|
|
18167
|
+
var brandImageTypes = ["logo", "banner", "product", "gallery", "other"];
|
|
18168
|
+
var parseBrandImageType = (value) => {
|
|
18169
|
+
if (brandImageTypes.includes(value))
|
|
18170
|
+
return value;
|
|
18171
|
+
throw new Error(`Unsupported brand image type: ${value}`);
|
|
18172
|
+
};
|
|
18001
18173
|
var readBodyOrBrandRef = async (options, name) => {
|
|
18002
18174
|
if (options.file) {
|
|
18003
18175
|
return readObjectBody(await readJsonInput(options.file), name);
|