@nogataka/imgen 0.2.0 → 0.3.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/README.md CHANGED
@@ -10,25 +10,32 @@ npm install -g @nogataka/imgen
10
10
 
11
11
  ## セットアップ
12
12
 
13
- ### 環境変数(推奨)
13
+ ### 環境変数
14
14
 
15
15
  ```bash
16
16
  export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com"
17
17
  export AZURE_OPENAI_API_KEY="your-api-key"
18
18
  export AZURE_OPENAI_DEPLOYMENT_NAME="gpt-5.1"
19
19
  export AZURE_OPENAI_DEPLOYMENT_NAME_IMAGE="gpt-image-1.5"
20
- export AZURE_OPENAI_API_VERSION="2024-02-15-preview"
21
- export AZURE_OPENAI_IMAGE_API_VERSION="2025-04-01-preview"
20
+ export AZURE_OPENAI_API_VERSION="2024-02-15-preview" # 省略可
21
+ export AZURE_OPENAI_IMAGE_API_VERSION="2025-04-01-preview" # 省略可
22
22
  ```
23
23
 
24
- ### 対話式設定
24
+ ### .env ファイル
25
+
26
+ 環境変数の代わりに `.env` ファイルで設定できます。探索順:
27
+
28
+ 1. `cwd/.env`(カレントディレクトリ)
29
+ 2. `~/.imgen/.env`
25
30
 
26
31
  ```bash
27
- imgen configure
32
+ # .env
33
+ AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com
34
+ AZURE_OPENAI_API_KEY=your-api-key
35
+ AZURE_OPENAI_DEPLOYMENT_NAME=gpt-5.1
36
+ AZURE_OPENAI_DEPLOYMENT_NAME_IMAGE=gpt-image-1.5
28
37
  ```
29
38
 
30
- Azure OpenAI の接続情報やデフォルト値を対話的に設定できます。設定は `~/.imgen/config.json` に保存されます。
31
-
32
39
  環境変数が設定されている場合、環境変数が優先されます。
33
40
 
34
41
  ## 使い方
@@ -54,7 +61,7 @@ imgen image gen "商品写真" -p builtin:landscape
54
61
  | `--output <path>` | `-o` | 出力先ファイルまたはディレクトリ | カレントディレクトリ |
55
62
  | `--json` | | JSON 形式で出力 | - |
56
63
  | `--dry-run` | | API を呼ばずに設定を確認 | - |
57
- | `--debug` | `-d` | デバッグログを有効化 | - |
64
+ | `--debug` | `-d` | デバッグ情報を表示 | - |
58
65
 
59
66
  ### 画像編集
60
67
 
@@ -95,11 +102,7 @@ imgen image explain chart.png -c "Q4 sales report" -f json -o description.json
95
102
 
96
103
  対応言語: `ja`(日本語), `en`(英語), `zh`(中国語), `ko`(韓国語), `es`(スペイン語), `fr`(フランス語), `de`(ドイツ語), `it`(イタリア語), `ru`(ロシア語), `vi`(ベトナム語)
97
104
 
98
- ## プリセット
99
-
100
- よく使う設定をプリセットとして保存・呼び出しできます。
101
-
102
- ### ビルトインプリセット
105
+ ## ビルトインプリセット
103
106
 
104
107
  | 名前 | サイズ | 品質 | 用途 |
105
108
  |------|--------|------|------|
@@ -109,41 +112,39 @@ imgen image explain chart.png -c "Q4 sales report" -f json -o description.json
109
112
  | `builtin:draft` | 1024x1024 | low | 下書き、プロトタイプ |
110
113
  | `builtin:photo` | 1536x1024 | high | 商品写真 |
111
114
 
112
- ### カスタムプリセット
113
-
114
- ```bash
115
- imgen preset save myhd -s 1536x1024 -q high -f png
116
- imgen preset list
117
- imgen preset delete myhd
118
- ```
115
+ ## 設定の優先順位
119
116
 
120
- プリセットは `~/.imgen/presets.json` に保存されます。
117
+ 1. CLI オプション(最優先)
118
+ 2. プリセット値(`-p` 指定時)
119
+ 3. デフォルト値
121
120
 
122
- ## ログ
121
+ ## SDK として使う
123
122
 
124
- 操作ログは `~/.imgen/logs/` JSON Lines 形式で保存されます。
123
+ imgen CLI だけでなく、Node.js ライブラリとしても利用できます。スライドジェネレーターや LLM ツールなど、他のアプリケーションから画像生成・編集・説明機能を呼び出せます。
125
124
 
126
125
  ```bash
127
- imgen log # 直近 20 件
128
- imgen log -n 50 -l debug # 直近 50 件(DEBUG 以上)
129
- imgen log -l error # エラーのみ
126
+ npm install @nogataka/imgen
130
127
  ```
131
128
 
132
- ## 設定の優先順位
129
+ ### 認証設定
133
130
 
134
- 1. CLI オプション(最優先)
135
- 2. プリセット値(`-p` 指定時)
136
- 3. 設定ファイル(`~/.imgen/config.json`)
137
- 4. デフォルト値
131
+ `getAzureConfig()` は以下の優先順位で設定を解決します:
138
132
 
139
- ## SDK として使う
133
+ 1. **環境変数**(最優先)
134
+ 2. **`.env` ファイル**(`cwd/.env` → `~/.imgen/.env`)
140
135
 
141
- imgen CLI だけでなく、Node.js ライブラリとしても利用できます。スライドジェネレーターや LLM ツールなど、他のアプリケーションから画像生成・編集・説明機能を呼び出せます。
136
+ アプリ側で `.env` ファイルを読み込んでいる場合(dotenv, Next.js 等)、そこに追記するだけで動きます:
142
137
 
143
138
  ```bash
144
- npm install @nogataka/imgen
139
+ # アプリ側の .env
140
+ AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com
141
+ AZURE_OPENAI_API_KEY=your-api-key
142
+ AZURE_OPENAI_DEPLOYMENT_NAME=gpt-5.1
143
+ AZURE_OPENAI_DEPLOYMENT_NAME_IMAGE=gpt-image-1.5
145
144
  ```
146
145
 
146
+ ### 使用例
147
+
147
148
  ```typescript
148
149
  import {
149
150
  AzureImageClient,
@@ -152,7 +153,7 @@ import {
152
153
  saveFileWithUniqueNameIfExists,
153
154
  } from "@nogataka/imgen/sdk";
154
155
 
155
- // Azure OpenAI 設定を取得(環境変数 or ~/.imgen/config.json)
156
+ // Azure OpenAI 設定を取得(環境変数 or .envファイル)
156
157
  const config = await getAzureConfig();
157
158
 
158
159
  // 画像生成
@@ -1,58 +1,45 @@
1
- // src/lang.ts
2
- var LANGUAGE_DESCRIPTIONS = {
3
- ja: "\u65E5\u672C\u8A9E",
4
- en: "\u82F1\u8A9E",
5
- zh: "\u4E2D\u56FD\u8A9E",
6
- ko: "\u97D3\u56FD\u8A9E",
7
- es: "\u30B9\u30DA\u30A4\u30F3\u8A9E",
8
- fr: "\u30D5\u30E9\u30F3\u30B9\u8A9E",
9
- de: "\u30C9\u30A4\u30C4\u8A9E",
10
- it: "\u30A4\u30BF\u30EA\u30A2\u8A9E",
11
- ru: "\u30ED\u30B7\u30A2\u8A9E",
12
- vi: "\u30D9\u30C8\u30CA\u30E0\u8A9E"
13
- };
14
-
15
1
  // src/utils/config.ts
16
2
  import * as fs from "fs/promises";
17
3
  import * as os from "os";
18
4
  import * as path from "path";
19
- var DEFAULT_CONFIG = {
20
- defaultLanguage: "ja",
21
- defaultImageSize: "1024x1024",
22
- defaultImageQuality: "high",
23
- defaultImageFormat: "png",
24
- logLevel: "info"
25
- };
26
- function getConfigDir() {
27
- return path.join(os.homedir(), ".imgen");
28
- }
29
- function getConfigPath() {
30
- return path.join(getConfigDir(), "config.json");
31
- }
32
- async function loadConfig() {
33
- try {
34
- const text = await fs.readFile(getConfigPath(), "utf-8");
35
- return JSON.parse(text);
36
- } catch {
37
- return null;
5
+ function parseEnvFile(content) {
6
+ const result = {};
7
+ for (const line of content.split("\n")) {
8
+ const trimmed = line.trim();
9
+ if (!trimmed || trimmed.startsWith("#")) continue;
10
+ const eqIndex = trimmed.indexOf("=");
11
+ if (eqIndex === -1) continue;
12
+ const key = trimmed.slice(0, eqIndex).trim();
13
+ let value = trimmed.slice(eqIndex + 1).trim();
14
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
15
+ value = value.slice(1, -1);
16
+ }
17
+ result[key] = value;
38
18
  }
19
+ return result;
39
20
  }
40
- async function saveConfig(config) {
41
- const configPath = getConfigPath();
42
- await fs.mkdir(path.dirname(configPath), { recursive: true });
43
- await fs.writeFile(configPath, JSON.stringify(config, null, 2));
21
+ async function loadEnvVars() {
22
+ const candidates = [path.join(process.cwd(), ".env"), path.join(os.homedir(), ".imgen", ".env")];
23
+ for (const envPath of candidates) {
24
+ try {
25
+ const content = await fs.readFile(envPath, "utf-8");
26
+ return parseEnvFile(content);
27
+ } catch {
28
+ }
29
+ }
30
+ return {};
44
31
  }
45
32
  async function getAzureConfig() {
46
- const config = await loadConfig();
47
- const endpoint = process.env.AZURE_OPENAI_ENDPOINT || config?.azureEndpoint;
48
- const apiKey = process.env.AZURE_OPENAI_API_KEY || config?.azureApiKey;
49
- const deploymentName = process.env.AZURE_OPENAI_DEPLOYMENT_NAME || config?.azureDeploymentName;
50
- const imageDeploymentName = process.env.AZURE_OPENAI_DEPLOYMENT_NAME_IMAGE || config?.azureImageDeploymentName;
51
- const apiVersion = process.env.AZURE_OPENAI_API_VERSION || config?.azureApiVersion || "2024-02-15-preview";
52
- const imageApiVersion = process.env.AZURE_OPENAI_IMAGE_API_VERSION || config?.azureImageApiVersion || "2025-04-01-preview";
33
+ const envVars = await loadEnvVars();
34
+ const endpoint = process.env.AZURE_OPENAI_ENDPOINT || envVars.AZURE_OPENAI_ENDPOINT;
35
+ const apiKey = process.env.AZURE_OPENAI_API_KEY || envVars.AZURE_OPENAI_API_KEY;
36
+ const deploymentName = process.env.AZURE_OPENAI_DEPLOYMENT_NAME || envVars.AZURE_OPENAI_DEPLOYMENT_NAME;
37
+ const imageDeploymentName = process.env.AZURE_OPENAI_DEPLOYMENT_NAME_IMAGE || envVars.AZURE_OPENAI_DEPLOYMENT_NAME_IMAGE;
38
+ const apiVersion = process.env.AZURE_OPENAI_API_VERSION || envVars.AZURE_OPENAI_API_VERSION || "2024-02-15-preview";
39
+ const imageApiVersion = process.env.AZURE_OPENAI_IMAGE_API_VERSION || envVars.AZURE_OPENAI_IMAGE_API_VERSION || "2025-04-01-preview";
53
40
  if (!endpoint || !apiKey || !deploymentName || !imageDeploymentName) {
54
41
  throw new Error(
55
- "Azure OpenAI \u306E\u8A2D\u5B9A\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002`imgen configure` \u30B3\u30DE\u30F3\u30C9\u3067\u8A2D\u5B9A\u3059\u308B\u304B\u3001\u74B0\u5883\u5909\u6570\u3092\u8A2D\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002"
42
+ "Azure OpenAI \u306E\u8A2D\u5B9A\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002\u74B0\u5883\u5909\u6570\u307E\u305F\u306F .env \u30D5\u30A1\u30A4\u30EB\u3067\u8A2D\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002"
56
43
  );
57
44
  }
58
45
  return { endpoint, apiKey, deploymentName, imageDeploymentName, apiVersion, imageApiVersion };
@@ -112,157 +99,9 @@ async function fileExists(filePath) {
112
99
 
113
100
  // src/utils/azure-chat.ts
114
101
  import { AzureOpenAI } from "openai";
115
-
116
- // src/utils/logger.ts
117
- import * as fs3 from "fs/promises";
118
- import * as path2 from "path";
119
- import * as os2 from "os";
120
- import { format } from "date-fns";
121
- var Logger = class _Logger {
122
- constructor(name) {
123
- this.name = name;
124
- const home = os2.homedir();
125
- this.logDir = path2.join(home, ".imgen", "logs");
126
- this.currentLogFile = this.generateLogFileName();
127
- }
128
- static instances = /* @__PURE__ */ new Map();
129
- static globalConfig = {
130
- destination: "CONSOLE" /* CONSOLE */,
131
- minLevel: "INFO" /* INFO */
132
- };
133
- static currentContext = "default";
134
- logDir;
135
- currentLogFile;
136
- static setGlobalConfig(config) {
137
- _Logger.globalConfig = { ..._Logger.globalConfig, ...config };
138
- }
139
- static setContext(name) {
140
- _Logger.currentContext = name;
141
- }
142
- static getInstance(options) {
143
- const { name } = options;
144
- if (!_Logger.instances.has(name)) {
145
- _Logger.instances.set(name, new _Logger(name));
146
- }
147
- return _Logger.instances.get(name);
148
- }
149
- generateLogFileName() {
150
- return path2.join(this.logDir, `${this.name}-${format(/* @__PURE__ */ new Date(), "yyyy-MM-dd")}.log`);
151
- }
152
- async ensureLogDirectory() {
153
- await fs3.mkdir(this.logDir, { recursive: true });
154
- }
155
- formatLogEntry(level, message, data) {
156
- return { timestamp: (/* @__PURE__ */ new Date()).toISOString(), level, message, data };
157
- }
158
- shouldLog(level) {
159
- const priority = {
160
- ["DEBUG" /* DEBUG */]: 0,
161
- ["INFO" /* INFO */]: 1,
162
- ["WARN" /* WARN */]: 2,
163
- ["ERROR" /* ERROR */]: 3
164
- };
165
- return priority[level] >= priority[_Logger.globalConfig.minLevel];
166
- }
167
- async writeLog(entry) {
168
- if (!this.shouldLog(entry.level)) return;
169
- const { destination } = _Logger.globalConfig;
170
- if (destination === "CONSOLE" /* CONSOLE */ || destination === "BOTH" /* BOTH */) {
171
- this.writeToConsole(entry);
172
- }
173
- if (destination === "FILE" /* FILE */ || destination === "BOTH" /* BOTH */) {
174
- await this.writeToFile(entry);
175
- }
176
- }
177
- writeToConsole(entry) {
178
- const ts = entry.timestamp.replace("T", " ").replace(/\.\d+Z$/, "");
179
- const dataStr = entry.data ? ` ${JSON.stringify(entry.data)}` : "";
180
- const msg = `[${ts}] [${this.name}] [${entry.level}] ${entry.message}${dataStr}`;
181
- switch (entry.level) {
182
- case "DEBUG" /* DEBUG */:
183
- console.debug(msg);
184
- break;
185
- case "INFO" /* INFO */:
186
- console.info(msg);
187
- break;
188
- case "WARN" /* WARN */:
189
- console.warn(msg);
190
- break;
191
- case "ERROR" /* ERROR */:
192
- console.error(msg);
193
- break;
194
- }
195
- }
196
- async writeToFile(entry) {
197
- await this.ensureLogDirectory();
198
- try {
199
- await fs3.appendFile(this.currentLogFile, JSON.stringify(entry) + "\n");
200
- } catch (error) {
201
- console.error(
202
- `\u30ED\u30B0\u306E\u66F8\u304D\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${error instanceof Error ? error.message : String(error)}`
203
- );
204
- }
205
- }
206
- debug(message, data) {
207
- return this.writeLog(this.formatLogEntry("DEBUG" /* DEBUG */, message, data));
208
- }
209
- info(message, data) {
210
- return this.writeLog(this.formatLogEntry("INFO" /* INFO */, message, data));
211
- }
212
- warn(message, data) {
213
- return this.writeLog(this.formatLogEntry("WARN" /* WARN */, message, data));
214
- }
215
- error(message, data) {
216
- return this.writeLog(this.formatLogEntry("ERROR" /* ERROR */, message, data));
217
- }
218
- static debug(message, data) {
219
- return _Logger.getInstance({ name: _Logger.currentContext }).debug(message, data);
220
- }
221
- static info(message, data) {
222
- return _Logger.getInstance({ name: _Logger.currentContext }).info(message, data);
223
- }
224
- static warn(message, data) {
225
- return _Logger.getInstance({ name: _Logger.currentContext }).warn(message, data);
226
- }
227
- static error(message, data) {
228
- return _Logger.getInstance({ name: _Logger.currentContext }).error(message, data);
229
- }
230
- getLatestLogFilePath() {
231
- return this.currentLogFile;
232
- }
233
- async getLogEntries(minLevel = "INFO" /* INFO */, maxEntries = 100) {
234
- try {
235
- await this.ensureLogDirectory();
236
- const content = await fs3.readFile(this.currentLogFile, "utf-8");
237
- const lines = content.trim().split("\n");
238
- const priority = {
239
- ["DEBUG" /* DEBUG */]: 0,
240
- ["INFO" /* INFO */]: 1,
241
- ["WARN" /* WARN */]: 2,
242
- ["ERROR" /* ERROR */]: 3
243
- };
244
- const entries = [];
245
- for (let i = lines.length - 1; i >= 0 && entries.length < maxEntries; i--) {
246
- try {
247
- const entry = JSON.parse(lines[i]);
248
- if (priority[entry.level] >= priority[minLevel]) entries.unshift(entry);
249
- } catch {
250
- continue;
251
- }
252
- }
253
- return entries;
254
- } catch (error) {
255
- if (error.code === "ENOENT") return [];
256
- throw error;
257
- }
258
- }
259
- };
260
-
261
- // src/utils/azure-chat.ts
262
102
  var AzureChatClient = class {
263
103
  client;
264
104
  deploymentName;
265
- logger;
266
105
  constructor(config) {
267
106
  this.client = new AzureOpenAI({
268
107
  endpoint: config.endpoint,
@@ -271,7 +110,6 @@ var AzureChatClient = class {
271
110
  deployment: config.deploymentName
272
111
  });
273
112
  this.deploymentName = config.deploymentName;
274
- this.logger = Logger.getInstance({ name: "azure-chat" });
275
113
  }
276
114
  /**
277
115
  * Generates a detailed image-generation prompt from a short theme description.
@@ -304,8 +142,7 @@ Prompt:
304
142
  messages: [{ role: "user", content: prompt }]
305
143
  });
306
144
  return response.choices[0]?.message?.content ?? "";
307
- } catch (error) {
308
- this.logger.error("\u30D7\u30ED\u30F3\u30D7\u30C8\u751F\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F", { error });
145
+ } catch {
309
146
  throw new Error("\u30D7\u30ED\u30F3\u30D7\u30C8\u306E\u751F\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F");
310
147
  }
311
148
  }
@@ -332,8 +169,7 @@ Prompt:
332
169
  fileName = fileName.toLowerCase().replace(/[^a-z0-9-]/g, "").replace(/-+/g, "-").replace(/^-|-$/g, "");
333
170
  if (fileName.length > maxLength) fileName = fileName.substring(0, maxLength);
334
171
  return fileName || "image";
335
- } catch (error) {
336
- this.logger.error("\u30D5\u30A1\u30A4\u30EB\u540D\u751F\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F", { error });
172
+ } catch {
337
173
  throw new Error("\u30D5\u30A1\u30A4\u30EB\u540D\u306E\u751F\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F");
338
174
  }
339
175
  }
@@ -365,8 +201,7 @@ ${context}` : ""}`
365
201
  ]
366
202
  });
367
203
  return response.choices[0]?.message?.content ?? "";
368
- } catch (error) {
369
- this.logger.error("\u753B\u50CF\u8AAC\u660E\u306E\u751F\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F", { error });
204
+ } catch {
370
205
  throw new Error("\u753B\u50CF\u306E\u8AAC\u660E\u751F\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F");
371
206
  }
372
207
  }
@@ -377,7 +212,6 @@ import { AzureOpenAI as AzureOpenAI2 } from "openai";
377
212
  var AzureImageClient = class {
378
213
  client;
379
214
  config;
380
- logger;
381
215
  constructor(config) {
382
216
  this.config = config;
383
217
  this.client = new AzureOpenAI2({
@@ -386,7 +220,6 @@ var AzureImageClient = class {
386
220
  apiVersion: config.imageApiVersion,
387
221
  deployment: config.imageDeploymentName
388
222
  });
389
- this.logger = Logger.getInstance({ name: "azure-image" });
390
223
  }
391
224
  /**
392
225
  * Generates an image from a text prompt using the Azure OpenAI SDK.
@@ -394,7 +227,6 @@ var AzureImageClient = class {
394
227
  */
395
228
  async generateImage(prompt, options) {
396
229
  const { size = "1024x1024", quality = "high" } = options;
397
- this.logger.debug("\u753B\u50CF\u751F\u6210\u30EA\u30AF\u30A8\u30B9\u30C8", { prompt: prompt.substring(0, 100), size, quality });
398
230
  try {
399
231
  const response = await this.client.images.generate({
400
232
  model: this.config.imageDeploymentName,
@@ -416,7 +248,6 @@ var AzureImageClient = class {
416
248
  return bytes;
417
249
  } catch (error) {
418
250
  if (error instanceof Error && error.message === "\u753B\u50CF\u30C7\u30FC\u30BF\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093") throw error;
419
- this.logger.error("\u753B\u50CF\u751F\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F", { error });
420
251
  throw new Error(
421
252
  `\u753B\u50CF\u751F\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${error instanceof Error ? error.message : String(error)}`
422
253
  );
@@ -429,7 +260,6 @@ var AzureImageClient = class {
429
260
  */
430
261
  async editImage(imageBuffer, prompt, options = {}) {
431
262
  const { size = "1024x1024" } = options;
432
- this.logger.debug("\u753B\u50CF\u7DE8\u96C6\u30EA\u30AF\u30A8\u30B9\u30C8 (REST API)", { prompt: prompt.substring(0, 100), size });
433
263
  const url = `${this.config.endpoint}/openai/deployments/${this.config.imageDeploymentName}/images/edits?api-version=${this.config.imageApiVersion}`;
434
264
  const blob = new Blob([imageBuffer], { type: "image/png" });
435
265
  const formData = new FormData();
@@ -459,7 +289,6 @@ var AzureImageClient = class {
459
289
  return bytes;
460
290
  } catch (error) {
461
291
  if (error instanceof Error && error.message === "\u753B\u50CF\u30C7\u30FC\u30BF\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093") throw error;
462
- this.logger.error("\u753B\u50CF\u7DE8\u96C6\u306B\u5931\u6557\u3057\u307E\u3057\u305F", { error });
463
292
  throw new Error(
464
293
  `\u753B\u50CF\u7DE8\u96C6\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${error instanceof Error ? error.message : String(error)}`
465
294
  );
@@ -467,11 +296,25 @@ var AzureImageClient = class {
467
296
  }
468
297
  };
469
298
 
299
+ // src/lang.ts
300
+ var LANGUAGE_DESCRIPTIONS = {
301
+ ja: "\u65E5\u672C\u8A9E",
302
+ en: "\u82F1\u8A9E",
303
+ zh: "\u4E2D\u56FD\u8A9E",
304
+ ko: "\u97D3\u56FD\u8A9E",
305
+ es: "\u30B9\u30DA\u30A4\u30F3\u8A9E",
306
+ fr: "\u30D5\u30E9\u30F3\u30B9\u8A9E",
307
+ de: "\u30C9\u30A4\u30C4\u8A9E",
308
+ it: "\u30A4\u30BF\u30EA\u30A2\u8A9E",
309
+ ru: "\u30ED\u30B7\u30A2\u8A9E",
310
+ vi: "\u30D9\u30C8\u30CA\u30E0\u8A9E"
311
+ };
312
+
470
313
  // src/utils/image.ts
471
- import * as fs4 from "fs/promises";
314
+ import * as fs3 from "fs/promises";
472
315
  async function readImageFile(filePath) {
473
316
  try {
474
- const buffer = await fs4.readFile(filePath);
317
+ const buffer = await fs3.readFile(filePath);
475
318
  return {
476
319
  data: buffer.toString("base64"),
477
320
  mimeType: getMimeType(filePath)
@@ -499,8 +342,6 @@ function getMimeType(filePath) {
499
342
  }
500
343
 
501
344
  // src/utils/preset.ts
502
- import * as fs5 from "fs/promises";
503
- import * as path3 from "path";
504
345
  var BUILTIN_PRESETS = {
505
346
  "builtin:square": { size: "1024x1024", quality: "high" },
506
347
  "builtin:landscape": { size: "1536x1024", quality: "high" },
@@ -508,78 +349,23 @@ var BUILTIN_PRESETS = {
508
349
  "builtin:draft": { size: "1024x1024", quality: "low" },
509
350
  "builtin:photo": { size: "1536x1024", quality: "high" }
510
351
  };
511
- function getPresetsPath() {
512
- return path3.join(getConfigDir(), "presets.json");
513
- }
514
- async function loadPresets() {
515
- try {
516
- const text = await fs5.readFile(getPresetsPath(), "utf-8");
517
- return JSON.parse(text);
518
- } catch {
519
- return {};
520
- }
521
- }
522
- async function savePresets(presets) {
523
- const p = getPresetsPath();
524
- await fs5.mkdir(path3.dirname(p), { recursive: true });
525
- await fs5.writeFile(p, JSON.stringify(presets, null, 2));
526
- }
527
- async function getPreset(name) {
352
+ function getPreset(name) {
528
353
  if (name.startsWith("builtin:") && BUILTIN_PRESETS[name]) {
529
354
  return BUILTIN_PRESETS[name];
530
355
  }
531
- const presets = await loadPresets();
532
- return presets[name] || null;
533
- }
534
- async function savePreset(name, preset) {
535
- if (name.startsWith("builtin:")) {
536
- throw new Error("\u30D3\u30EB\u30C8\u30A4\u30F3\u30D7\u30EA\u30BB\u30C3\u30C8\u306F\u4E0A\u66F8\u304D\u3067\u304D\u307E\u305B\u3093");
537
- }
538
- const presets = await loadPresets();
539
- presets[name] = preset;
540
- await savePresets(presets);
541
- }
542
- async function deletePreset(name) {
543
- if (name.startsWith("builtin:")) {
544
- throw new Error("\u30D3\u30EB\u30C8\u30A4\u30F3\u30D7\u30EA\u30BB\u30C3\u30C8\u306F\u524A\u9664\u3067\u304D\u307E\u305B\u3093");
545
- }
546
- const presets = await loadPresets();
547
- if (!presets[name]) return false;
548
- delete presets[name];
549
- await savePresets(presets);
550
- return true;
551
- }
552
- async function listAllPresets() {
553
- const result = [];
554
- for (const [name, preset] of Object.entries(BUILTIN_PRESETS)) {
555
- result.push({ name, preset, builtin: true });
556
- }
557
- const presets = await loadPresets();
558
- for (const [name, preset] of Object.entries(presets)) {
559
- result.push({ name, preset, builtin: false });
560
- }
561
- return result;
356
+ return BUILTIN_PRESETS[name] || null;
562
357
  }
563
358
 
564
359
  export {
565
- LANGUAGE_DESCRIPTIONS,
566
- DEFAULT_CONFIG,
567
- getConfigPath,
568
- loadConfig,
569
- saveConfig,
570
360
  getAzureConfig,
571
361
  saveFileWithUniqueNameIfExists,
572
362
  loadContextFile,
573
363
  fileExists,
574
- Logger,
575
364
  AzureChatClient,
576
365
  AzureImageClient,
366
+ LANGUAGE_DESCRIPTIONS,
577
367
  readImageFile,
578
368
  getMimeType,
579
369
  BUILTIN_PRESETS,
580
- getPresetsPath,
581
- getPreset,
582
- savePreset,
583
- deletePreset,
584
- listAllPresets
370
+ getPreset
585
371
  };