@yuiseki/gyazocli 0.0.1

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 ADDED
@@ -0,0 +1,42 @@
1
+ # @yuiseki/gyazocli
2
+
3
+ Gyazo Memory CLI for AI Secretary.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm i -g @yuiseki/gyazocli
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```bash
14
+ gyazo config set token your_personal_gyazo_access_token_here
15
+ gyazo sync --days 10
16
+ gyazo --help
17
+ ```
18
+
19
+ ## Development
20
+
21
+ ### Build
22
+
23
+ ```bash
24
+ npm install
25
+ npm run build
26
+ ```
27
+
28
+ ### Link local CLI with npm link
29
+
30
+ ```bash
31
+ # from this repository root
32
+ npm link
33
+
34
+ # verify linked command
35
+ gyazo --version
36
+ ```
37
+
38
+ Unlink when finished:
39
+
40
+ ```bash
41
+ npm unlink -g @yuiseki/gyazocli
42
+ ```
package/dist/api.js ADDED
@@ -0,0 +1,67 @@
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.listImages = listImages;
7
+ exports.getImageDetail = getImageDetail;
8
+ exports.searchImages = searchImages;
9
+ exports.getCurrentUser = getCurrentUser;
10
+ exports.uploadImage = uploadImage;
11
+ const axios_1 = __importDefault(require("axios"));
12
+ const form_data_1 = __importDefault(require("form-data"));
13
+ const config_1 = require("./config");
14
+ const API_BASE_URL = 'https://api.gyazo.com/api/images';
15
+ const API_SEARCH_URL = 'https://api.gyazo.com/api/search';
16
+ const API_USERS_ME_URL = 'https://api.gyazo.com/api/users/me';
17
+ const API_UPLOAD_URL = 'https://upload.gyazo.com/api/upload';
18
+ async function requestWithRetry(url, params = {}) {
19
+ const headers = { Authorization: `Bearer ${config_1.config.GYAZO_ACCESS_TOKEN}` };
20
+ try {
21
+ const response = await axios_1.default.get(url, { headers, params });
22
+ return response.data;
23
+ }
24
+ catch (error) {
25
+ if (error.response && error.response.status === 429) {
26
+ const retryAfter = parseInt(error.response.headers['retry-after'] || '5', 10);
27
+ console.warn(`Rate limited. Retrying after ${retryAfter} seconds...`);
28
+ await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
29
+ return requestWithRetry(url, params);
30
+ }
31
+ throw error;
32
+ }
33
+ }
34
+ async function listImages(page = 1, perPage = 20) {
35
+ return requestWithRetry(API_BASE_URL, { page, per_page: perPage });
36
+ }
37
+ async function getImageDetail(imageId) {
38
+ return requestWithRetry(`${API_BASE_URL}/${imageId}`);
39
+ }
40
+ async function searchImages(query, page = 1, perPage = 20) {
41
+ return requestWithRetry(API_SEARCH_URL, { query, page, per: perPage });
42
+ }
43
+ async function getCurrentUser() {
44
+ return requestWithRetry(API_USERS_ME_URL);
45
+ }
46
+ async function uploadImage(options) {
47
+ const form = new form_data_1.default();
48
+ form.append('access_token', config_1.config.GYAZO_ACCESS_TOKEN || '');
49
+ form.append('imagedata', options.imageData, {
50
+ filename: options.filename || 'upload.bin',
51
+ });
52
+ if (options.title)
53
+ form.append('title', options.title);
54
+ if (options.app)
55
+ form.append('app', options.app);
56
+ if (options.refererUrl)
57
+ form.append('referer_url', options.refererUrl);
58
+ if (options.desc)
59
+ form.append('desc', options.desc);
60
+ if (typeof options.timestamp === 'number') {
61
+ form.append('created_at', String(options.timestamp));
62
+ }
63
+ const response = await axios_1.default.post(API_UPLOAD_URL, form, {
64
+ headers: form.getHeaders(),
65
+ });
66
+ return response.data;
67
+ }
package/dist/config.js ADDED
@@ -0,0 +1,25 @@
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.config = void 0;
7
+ exports.setAccessToken = setAccessToken;
8
+ const dotenv_1 = __importDefault(require("dotenv"));
9
+ const zod_1 = require("zod");
10
+ dotenv_1.default.config({ quiet: true });
11
+ const configSchema = zod_1.z.object({
12
+ GYAZO_ACCESS_TOKEN: zod_1.z.string().optional(),
13
+ GYAZO_CLIENT_ID: zod_1.z.string().optional(),
14
+ GYAZO_CLIENT_SECRET: zod_1.z.string().optional(),
15
+ GYAZO_CACHE_DIR: zod_1.z.string().optional(),
16
+ });
17
+ exports.config = configSchema.parse({
18
+ GYAZO_ACCESS_TOKEN: process.env.GYAZO_ACCESS_TOKEN,
19
+ GYAZO_CLIENT_ID: process.env.GYAZO_CLIENT_ID,
20
+ GYAZO_CLIENT_SECRET: process.env.GYAZO_CLIENT_SECRET,
21
+ GYAZO_CACHE_DIR: process.env.GYAZO_CACHE_DIR,
22
+ });
23
+ function setAccessToken(token) {
24
+ exports.config.GYAZO_ACCESS_TOKEN = token;
25
+ }
@@ -0,0 +1,60 @@
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.getStoredConfig = getStoredConfig;
7
+ exports.setStoredConfig = setStoredConfig;
8
+ exports.ensureAccessToken = ensureAccessToken;
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const path_1 = __importDefault(require("path"));
11
+ const os_1 = __importDefault(require("os"));
12
+ const config_1 = require("./config");
13
+ const CONFIG_DIR = path_1.default.join(os_1.default.homedir(), '.config', 'gyazo');
14
+ const CREDENTIALS_FILE = path_1.default.join(CONFIG_DIR, 'credentials.json');
15
+ function loadStoredCredentials() {
16
+ if (fs_1.default.existsSync(CREDENTIALS_FILE)) {
17
+ try {
18
+ return JSON.parse(fs_1.default.readFileSync(CREDENTIALS_FILE, 'utf-8'));
19
+ }
20
+ catch (e) {
21
+ return {};
22
+ }
23
+ }
24
+ return {};
25
+ }
26
+ function getStoredConfig(key) {
27
+ const stored = loadStoredCredentials();
28
+ if (key === 'token')
29
+ return stored.GYAZO_ACCESS_TOKEN;
30
+ return undefined;
31
+ }
32
+ function setStoredConfig(key, value) {
33
+ const stored = loadStoredCredentials();
34
+ if (key === 'token') {
35
+ stored.GYAZO_ACCESS_TOKEN = value;
36
+ }
37
+ else {
38
+ console.error(`Unknown config key: ${key}`);
39
+ process.exit(1);
40
+ }
41
+ if (!fs_1.default.existsSync(CONFIG_DIR)) {
42
+ fs_1.default.mkdirSync(CONFIG_DIR, { recursive: true });
43
+ }
44
+ fs_1.default.writeFileSync(CREDENTIALS_FILE, JSON.stringify(stored, null, 2));
45
+ console.error(`Config set: ${key}=${value}`);
46
+ }
47
+ async function ensureAccessToken() {
48
+ if (config_1.config.GYAZO_ACCESS_TOKEN) {
49
+ return config_1.config.GYAZO_ACCESS_TOKEN;
50
+ }
51
+ const storedToken = getStoredConfig('token');
52
+ if (storedToken) {
53
+ (0, config_1.setAccessToken)(storedToken);
54
+ return storedToken;
55
+ }
56
+ console.error('Error: Gyazo Access Token is not set.');
57
+ console.error('Please run the following command to set your access token:');
58
+ console.error(' gyazo config set token <your_access_token>');
59
+ process.exit(1);
60
+ }