addashboard-cli 0.2.4
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 +48 -0
- package/dist/commands/ads.js +139 -0
- package/dist/commands/ads.js.map +1 -0
- package/dist/commands/auth.js +75 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/authDevice.js +110 -0
- package/dist/commands/authDevice.js.map +1 -0
- package/dist/commands/authGoogle.js +196 -0
- package/dist/commands/authGoogle.js.map +1 -0
- package/dist/commands/freee.js +249 -0
- package/dist/commands/freee.js.map +1 -0
- package/dist/commands/submission.js +299 -0
- package/dist/commands/submission.js.map +1 -0
- package/dist/index.js +290 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/apiClient.js +86 -0
- package/dist/lib/apiClient.js.map +1 -0
- package/dist/lib/credentialStore.js +76 -0
- package/dist/lib/credentialStore.js.map +1 -0
- package/package.json +54 -0
- package/skills/ad-ops/README.md +139 -0
- package/skills/ad-ops/SKILL.md +146 -0
- package/skills/ad-ops/config.json +5 -0
- package/skills/invoice-issue-freee/README.md +109 -0
- package/skills/invoice-issue-freee/SKILL.md +190 -0
- package/skills/invoice-issue-freee/config.json +31 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const readline_1 = __importDefault(require("readline"));
|
|
9
|
+
const credentialStore_1 = require("./lib/credentialStore");
|
|
10
|
+
const auth_1 = require("./commands/auth");
|
|
11
|
+
const authGoogle_1 = require("./commands/authGoogle");
|
|
12
|
+
const authDevice_1 = require("./commands/authDevice");
|
|
13
|
+
const ads_1 = require("./commands/ads");
|
|
14
|
+
const submission_1 = require("./commands/submission");
|
|
15
|
+
const freee_1 = require("./commands/freee");
|
|
16
|
+
// 本番エンドポイント: https://macchiato.site (Lightsail 35.73.207.72)
|
|
17
|
+
// ローカル開発時は --endpoint http://localhost:3001 か WEBGRAM_ENDPOINT env で切替。
|
|
18
|
+
const DEFAULT_ENDPOINT = process.env.WEBGRAM_ENDPOINT || 'https://macchiato.site';
|
|
19
|
+
const program = new commander_1.Command();
|
|
20
|
+
program
|
|
21
|
+
.name('webgram')
|
|
22
|
+
.description('webgram CLI — ad-dashboard を Claude Code / Codex CLI から操作する')
|
|
23
|
+
.version('0.2.3');
|
|
24
|
+
const auth = program.command('auth').description('認証関連コマンド');
|
|
25
|
+
auth
|
|
26
|
+
.command('login')
|
|
27
|
+
.description('ad-dashboard にログインして access_token + refresh_token を取得する。' +
|
|
28
|
+
'デフォルトは Google アカウント(@webgram.jp)でのログイン(設定不要・クライアント ID はサーバーが提供)。' +
|
|
29
|
+
'対話環境ではブラウザ loopback、非対話環境(Claude Code 等)では自動で device flow になる。' +
|
|
30
|
+
'どうしても対話もブラウザも無理な場合のみ --password(ROPC・deprecated)')
|
|
31
|
+
.option('--endpoint <url>', 'ad-dashboard のエンドポイント', DEFAULT_ENDPOINT)
|
|
32
|
+
.option('--google', 'Google アカウントでログイン(デフォルト)')
|
|
33
|
+
.option('--device', 'device flow を強制する(TTY でも URL + コード提示方式でログイン)')
|
|
34
|
+
.option('--email <email>', 'パスワード方式のメールアドレス(省略時 prompt)')
|
|
35
|
+
.option('--password [password]', 'パスワード方式(ROPC)でログイン。値省略時は prompt(フォールバック・deprecated)')
|
|
36
|
+
.option('--client-id <id>', 'Google ログイン用 OAuth クライアント ID の上書き(通常は不要。未指定ならサーバーから取得)')
|
|
37
|
+
.action(async (opts) => {
|
|
38
|
+
const store = new credentialStore_1.CredentialStore((0, credentialStore_1.defaultConfigDir)());
|
|
39
|
+
// --google 指定、または --password 未指定なら Google 方式(デフォルト)
|
|
40
|
+
const usePassword = opts.password !== undefined && !opts.google;
|
|
41
|
+
if (!usePassword) {
|
|
42
|
+
// 非対話環境(stdout が TTY でない)または --device 指定時は device flow。
|
|
43
|
+
// それ以外(対話環境)は従来どおり loopback ブラウザフロー。
|
|
44
|
+
const useDevice = opts.device === true || !process.stdout.isTTY;
|
|
45
|
+
if (useDevice) {
|
|
46
|
+
const result = await (0, authDevice_1.runDeviceLogin)({ endpoint: opts.endpoint, store });
|
|
47
|
+
if (result.ok) {
|
|
48
|
+
const who = await (0, auth_1.runWhoami)({ store });
|
|
49
|
+
const email = who.ok && who.user ? who.user.email : undefined;
|
|
50
|
+
// eslint-disable-next-line no-console
|
|
51
|
+
console.log(email ? `✓ Logged in as ${email}` : '✓ Logged in');
|
|
52
|
+
// eslint-disable-next-line no-console
|
|
53
|
+
console.log(` Saved to ${store.dir}/credentials.json (chmod 0600)`);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
// eslint-disable-next-line no-console
|
|
57
|
+
console.error(`✗ Login failed: ${result.error}`);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// eslint-disable-next-line no-console
|
|
63
|
+
console.log('ブラウザで Google ログインを開きます…');
|
|
64
|
+
const result = await (0, authGoogle_1.runGoogleLogin)({
|
|
65
|
+
endpoint: opts.endpoint,
|
|
66
|
+
store,
|
|
67
|
+
clientId: opts.clientId,
|
|
68
|
+
});
|
|
69
|
+
if (result.ok) {
|
|
70
|
+
const who = await (0, auth_1.runWhoami)({ store });
|
|
71
|
+
const email = who.ok && who.user ? who.user.email : undefined;
|
|
72
|
+
// eslint-disable-next-line no-console
|
|
73
|
+
console.log(email ? `✓ Logged in as ${email}` : '✓ Logged in');
|
|
74
|
+
// eslint-disable-next-line no-console
|
|
75
|
+
console.log(` Saved to ${store.dir}/credentials.json (chmod 0600)`);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
if (result.authUrl) {
|
|
79
|
+
// eslint-disable-next-line no-console
|
|
80
|
+
console.error('✗ ブラウザを自動で開けませんでした。以下の URL を手動で開いてください:');
|
|
81
|
+
// eslint-disable-next-line no-console
|
|
82
|
+
console.error(` ${result.authUrl}`);
|
|
83
|
+
}
|
|
84
|
+
// eslint-disable-next-line no-console
|
|
85
|
+
console.error(`✗ Login failed: ${result.error}`);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
// ── パスワード方式(ROPC) ──
|
|
91
|
+
const email = opts.email ?? (await prompt('email: '));
|
|
92
|
+
const password = typeof opts.password === 'string' ? opts.password : await promptHidden('password: ');
|
|
93
|
+
const result = await (0, auth_1.runLogin)({
|
|
94
|
+
endpoint: opts.endpoint,
|
|
95
|
+
username: email,
|
|
96
|
+
password,
|
|
97
|
+
store,
|
|
98
|
+
});
|
|
99
|
+
if (result.ok) {
|
|
100
|
+
// eslint-disable-next-line no-console
|
|
101
|
+
console.log(`✓ Logged in as ${result.email}`);
|
|
102
|
+
// eslint-disable-next-line no-console
|
|
103
|
+
console.log(` Saved to ${store.dir}/credentials.json (chmod 0600)`);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
// eslint-disable-next-line no-console
|
|
107
|
+
console.error(`✗ Login failed: ${result.error}`);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
auth
|
|
112
|
+
.command('whoami')
|
|
113
|
+
.description('現在の access_token に紐づくユーザー情報を表示する')
|
|
114
|
+
.action(async () => {
|
|
115
|
+
const store = new credentialStore_1.CredentialStore((0, credentialStore_1.defaultConfigDir)());
|
|
116
|
+
const result = await (0, auth_1.runWhoami)({ store });
|
|
117
|
+
if (result.ok && result.user) {
|
|
118
|
+
// eslint-disable-next-line no-console
|
|
119
|
+
console.log(JSON.stringify(result.user, null, 2));
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
// eslint-disable-next-line no-console
|
|
123
|
+
console.error(`✗ ${result.error}`);
|
|
124
|
+
process.exit(1);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
auth
|
|
128
|
+
.command('logout')
|
|
129
|
+
.description('refresh_token を revoke し credentials.json を削除する')
|
|
130
|
+
.action(async () => {
|
|
131
|
+
const store = new credentialStore_1.CredentialStore((0, credentialStore_1.defaultConfigDir)());
|
|
132
|
+
await (0, auth_1.runLogout)({ store });
|
|
133
|
+
// eslint-disable-next-line no-console
|
|
134
|
+
console.log('✓ Logged out');
|
|
135
|
+
});
|
|
136
|
+
// ──────────────────────────── list / submit (v5) ────────────────────────────
|
|
137
|
+
program
|
|
138
|
+
.command('list')
|
|
139
|
+
.description('媒体のアカウント・キャンペーン・リソースを取得する (対応: meta, yda, google, smartnews, bytedance)')
|
|
140
|
+
.requiredOption('--platform <platform>', 'meta | yda | google | smartnews | bytedance')
|
|
141
|
+
.requiredOption('--resource <resource>', 'accounts | campaigns | resources (smartnews は resources 非対応)')
|
|
142
|
+
.option('--account-id <id>', '対象アカウント ID(campaigns / resources で必須)')
|
|
143
|
+
.option('--campaign-id <id>', '対象キャンペーン ID(yda + campaigns で単一CPインポート用)')
|
|
144
|
+
.action(async (opts) => {
|
|
145
|
+
const store = new credentialStore_1.CredentialStore((0, credentialStore_1.defaultConfigDir)());
|
|
146
|
+
const result = await (0, ads_1.runList)({
|
|
147
|
+
store,
|
|
148
|
+
platform: opts.platform,
|
|
149
|
+
resource: opts.resource,
|
|
150
|
+
accountId: opts.accountId,
|
|
151
|
+
campaignId: opts.campaignId,
|
|
152
|
+
});
|
|
153
|
+
if (result.ok) {
|
|
154
|
+
console.log(JSON.stringify(result.data, null, 2));
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
console.error(`✗ ${result.error}`);
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
program
|
|
162
|
+
.command('submit')
|
|
163
|
+
.description('入稿ボディ JSON を ad-dashboard 経由で媒体に POST する (dry-run がデフォルト、対応: meta, yda, google, smartnews, bytedance)')
|
|
164
|
+
.requiredOption('--platform <platform>', 'meta | yda | google | smartnews | bytedance (bytedance は operation_status=DISABLE で本実行)')
|
|
165
|
+
.requiredOption('--json-file <path>', '入稿ボディ JSON のファイルパス')
|
|
166
|
+
.option('--yes', '本実行を許可する(このフラグなしで dry-run なしの操作は exit 2 で拒否)', false)
|
|
167
|
+
.option('--no-dry-run', '本実行する (--yes も必須)')
|
|
168
|
+
.action(async (opts) => {
|
|
169
|
+
const store = new credentialStore_1.CredentialStore((0, credentialStore_1.defaultConfigDir)());
|
|
170
|
+
const result = await (0, submission_1.runSubmit)({
|
|
171
|
+
store,
|
|
172
|
+
platform: opts.platform,
|
|
173
|
+
jsonFile: opts.jsonFile,
|
|
174
|
+
dryRun: opts.dryRun !== false, // commander の --no-dry-run で false 化
|
|
175
|
+
yes: !!opts.yes,
|
|
176
|
+
});
|
|
177
|
+
if (result.ok) {
|
|
178
|
+
console.log(JSON.stringify(result.data, null, 2));
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
console.error(`✗ ${result.error}`);
|
|
182
|
+
process.exit(result.exitCode);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
// ──────────────────────────── freee 請求書 ────────────────────────────
|
|
186
|
+
const freee = program.command('freee').description('freee 請求書発行コマンド(allowlist 制限あり)');
|
|
187
|
+
freee
|
|
188
|
+
.command('login')
|
|
189
|
+
.description('freee に OAuth 認可し access/refresh token を ad-dashboard 側に保存する')
|
|
190
|
+
.action(async () => {
|
|
191
|
+
const store = new credentialStore_1.CredentialStore((0, credentialStore_1.defaultConfigDir)());
|
|
192
|
+
const result = await (0, freee_1.runFreeeLogin)({ store });
|
|
193
|
+
if (result.ok) {
|
|
194
|
+
console.log(`✓ freee 接続完了 (company_id=${result.companyId || '未確定'})`);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
console.error(`✗ freee login failed: ${result.error}`);
|
|
198
|
+
process.exit(1);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
freee
|
|
202
|
+
.command('templates')
|
|
203
|
+
.description('使用可能な freee 帳票テンプレート一覧を取得する')
|
|
204
|
+
.action(async () => {
|
|
205
|
+
const store = new credentialStore_1.CredentialStore((0, credentialStore_1.defaultConfigDir)());
|
|
206
|
+
const result = await (0, freee_1.runFreeeTemplates)({ store });
|
|
207
|
+
if (result.ok) {
|
|
208
|
+
console.log(JSON.stringify(result.data, null, 2));
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
console.error(`✗ ${result.error}`);
|
|
212
|
+
process.exit(1);
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
freee
|
|
216
|
+
.command('issue')
|
|
217
|
+
.description('請求書ボディ JSON を freee に発行し report_url を返す(dry-run がデフォルト)')
|
|
218
|
+
.requiredOption('--json-file <path>', '請求書ボディ JSON のファイルパス')
|
|
219
|
+
.option('--yes', '本実行を許可する(このフラグなしで dry-run なしの操作は exit 2 で拒否)', false)
|
|
220
|
+
.option('--no-dry-run', '本実行する (--yes も必須)')
|
|
221
|
+
.action(async (opts) => {
|
|
222
|
+
const store = new credentialStore_1.CredentialStore((0, credentialStore_1.defaultConfigDir)());
|
|
223
|
+
const result = await (0, freee_1.runFreeeIssue)({
|
|
224
|
+
store,
|
|
225
|
+
jsonFile: opts.jsonFile,
|
|
226
|
+
dryRun: opts.dryRun !== false, // commander の --no-dry-run で false 化
|
|
227
|
+
yes: !!opts.yes,
|
|
228
|
+
});
|
|
229
|
+
if (result.ok) {
|
|
230
|
+
console.log(JSON.stringify(result.data, null, 2));
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
console.error(`✗ ${result.error}`);
|
|
234
|
+
process.exit(result.exitCode);
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
program.parseAsync(process.argv).catch((err) => {
|
|
238
|
+
// eslint-disable-next-line no-console
|
|
239
|
+
console.error(err);
|
|
240
|
+
process.exit(1);
|
|
241
|
+
});
|
|
242
|
+
// ──────────────────────────── prompt helpers ────────────────────────────
|
|
243
|
+
function prompt(message) {
|
|
244
|
+
const rl = readline_1.default.createInterface({ input: process.stdin, output: process.stdout });
|
|
245
|
+
return new Promise((resolve) => {
|
|
246
|
+
rl.question(message, (answer) => {
|
|
247
|
+
rl.close();
|
|
248
|
+
resolve(answer);
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* stdin から TTY 表示を抑制してパスワードを取得する。
|
|
254
|
+
* 非 TTY (パイプ入力) 環境では通常の readline で受ける。
|
|
255
|
+
*/
|
|
256
|
+
function promptHidden(message) {
|
|
257
|
+
if (!process.stdin.isTTY)
|
|
258
|
+
return prompt(message);
|
|
259
|
+
const ETX = ''; // Ctrl+C
|
|
260
|
+
const DEL = ''; // backspace
|
|
261
|
+
const BS = '\b';
|
|
262
|
+
return new Promise((resolve) => {
|
|
263
|
+
process.stdout.write(message);
|
|
264
|
+
const stdin = process.stdin;
|
|
265
|
+
stdin.setRawMode?.(true);
|
|
266
|
+
stdin.resume();
|
|
267
|
+
let buf = '';
|
|
268
|
+
const onData = (chunk) => {
|
|
269
|
+
const c = chunk.toString('utf8');
|
|
270
|
+
if (c === '\n' || c === '\r') {
|
|
271
|
+
process.stdout.write('\n');
|
|
272
|
+
stdin.setRawMode?.(false);
|
|
273
|
+
stdin.pause();
|
|
274
|
+
stdin.off('data', onData);
|
|
275
|
+
resolve(buf);
|
|
276
|
+
}
|
|
277
|
+
else if (c === ETX) {
|
|
278
|
+
process.exit(130);
|
|
279
|
+
}
|
|
280
|
+
else if (c === DEL || c === BS) {
|
|
281
|
+
buf = buf.slice(0, -1);
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
buf += c;
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
stdin.on('data', onData);
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.buildApiClient = buildApiClient;
|
|
7
|
+
exports.buildAuthedApiClient = buildAuthedApiClient;
|
|
8
|
+
const axios_1 = __importDefault(require("axios"));
|
|
9
|
+
const DEFAULT_TIMEOUT_MS = 15000;
|
|
10
|
+
const DEFAULT_ACCEPT = 'application/json, text/event-stream';
|
|
11
|
+
/**
|
|
12
|
+
* ad-dashboard REST API を叩く axios インスタンスを生成する(auto-refresh なし)。
|
|
13
|
+
*
|
|
14
|
+
* 401 → 自動 refresh が欲しい場合は buildAuthedApiClient を使うこと。
|
|
15
|
+
* こちらは auth login / logout など、credentials 確定前のフローで使う。
|
|
16
|
+
*/
|
|
17
|
+
function buildApiClient(opts) {
|
|
18
|
+
const client = axios_1.default.create({
|
|
19
|
+
baseURL: opts.endpoint,
|
|
20
|
+
timeout: opts.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
21
|
+
headers: { Accept: DEFAULT_ACCEPT },
|
|
22
|
+
});
|
|
23
|
+
if (opts.accessToken) {
|
|
24
|
+
client.defaults.headers.common['Authorization'] = `Bearer ${opts.accessToken}`;
|
|
25
|
+
}
|
|
26
|
+
return client;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 401 を検知したら refresh_token で /api/auth/cli/refresh を叩いて新 token を取得し、
|
|
30
|
+
* credentials.json を更新したうえで元リクエストを 1 回だけ retry する axios インスタンス。
|
|
31
|
+
*
|
|
32
|
+
* 再試行も 401 / refresh 自体が 401 → 元エラーを throw(無限ループ防止)。
|
|
33
|
+
*/
|
|
34
|
+
function buildAuthedApiClient(store) {
|
|
35
|
+
const creds = store.load();
|
|
36
|
+
if (!creds)
|
|
37
|
+
throw new Error('not_logged_in');
|
|
38
|
+
const client = axios_1.default.create({
|
|
39
|
+
baseURL: creds.endpoint,
|
|
40
|
+
timeout: DEFAULT_TIMEOUT_MS,
|
|
41
|
+
headers: {
|
|
42
|
+
Accept: DEFAULT_ACCEPT,
|
|
43
|
+
Authorization: `Bearer ${creds.accessToken}`,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
client.defaults.headers.common['Authorization'] = `Bearer ${creds.accessToken}`;
|
|
47
|
+
client.interceptors.response.use((res) => res, async (err) => {
|
|
48
|
+
const original = err.config;
|
|
49
|
+
if (!original || err.response?.status !== 401 || original._retried) {
|
|
50
|
+
throw err;
|
|
51
|
+
}
|
|
52
|
+
original._retried = true;
|
|
53
|
+
// refresh
|
|
54
|
+
const current = store.load();
|
|
55
|
+
if (!current)
|
|
56
|
+
throw err;
|
|
57
|
+
let refreshed;
|
|
58
|
+
try {
|
|
59
|
+
refreshed = await axios_1.default.post(`${current.endpoint}/api/auth/cli/refresh`, { refresh_token: current.refreshToken }, {
|
|
60
|
+
timeout: DEFAULT_TIMEOUT_MS,
|
|
61
|
+
headers: { 'Content-Type': 'application/json' },
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// refresh も失敗(401 含む) → 元の 401 を投げる
|
|
66
|
+
throw err;
|
|
67
|
+
}
|
|
68
|
+
const { access_token, refresh_token, expires_in } = refreshed.data ?? {};
|
|
69
|
+
if (!access_token || !refresh_token)
|
|
70
|
+
throw err;
|
|
71
|
+
const updated = {
|
|
72
|
+
endpoint: current.endpoint,
|
|
73
|
+
accessToken: access_token,
|
|
74
|
+
refreshToken: refresh_token,
|
|
75
|
+
expiresAt: new Date(Date.now() + (expires_in ?? 3600) * 1000).toISOString(),
|
|
76
|
+
};
|
|
77
|
+
store.save(updated);
|
|
78
|
+
// retry: client.defaults と original 両方の Authorization を新値に
|
|
79
|
+
client.defaults.headers.common['Authorization'] = `Bearer ${access_token}`;
|
|
80
|
+
original.headers = original.headers ?? {};
|
|
81
|
+
original.headers['Authorization'] = `Bearer ${access_token}`;
|
|
82
|
+
return client(original);
|
|
83
|
+
});
|
|
84
|
+
return client;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=apiClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiClient.js","sourceRoot":"","sources":["../../src/lib/apiClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.CredentialStore = void 0;
|
|
7
|
+
exports.defaultConfigDir = defaultConfigDir;
|
|
8
|
+
exports.saveCredentials = saveCredentials;
|
|
9
|
+
exports.loadCredentials = loadCredentials;
|
|
10
|
+
exports.clearCredentials = clearCredentials;
|
|
11
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
|
+
const os_1 = __importDefault(require("os"));
|
|
13
|
+
const path_1 = __importDefault(require("path"));
|
|
14
|
+
/** デフォルトの保存先ディレクトリ ($XDG_CONFIG_HOME/webgram or ~/.config/webgram) */
|
|
15
|
+
function defaultConfigDir() {
|
|
16
|
+
const xdg = process.env.XDG_CONFIG_HOME;
|
|
17
|
+
if (xdg && xdg.length > 0)
|
|
18
|
+
return path_1.default.join(xdg, 'webgram');
|
|
19
|
+
return path_1.default.join(os_1.default.homedir(), '.config', 'webgram');
|
|
20
|
+
}
|
|
21
|
+
const FILE_NAME = 'credentials.json';
|
|
22
|
+
/**
|
|
23
|
+
* ファイル単位のクレデンシャル保存。chmod 0600 で保存し JSON で永続化する。
|
|
24
|
+
*
|
|
25
|
+
* インスタンスベース API も関数 API も両方提供:
|
|
26
|
+
* - new CredentialStore(dir).save() / load() / clear()
|
|
27
|
+
* - saveCredentials(creds, dir) / loadCredentials(dir) / clearCredentials(dir)
|
|
28
|
+
*/
|
|
29
|
+
class CredentialStore {
|
|
30
|
+
dir;
|
|
31
|
+
constructor(dir = defaultConfigDir()) {
|
|
32
|
+
this.dir = dir;
|
|
33
|
+
}
|
|
34
|
+
get filePath() {
|
|
35
|
+
return path_1.default.join(this.dir, FILE_NAME);
|
|
36
|
+
}
|
|
37
|
+
save(creds) {
|
|
38
|
+
fs_1.default.mkdirSync(this.dir, { recursive: true });
|
|
39
|
+
fs_1.default.writeFileSync(this.filePath, JSON.stringify(creds, null, 2), { mode: 0o600 });
|
|
40
|
+
// mode オプションは「新規作成時のみ」適用されるため、既存ファイル更新時にも 0600 を保証する
|
|
41
|
+
fs_1.default.chmodSync(this.filePath, 0o600);
|
|
42
|
+
}
|
|
43
|
+
load() {
|
|
44
|
+
if (!fs_1.default.existsSync(this.filePath))
|
|
45
|
+
return null;
|
|
46
|
+
try {
|
|
47
|
+
const raw = fs_1.default.readFileSync(this.filePath, 'utf8');
|
|
48
|
+
const parsed = JSON.parse(raw);
|
|
49
|
+
if (typeof parsed?.endpoint !== 'string' ||
|
|
50
|
+
typeof parsed?.accessToken !== 'string' ||
|
|
51
|
+
typeof parsed?.refreshToken !== 'string' ||
|
|
52
|
+
typeof parsed?.expiresAt !== 'string') {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
return parsed;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
clear() {
|
|
62
|
+
if (fs_1.default.existsSync(this.filePath))
|
|
63
|
+
fs_1.default.unlinkSync(this.filePath);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.CredentialStore = CredentialStore;
|
|
67
|
+
function saveCredentials(creds, dir = defaultConfigDir()) {
|
|
68
|
+
new CredentialStore(dir).save(creds);
|
|
69
|
+
}
|
|
70
|
+
function loadCredentials(dir = defaultConfigDir()) {
|
|
71
|
+
return new CredentialStore(dir).load();
|
|
72
|
+
}
|
|
73
|
+
function clearCredentials(dir = defaultConfigDir()) {
|
|
74
|
+
new CredentialStore(dir).clear();
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=credentialStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentialStore.js","sourceRoot":"","sources":["../../src/lib/credentialStore.ts"],"names":[],"mappings":";;;;;;AAkBA,4CAIC;AAiDD,0CAEC;AAED,0CAEC;AAED,4CAEC;AAjFD,4CAAoB;AACpB,4CAAoB;AACpB,gDAAwB;AAexB,sEAAsE;AACtE,SAAgB,gBAAgB;IAC9B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IACxC,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC5D,OAAO,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,SAAS,GAAG,kBAAkB,CAAC;AAErC;;;;;;GAMG;AACH,MAAa,eAAe;IACE;IAA5B,YAA4B,MAAc,gBAAgB,EAAE;QAAhC,QAAG,GAAH,GAAG,CAA6B;IAAG,CAAC;IAEhE,IAAY,QAAQ;QAClB,OAAO,cAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,CAAC,KAAkB;QACrB,YAAE,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,YAAE,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACjF,qDAAqD;QACrD,YAAE,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACrC,CAAC;IAED,IAAI;QACF,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,OAAO,IAAI,CAAC;QAC/C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAE,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/B,IACE,OAAO,MAAM,EAAE,QAAQ,KAAK,QAAQ;gBACpC,OAAO,MAAM,EAAE,WAAW,KAAK,QAAQ;gBACvC,OAAO,MAAM,EAAE,YAAY,KAAK,QAAQ;gBACxC,OAAO,MAAM,EAAE,SAAS,KAAK,QAAQ,EACrC,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,MAAqB,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK;QACH,IAAI,YAAE,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,YAAE,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjE,CAAC;CACF;AApCD,0CAoCC;AAED,SAAgB,eAAe,CAAC,KAAkB,EAAE,MAAc,gBAAgB,EAAE;IAClF,IAAI,eAAe,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC;AAED,SAAgB,eAAe,CAAC,MAAc,gBAAgB,EAAE;IAC9D,OAAO,IAAI,eAAe,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACzC,CAAC;AAED,SAAgB,gBAAgB,CAAC,MAAc,gBAAgB,EAAE;IAC/D,IAAI,eAAe,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC;AACnC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "addashboard-cli",
|
|
3
|
+
"version": "0.2.4",
|
|
4
|
+
"description": "webgram CLI — ad-dashboard (https://macchiato.site) を Claude Code / Codex CLI から操作するための CLI",
|
|
5
|
+
"bin": {
|
|
6
|
+
"webgram": "./dist/index.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md",
|
|
11
|
+
"skills/ad-ops/**",
|
|
12
|
+
"skills/invoice-issue-freee/**"
|
|
13
|
+
],
|
|
14
|
+
"keywords": [
|
|
15
|
+
"webgram",
|
|
16
|
+
"ad-dashboard",
|
|
17
|
+
"cli",
|
|
18
|
+
"claude-code",
|
|
19
|
+
"codex"
|
|
20
|
+
],
|
|
21
|
+
"author": "WEBGRAM / Almie",
|
|
22
|
+
"license": "UNLICENSED",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/WEBGRAM-WG/ad-dashboard.git",
|
|
26
|
+
"directory": "cli"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/WEBGRAM-WG/ad-dashboard/tree/main/cli",
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=18"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsc",
|
|
37
|
+
"dev": "tsx src/index.ts",
|
|
38
|
+
"start": "node dist/index.js",
|
|
39
|
+
"test": "vitest run",
|
|
40
|
+
"test:watch": "vitest",
|
|
41
|
+
"prepublishOnly": "npm run build"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"axios": "^1.7.7",
|
|
45
|
+
"commander": "^12.1.0"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/node": "^22.9.0",
|
|
49
|
+
"nock": "14.0.16",
|
|
50
|
+
"tsx": "^4.19.2",
|
|
51
|
+
"typescript": "^5.6.3",
|
|
52
|
+
"vitest": "^4.1.9"
|
|
53
|
+
}
|
|
54
|
+
}
|