@chnxthr/knowledge-mcp 0.3.0 → 0.3.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.
@@ -1,25 +1,94 @@
1
- /**
2
- * Google Drive API wrapper.
3
- *
4
- * 인증 옵션 (우선순위 순):
5
- * 1. Service Account JSON (권장 — production-grade)
6
- * - GOOGLE_SERVICE_ACCOUNT_KEY (inline JSON, Railway 친화)
7
- * - GOOGLE_APPLICATION_CREDENTIALS (JSON 파일 path)
8
- *
9
- * 2. OAuth Refresh Token (fallback, single-user)
10
- * - GOOGLE_OAUTH_CLIENT_ID + GOOGLE_OAUTH_CLIENT_SECRET + GOOGLE_OAUTH_REFRESH_TOKEN
11
- * - Legacy DRIVE_* fallback
12
- *
13
- * Service Account 사용 시:
14
- * - Drive 폴더에 service account email (xxx@<project>.iam.gserviceaccount.com) viewer 공유 필수
15
- * - refresh_token 만료·rotation 없음
16
- * - server-to-server auth (production standard)
17
- */
18
- import type { drive_v3 } from 'googleapis';
19
- /**
20
- * googleapis 는 불러오는 데만 CPU 1초 이상 걸린다(가장 무거운 의존성). 그래서 처음 쓸 때 불러온다 —
21
- * Drive 를 안 쓰는 서버와 `knowledge-mcp keys` 같은 명령이 그만큼 빨리 뜬다.
22
- */
23
- export declare function getDriveClient(): Promise<drive_v3.Drive>;
1
+ export interface DriveFile {
2
+ id?: string | null;
3
+ name?: string | null;
4
+ mimeType?: string | null;
5
+ parents?: string[] | null;
6
+ modifiedTime?: string | null;
7
+ size?: string | null;
8
+ webViewLink?: string | null;
9
+ trashed?: boolean | null;
10
+ owners?: Array<{
11
+ emailAddress?: string | null;
12
+ displayName?: string | null;
13
+ }> | null;
14
+ [field: string]: unknown;
15
+ }
16
+ export interface DriveChange {
17
+ removed?: boolean | null;
18
+ fileId?: string | null;
19
+ file?: DriveFile | null;
20
+ }
21
+ export interface DriveChangeList {
22
+ nextPageToken?: string | null;
23
+ newStartPageToken?: string | null;
24
+ changes?: DriveChange[];
25
+ }
26
+ export interface DriveFileList {
27
+ files?: DriveFile[];
28
+ nextPageToken?: string | null;
29
+ }
30
+ type Params = Record<string, string | number | boolean | undefined>;
31
+ type ResponseType = 'json' | 'text' | 'arraybuffer';
32
+ export interface DriveClient {
33
+ files: {
34
+ list(params: Params): Promise<{
35
+ data: DriveFileList;
36
+ }>;
37
+ /** Metadata, or the file body with `alt: 'media'` and a response type. */
38
+ get(params: Params & {
39
+ fileId: string;
40
+ }, opts?: {
41
+ responseType?: ResponseType;
42
+ }): Promise<{
43
+ data: any;
44
+ }>;
45
+ export(params: Params & {
46
+ fileId: string;
47
+ mimeType: string;
48
+ }, opts?: {
49
+ responseType?: ResponseType;
50
+ }): Promise<{
51
+ data: any;
52
+ }>;
53
+ };
54
+ changes: {
55
+ getStartPageToken(params?: Params): Promise<{
56
+ data: {
57
+ startPageToken?: string | null;
58
+ };
59
+ }>;
60
+ list(params: Params & {
61
+ pageToken: string;
62
+ }): Promise<{
63
+ data: DriveChangeList;
64
+ }>;
65
+ };
66
+ }
67
+ export declare class DriveApiError extends Error {
68
+ /** HTTP status (0 = network or timeout). googleapis put the same value in `code`. */
69
+ readonly code: number;
70
+ constructor(message: string,
71
+ /** HTTP status (0 = network or timeout). googleapis put the same value in `code`. */
72
+ code: number);
73
+ }
74
+ type Credentials = {
75
+ kind: 'service_account';
76
+ clientEmail: string;
77
+ privateKey: string;
78
+ tokenUri: string;
79
+ } | {
80
+ kind: 'refresh_token';
81
+ clientId: string;
82
+ clientSecret: string;
83
+ refreshToken: string;
84
+ tokenUri: string;
85
+ };
86
+ /** Which credentials the env provides. Throws with the options when none are set. */
87
+ export declare function resolveCredentials(env?: NodeJS.ProcessEnv): Credentials;
88
+ /** Builds a client. `apiBase` and credentials are injectable for tests; production uses env and Google URLs. */
89
+ export declare function createDriveClient(creds: Credentials, apiBase?: string): DriveClient;
90
+ /** The process-wide Drive client, built from env on first use. */
91
+ export declare function getDriveClient(): Promise<DriveClient>;
24
92
  /** Google Drive query language 의 single-quote escape. */
25
93
  export declare function escapeDriveQuery(s: string): string;
94
+ export {};
@@ -1,60 +1,218 @@
1
- let _client = null;
2
- const DRIVE_READONLY_SCOPE = 'https://www.googleapis.com/auth/drive.readonly';
3
- // Drive API 전역 timeout — googleapis 는 명시 timeout 이 없으면 무한에 가깝게 hang 할 수 있어
4
- // (search/read/list·classifyAndPath 부모 walk가 매달리면 stateless transport 에서 도구 호출
5
- // 전체가 멈춤). google.options 로 전역 15s 부여. internal-mcp 는 google API 를 drive 만 쓴다.
6
- const DRIVE_TIMEOUT_MS = Number(process.env.DRIVE_TIMEOUT_MS ?? 15_000);
7
1
  /**
8
- * googleapis 는 불러오는 데만 CPU 1초 이상 걸린다(가장 무거운 의존성). 그래서 처음 쓸 때 불러온다 —
9
- * Drive 를 안 쓰는 서버와 `knowledge-mcp keys` 같은 명령이 그만큼 빨리 뜬다.
2
+ * Google Drive API (v3, read-only) over plain HTTPS.
3
+ *
4
+ * 인증 옵션 (우선순위 순):
5
+ * 1. Service Account JSON (권장 — production-grade)
6
+ * - GOOGLE_SERVICE_ACCOUNT_KEY (inline JSON, Railway 친화)
7
+ * - GOOGLE_APPLICATION_CREDENTIALS (JSON 파일 path. service_account 또는 authorized_user)
8
+ *
9
+ * 2. OAuth Refresh Token (fallback, single-user)
10
+ * - GOOGLE_OAUTH_CLIENT_ID + GOOGLE_OAUTH_CLIENT_SECRET + GOOGLE_OAUTH_REFRESH_TOKEN
11
+ * - Legacy DRIVE_* fallback
12
+ *
13
+ * Service Account 사용 시:
14
+ * - Drive 폴더에 service account email (xxx@<project>.iam.gserviceaccount.com) viewer 공유 필수
15
+ * - refresh_token 만료·rotation 없음
16
+ *
17
+ * googleapis 대신 직접 부르는 이유: googleapis(google-auth-library → gaxios → node-fetch → fetch-blob)는
18
+ * 최신판도 폐기된 패키지(node-domexception, 옛 판은 uuid)를 끌어와 설치마다 경고를 남겼고, 불러오는 데만
19
+ * CPU 1초가 넘게 들었다. 이 서버가 쓰는 Drive 엔드포인트는 5개뿐이다. 호출 모양(drive.files.list 등,
20
+ * { data } 반환)은 googleapis 와 같게 둬서 도구 코드는 바꾸지 않았다.
10
21
  */
11
- export async function getDriveClient() {
12
- if (_client)
13
- return _client;
14
- const { google } = await import('googleapis');
15
- const { GoogleAuth } = await import('google-auth-library');
16
- google.options({ timeout: DRIVE_TIMEOUT_MS });
17
- // ── Option 1: Service Account (권장) ────────────────────
18
- const serviceAccountJson = process.env.GOOGLE_SERVICE_ACCOUNT_KEY;
19
- const credentialsPath = process.env.GOOGLE_APPLICATION_CREDENTIALS;
20
- if (serviceAccountJson) {
21
- // Inline JSON (Railway env)
22
- let parsed;
22
+ import { readFileSync } from 'node:fs';
23
+ import { SignJWT, importPKCS8 } from 'jose';
24
+ const DRIVE_READONLY_SCOPE = 'https://www.googleapis.com/auth/drive.readonly';
25
+ const DEFAULT_TOKEN_URI = 'https://oauth2.googleapis.com/token';
26
+ const DRIVE_API = 'https://www.googleapis.com/drive/v3';
27
+ // Drive API 전역 timeout — 명시 timeout 이 없으면 매달린 호출 하나가 도구 호출 전체를 멈춘다.
28
+ const DRIVE_TIMEOUT_MS = Number(process.env.DRIVE_TIMEOUT_MS ?? 15_000);
29
+ const RETRIES = 3; // 429·5xx·네트워크 오류. GET 만 쓰므로 다시 보내도 안전하다
30
+ export class DriveApiError extends Error {
31
+ code;
32
+ constructor(message,
33
+ /** HTTP status (0 = network or timeout). googleapis put the same value in `code`. */
34
+ code) {
35
+ super(message);
36
+ this.code = code;
37
+ this.name = 'DriveApiError';
38
+ }
39
+ }
40
+ function credentialsFromJson(raw, source) {
41
+ let j;
42
+ try {
43
+ j = JSON.parse(raw);
44
+ }
45
+ catch (e) {
46
+ throw new Error(`[drive] ${source} is not valid JSON: ${e instanceof Error ? e.message : String(e)}`);
47
+ }
48
+ if (j.type === 'authorized_user') {
49
+ return {
50
+ kind: 'refresh_token',
51
+ clientId: String(j.client_id ?? ''),
52
+ clientSecret: String(j.client_secret ?? ''),
53
+ refreshToken: String(j.refresh_token ?? ''),
54
+ tokenUri: DEFAULT_TOKEN_URI,
55
+ };
56
+ }
57
+ if (typeof j.client_email !== 'string' || typeof j.private_key !== 'string') {
58
+ throw new Error(`[drive] ${source} must be a service account key (client_email, private_key) or an authorized_user file`);
59
+ }
60
+ return {
61
+ kind: 'service_account',
62
+ clientEmail: j.client_email,
63
+ privateKey: j.private_key,
64
+ tokenUri: typeof j.token_uri === 'string' ? j.token_uri : DEFAULT_TOKEN_URI,
65
+ };
66
+ }
67
+ /** Which credentials the env provides. Throws with the options when none are set. */
68
+ export function resolveCredentials(env = process.env) {
69
+ if (env.GOOGLE_SERVICE_ACCOUNT_KEY)
70
+ return credentialsFromJson(env.GOOGLE_SERVICE_ACCOUNT_KEY, 'GOOGLE_SERVICE_ACCOUNT_KEY');
71
+ if (env.GOOGLE_APPLICATION_CREDENTIALS) {
72
+ const path = env.GOOGLE_APPLICATION_CREDENTIALS;
73
+ let raw;
23
74
  try {
24
- parsed = JSON.parse(serviceAccountJson);
75
+ raw = readFileSync(path, 'utf8');
25
76
  }
26
77
  catch (e) {
27
- throw new Error('[drive] GOOGLE_SERVICE_ACCOUNT_KEY is not valid JSON: ' +
28
- (e instanceof Error ? e.message : String(e)));
78
+ throw new Error(`[drive] cannot read GOOGLE_APPLICATION_CREDENTIALS (${path}): ${e instanceof Error ? e.message : String(e)}`);
29
79
  }
30
- const auth = new GoogleAuth({
31
- credentials: parsed,
32
- scopes: [DRIVE_READONLY_SCOPE],
33
- });
34
- _client = google.drive({ version: 'v3', auth });
35
- return _client;
36
- }
37
- if (credentialsPath) {
38
- // GoogleAuth 가 자동 GOOGLE_APPLICATION_CREDENTIALS env 인식
39
- const auth = new GoogleAuth({ scopes: [DRIVE_READONLY_SCOPE] });
40
- _client = google.drive({ version: 'v3', auth });
41
- return _client;
42
- }
43
- // ── Option 2: OAuth Refresh Token (fallback) ────────────
44
- const clientId = process.env.GOOGLE_OAUTH_CLIENT_ID || process.env.DRIVE_CLIENT_ID;
45
- const clientSecret = process.env.GOOGLE_OAUTH_CLIENT_SECRET || process.env.DRIVE_CLIENT_SECRET;
46
- const refreshToken = process.env.GOOGLE_OAUTH_REFRESH_TOKEN || process.env.DRIVE_REFRESH_TOKEN;
80
+ return credentialsFromJson(raw, 'GOOGLE_APPLICATION_CREDENTIALS');
81
+ }
82
+ const clientId = env.GOOGLE_OAUTH_CLIENT_ID || env.DRIVE_CLIENT_ID;
83
+ const clientSecret = env.GOOGLE_OAUTH_CLIENT_SECRET || env.DRIVE_CLIENT_SECRET;
84
+ const refreshToken = env.GOOGLE_OAUTH_REFRESH_TOKEN || env.DRIVE_REFRESH_TOKEN;
47
85
  if (clientId && clientSecret && refreshToken) {
48
- const oauth = new google.auth.OAuth2(clientId, clientSecret);
49
- oauth.setCredentials({ refresh_token: refreshToken });
50
- _client = google.drive({ version: 'v3', auth: oauth });
51
- return _client;
86
+ return { kind: 'refresh_token', clientId, clientSecret, refreshToken, tokenUri: DEFAULT_TOKEN_URI };
52
87
  }
53
88
  throw new Error('[drive] Drive credentials missing. Use one of:\n' +
54
89
  ' (1) GOOGLE_SERVICE_ACCOUNT_KEY (inline JSON) ← 권장\n' +
55
90
  ' (2) GOOGLE_APPLICATION_CREDENTIALS (JSON file path) ← 권장\n' +
56
91
  ' (3) GOOGLE_OAUTH_CLIENT_ID + _SECRET + _REFRESH_TOKEN ← fallback');
57
92
  }
93
+ async function requestToken(creds) {
94
+ const form = new URLSearchParams();
95
+ if (creds.kind === 'service_account') {
96
+ // OAuth 2.0 JWT bearer grant (RFC 7523): 서비스 계정 키로 서명한 assertion 을 토큰으로 바꾼다.
97
+ const now = Math.floor(Date.now() / 1000);
98
+ const key = await importPKCS8(creds.privateKey, 'RS256');
99
+ const assertion = await new SignJWT({ scope: DRIVE_READONLY_SCOPE })
100
+ .setProtectedHeader({ alg: 'RS256', typ: 'JWT' })
101
+ .setIssuer(creds.clientEmail)
102
+ .setAudience(creds.tokenUri)
103
+ .setIssuedAt(now)
104
+ .setExpirationTime(now + 3600)
105
+ .sign(key);
106
+ form.set('grant_type', 'urn:ietf:params:oauth:grant-type:jwt-bearer');
107
+ form.set('assertion', assertion);
108
+ }
109
+ else {
110
+ form.set('grant_type', 'refresh_token');
111
+ form.set('client_id', creds.clientId);
112
+ form.set('client_secret', creds.clientSecret);
113
+ form.set('refresh_token', creds.refreshToken);
114
+ }
115
+ const res = await fetch(creds.tokenUri, {
116
+ method: 'POST',
117
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
118
+ body: form,
119
+ signal: AbortSignal.timeout(DRIVE_TIMEOUT_MS),
120
+ });
121
+ const body = (await res.json().catch(() => ({})));
122
+ if (!res.ok || !body.access_token) {
123
+ // Google 은 오류 본문에 토큰이나 키를 돌려주지 않는다. 오류 코드와 설명만 남긴다.
124
+ throw new DriveApiError(`[drive] token request failed ${res.status}: ${body.error ?? ''} ${body.error_description ?? ''}`.trim(), res.status);
125
+ }
126
+ return { token: body.access_token, expiresAt: Date.now() + (body.expires_in ?? 3600) * 1000 };
127
+ }
128
+ /** Builds a client. `apiBase` and credentials are injectable for tests; production uses env and Google URLs. */
129
+ export function createDriveClient(creds, apiBase = DRIVE_API) {
130
+ let cached = null;
131
+ let pending = null;
132
+ const accessToken = () => {
133
+ if (cached && cached.expiresAt - 60_000 > Date.now())
134
+ return Promise.resolve(cached.token);
135
+ pending ??= requestToken(creds)
136
+ .then((t) => {
137
+ cached = t;
138
+ return t.token;
139
+ })
140
+ .finally(() => {
141
+ pending = null;
142
+ });
143
+ return pending;
144
+ };
145
+ const get = async (path, params = {}, responseType = 'json') => {
146
+ const qs = new URLSearchParams();
147
+ for (const [k, v] of Object.entries(params))
148
+ if (v !== undefined)
149
+ qs.set(k, String(v));
150
+ const url = `${apiBase}${path}${qs.size ? `?${qs}` : ''}`;
151
+ for (let attempt = 0;; attempt++) {
152
+ let res;
153
+ try {
154
+ res = await fetch(url, {
155
+ headers: { Authorization: `Bearer ${await accessToken()}`, Accept: responseType === 'json' ? 'application/json' : '*/*' },
156
+ signal: AbortSignal.timeout(DRIVE_TIMEOUT_MS),
157
+ });
158
+ }
159
+ catch (e) {
160
+ if (e instanceof DriveApiError)
161
+ throw e; // token request failed
162
+ if (attempt + 1 < RETRIES) {
163
+ await new Promise((r) => setTimeout(r, 500 * 2 ** attempt));
164
+ continue;
165
+ }
166
+ const reason = e instanceof Error && e.name === 'TimeoutError' ? `timeout ${DRIVE_TIMEOUT_MS}ms` : String(e);
167
+ throw new DriveApiError(`[drive] GET ${path} failed: ${reason}`, 0);
168
+ }
169
+ if (res.status === 401 && attempt === 0) {
170
+ cached = null; // revoked or expired early: get a new token once
171
+ continue;
172
+ }
173
+ if ((res.status === 429 || res.status >= 500) && attempt + 1 < RETRIES) {
174
+ const after = Number(res.headers.get('retry-after'));
175
+ await res.arrayBuffer().catch(() => undefined);
176
+ await new Promise((r) => setTimeout(r, Number.isFinite(after) && after > 0 ? after * 1000 : 500 * 2 ** attempt));
177
+ continue;
178
+ }
179
+ if (!res.ok) {
180
+ const text = await res.text().catch(() => '');
181
+ let msg = text.slice(0, 300);
182
+ try {
183
+ msg = JSON.parse(text).error?.message ?? msg;
184
+ }
185
+ catch {
186
+ /* not JSON */
187
+ }
188
+ throw new DriveApiError(`[drive] ${res.status} ${path}: ${msg}`, res.status);
189
+ }
190
+ if (responseType === 'arraybuffer')
191
+ return { data: await res.arrayBuffer() };
192
+ if (responseType === 'text')
193
+ return { data: await res.text() };
194
+ return { data: await res.json() };
195
+ }
196
+ };
197
+ const fileId = (id) => encodeURIComponent(id);
198
+ return {
199
+ files: {
200
+ list: (params) => get('/files', params),
201
+ get: ({ fileId: id, ...params }, opts) => get(`/files/${fileId(id)}`, params, opts?.responseType ?? 'json'),
202
+ export: ({ fileId: id, ...params }, opts) => get(`/files/${fileId(id)}/export`, params, opts?.responseType ?? 'text'),
203
+ },
204
+ changes: {
205
+ getStartPageToken: (params) => get('/changes/startPageToken', params),
206
+ list: (params) => get('/changes', params),
207
+ },
208
+ };
209
+ }
210
+ let _client = null;
211
+ /** The process-wide Drive client, built from env on first use. */
212
+ export async function getDriveClient() {
213
+ _client ??= createDriveClient(resolveCredentials());
214
+ return _client;
215
+ }
58
216
  /** Google Drive query language 의 single-quote escape. */
59
217
  export function escapeDriveQuery(s) {
60
218
  return s.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/plugins/drive/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/plugins/drive/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AAE5C,MAAM,oBAAoB,GAAG,gDAAgD,CAAC;AAC9E,MAAM,iBAAiB,GAAG,qCAAqC,CAAC;AAChE,MAAM,SAAS,GAAG,qCAAqC,CAAC;AAExD,oEAAoE;AACpE,MAAM,gBAAgB,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,MAAM,CAAC,CAAC;AACxE,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,yCAAyC;AA8C5D,MAAM,OAAO,aAAc,SAAQ,KAAK;IAI3B;IAHX,YACE,OAAe;IACf,qFAAqF;IAC5E,IAAY;QAErB,KAAK,CAAC,OAAO,CAAC,CAAC;QAFN,SAAI,GAAJ,IAAI,CAAQ;QAGrB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAOD,SAAS,mBAAmB,CAAC,GAAW,EAAE,MAAc;IACtD,IAAI,CAA0B,CAAC;IAC/B,IAAI,CAAC;QACH,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,WAAW,MAAM,uBAAuB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACxG,CAAC;IACD,IAAI,CAAC,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;QACjC,OAAO;YACL,IAAI,EAAE,eAAe;YACrB,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC;YACnC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,aAAa,IAAI,EAAE,CAAC;YAC3C,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,aAAa,IAAI,EAAE,CAAC;YAC3C,QAAQ,EAAE,iBAAiB;SAC5B,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,CAAC,YAAY,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;QAC5E,MAAM,IAAI,KAAK,CAAC,WAAW,MAAM,uFAAuF,CAAC,CAAC;IAC5H,CAAC;IACD,OAAO;QACL,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,CAAC,CAAC,YAAY;QAC3B,UAAU,EAAE,CAAC,CAAC,WAAW;QACzB,QAAQ,EAAE,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB;KAC5E,CAAC;AACJ,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,kBAAkB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACrE,IAAI,GAAG,CAAC,0BAA0B;QAAE,OAAO,mBAAmB,CAAC,GAAG,CAAC,0BAA0B,EAAE,4BAA4B,CAAC,CAAC;IAC7H,IAAI,GAAG,CAAC,8BAA8B,EAAE,CAAC;QACvC,MAAM,IAAI,GAAG,GAAG,CAAC,8BAA8B,CAAC;QAChD,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACH,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,uDAAuD,IAAI,MAAM,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACjI,CAAC;QACD,OAAO,mBAAmB,CAAC,GAAG,EAAE,gCAAgC,CAAC,CAAC;IACpE,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,CAAC,sBAAsB,IAAI,GAAG,CAAC,eAAe,CAAC;IACnE,MAAM,YAAY,GAAG,GAAG,CAAC,0BAA0B,IAAI,GAAG,CAAC,mBAAmB,CAAC;IAC/E,MAAM,YAAY,GAAG,GAAG,CAAC,0BAA0B,IAAI,GAAG,CAAC,mBAAmB,CAAC;IAC/E,IAAI,QAAQ,IAAI,YAAY,IAAI,YAAY,EAAE,CAAC;QAC7C,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IACtG,CAAC;IACD,MAAM,IAAI,KAAK,CACb,kDAAkD;QAChD,uDAAuD;QACvD,8DAA8D;QAC9D,oEAAoE,CACvE,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,KAAkB;IAC5C,MAAM,IAAI,GAAG,IAAI,eAAe,EAAE,CAAC;IACnC,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;QACrC,6EAA6E;QAC7E,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,KAAK,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACzD,MAAM,SAAS,GAAG,MAAM,IAAI,OAAO,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC;aACjE,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;aAChD,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC;aAC5B,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC;aAC3B,WAAW,CAAC,GAAG,CAAC;aAChB,iBAAiB,CAAC,GAAG,GAAG,IAAI,CAAC;aAC7B,IAAI,CAAC,GAAG,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,6CAA6C,CAAC,CAAC;QACtE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACnC,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;QACxC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;QACtC,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;QAC9C,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;IAChD,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE;QACtC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;QAChE,IAAI,EAAE,IAAI;QACV,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,gBAAgB,CAAC;KAC9C,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAA+F,CAAC;IAChJ,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClC,oDAAoD;QACpD,MAAM,IAAI,aAAa,CAAC,gCAAgC,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,KAAK,IAAI,EAAE,IAAI,IAAI,CAAC,iBAAiB,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAChJ,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC;AAChG,CAAC;AAED,gHAAgH;AAChH,MAAM,UAAU,iBAAiB,CAAC,KAAkB,EAAE,OAAO,GAAG,SAAS;IACvE,IAAI,MAAM,GAAgD,IAAI,CAAC;IAC/D,IAAI,OAAO,GAA2B,IAAI,CAAC;IAC3C,MAAM,WAAW,GAAG,GAAoB,EAAE;QACxC,IAAI,MAAM,IAAI,MAAM,CAAC,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE;YAAE,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3F,OAAO,KAAK,YAAY,CAAC,KAAK,CAAC;aAC5B,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;YACV,MAAM,GAAG,CAAC,CAAC;YACX,OAAO,CAAC,CAAC,KAAK,CAAC;QACjB,CAAC,CAAC;aACD,OAAO,CAAC,GAAG,EAAE;YACZ,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC,CAAC,CAAC;QACL,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;IAEF,MAAM,GAAG,GAAG,KAAK,EAAE,IAAY,EAAE,SAAiB,EAAE,EAAE,eAA6B,MAAM,EAA0B,EAAE;QACnH,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;QACjC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,IAAI,CAAC,KAAK,SAAS;gBAAE,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACvF,MAAM,GAAG,GAAG,GAAG,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAC1D,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,EAAE,EAAE,CAAC;YAClC,IAAI,GAAa,CAAC;YAClB,IAAI,CAAC;gBACH,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;oBACrB,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,MAAM,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,YAAY,KAAK,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,KAAK,EAAE;oBACzH,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,gBAAgB,CAAC;iBAC9C,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,IAAI,CAAC,YAAY,aAAa;oBAAE,MAAM,CAAC,CAAC,CAAC,uBAAuB;gBAChE,IAAI,OAAO,GAAG,CAAC,GAAG,OAAO,EAAE,CAAC;oBAC1B,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC;oBAC5D,SAAS;gBACX,CAAC;gBACD,MAAM,MAAM,GAAG,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC,CAAC,WAAW,gBAAgB,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBAC7G,MAAM,IAAI,aAAa,CAAC,eAAe,IAAI,YAAY,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;YACtE,CAAC;YACD,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;gBACxC,MAAM,GAAG,IAAI,CAAC,CAAC,iDAAiD;gBAChE,SAAS;YACX,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,GAAG,OAAO,EAAE,CAAC;gBACvE,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;gBACrD,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;gBAC/C,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC;gBACjH,SAAS;YACX,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC9C,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;gBAC7B,IAAI,CAAC;oBACH,GAAG,GAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAsC,CAAC,KAAK,EAAE,OAAO,IAAI,GAAG,CAAC;gBACrF,CAAC;gBAAC,MAAM,CAAC;oBACP,cAAc;gBAChB,CAAC;gBACD,MAAM,IAAI,aAAa,CAAC,WAAW,GAAG,CAAC,MAAM,IAAI,IAAI,KAAK,GAAG,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;YAC/E,CAAC;YACD,IAAI,YAAY,KAAK,aAAa;gBAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC;YAC7E,IAAI,YAAY,KAAK,MAAM;gBAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;YAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;QACpC,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;IACtD,OAAO;QACL,KAAK,EAAE;YACL,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC;YACvC,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,IAAI,MAAM,CAAC;YAC3G,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,IAAI,MAAM,CAAC;SACtH;QACD,OAAO,EAAE;YACP,iBAAiB,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,yBAAyB,EAAE,MAAM,CAAC;YACrE,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC;SAC1C;KACF,CAAC;AACJ,CAAC;AAED,IAAI,OAAO,GAAuB,IAAI,CAAC;AAEvC,kEAAkE;AAClE,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,OAAO,KAAK,iBAAiB,CAAC,kBAAkB,EAAE,CAAC,CAAC;IACpD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,gBAAgB,CAAC,CAAS;IACxC,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACvD,CAAC"}
@@ -6,16 +6,16 @@
6
6
  * - Google Docs → Drive export text/markdown
7
7
  * - Google Sheets → Drive export text/csv
8
8
  * - Google Slides → Drive export text/plain
9
- * - Word .docx → mammoth (텍스트 레이어)
9
+ * - Word .docx → ooxml.ts (zip 안 XML 의 문단 텍스트)
10
10
  * - PDF (digital) → pdf-parse (텍스트 레이어)
11
11
  *
12
12
  * OCR 필요 (후속 — Mathpix):
13
13
  * - PDF (스캔본, 텍스트 부족) → Mathpix
14
14
  * - .pptx / image → Mathpix / Gemini multimodal
15
15
  *
16
- * lazy import (mammoth/pdf-parse) — 필요 시에만 로드.
16
+ * lazy import (pdf-parse, xlsx) — 필요 시에만 로드.
17
17
  */
18
- import type { drive_v3 } from 'googleapis';
18
+ import type { DriveClient } from './client.js';
19
19
  export interface ExtractResult {
20
20
  text: string;
21
21
  method: string;
@@ -23,4 +23,4 @@ export interface ExtractResult {
23
23
  meta?: Record<string, unknown>;
24
24
  }
25
25
  /** 추출 + 정제 (노이즈 cleanup). 색인·검색 진입점. */
26
- export declare function extractText(drive: drive_v3.Drive, fileId: string, mimeType: string): Promise<ExtractResult>;
26
+ export declare function extractText(drive: DriveClient, fileId: string, mimeType: string): Promise<ExtractResult>;
@@ -34,12 +34,11 @@ async function extractRaw(drive, fileId, mimeType) {
34
34
  if (mimeType === 'application/vnd.google-apps.presentation') {
35
35
  return { text: await exportGoogle(drive, fileId, 'text/plain'), method: 'gslide→txt' };
36
36
  }
37
- // 3. Word .docx — mammoth (텍스트 레이어)
37
+ // 3. Word .docx — 의존성 없는 zip/XML 읽기 (ooxml.ts). 문단 사이 빈 줄 — 예전 mammoth extractRawText 와 같은 모양
38
38
  if (mimeType.includes('wordprocessingml')) {
39
- const mammoth = (await import('mammoth')).default ?? (await import('mammoth'));
39
+ const { docxText } = await import('./ooxml.js');
40
40
  const buffer = await downloadBuffer(drive, fileId);
41
- const result = await mammoth.extractRawText({ buffer });
42
- return { text: result.value, method: 'docx→mammoth' };
41
+ return { text: docxText(buffer), method: 'docx→ooxml' };
43
42
  }
44
43
  // 4. PDF — pdf-parse v2. digital 텍스트, 스캔본(<MIN) 은 Mathpix OCR fallback
45
44
  if (mimeType === 'application/pdf') {
@@ -69,23 +68,11 @@ async function extractRaw(drive, fileId, mimeType) {
69
68
  meta: { pages, charsPerPage: Math.round(charsPerPage), ocr: true },
70
69
  };
71
70
  }
72
- // 5. PowerPoint .pptx → officeparser (슬라이드 텍스트)
73
- // v7 parseOffice 는 OfficeParserAST 반환 → markdown(.to('md')) 우선, 실패 시 toText().
71
+ // 5. PowerPoint .pptx → 슬라이드마다 "## Slide N" + 본문 + 발표자 노트 (ooxml.ts)
74
72
  if (mimeType.includes('presentationml')) {
75
- const { parseOffice } = await import('officeparser');
73
+ const { pptxText } = await import('./ooxml.js');
76
74
  const buffer = await downloadBuffer(drive, fileId);
77
- const ast = (await parseOffice(buffer));
78
- let text = '';
79
- try {
80
- const md = await ast.to('md');
81
- text = md?.value ?? '';
82
- }
83
- catch {
84
- /* md 변환 실패 → toText fallback */
85
- }
86
- if (!text.trim())
87
- text = ast.toText();
88
- return { text, method: 'pptx→officeparser' };
75
+ return { text: pptxText(buffer), method: 'pptx→ooxml' };
89
76
  }
90
77
  // 6. Excel .xlsx → SheetJS (시트별 csv)
91
78
  if (mimeType.includes('spreadsheetml')) {
@@ -1 +1 @@
1
- {"version":3,"file":"extract_text.js","sourceRoot":"","sources":["../../../src/plugins/drive/extract_text.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"extract_text.js","sourceRoot":"","sources":["../../../src/plugins/drive/extract_text.ts"],"names":[],"mappings":"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"}
@@ -11,7 +11,6 @@
11
11
  * 5. callback 받으면 콘솔에 refresh token 출력
12
12
  * 6. .env 에 GOOGLE_OAUTH_REFRESH_TOKEN= 라인 추가
13
13
  */
14
- import { google } from 'googleapis';
15
14
  import http from 'http';
16
15
  import { URL } from 'url';
17
16
  import { execFile } from 'child_process';
@@ -29,12 +28,15 @@ export async function runGetToken() {
29
28
  console.error('❌ GOOGLE_OAUTH_CLIENT_ID / CLIENT_SECRET 가 .env 에 없습니다.');
30
29
  process.exit(1);
31
30
  }
32
- const oauth = new google.auth.OAuth2(clientId, clientSecret, REDIRECT_URI);
33
- const authUrl = oauth.generateAuthUrl({
34
- access_type: 'offline',
35
- prompt: 'consent', // refresh_token 강제 발급
36
- scope: [SCOPE],
37
- });
31
+ const authUrl = 'https://accounts.google.com/o/oauth2/v2/auth?' +
32
+ new URLSearchParams({
33
+ client_id: clientId,
34
+ redirect_uri: REDIRECT_URI,
35
+ response_type: 'code',
36
+ scope: SCOPE,
37
+ access_type: 'offline',
38
+ prompt: 'consent', // refresh_token 강제 발급
39
+ }).toString();
38
40
  console.log('\n========================================');
39
41
  console.log(' OAuth Refresh Token 발급');
40
42
  console.log('========================================\n');
@@ -64,7 +66,20 @@ export async function runGetToken() {
64
66
  return;
65
67
  }
66
68
  try {
67
- const { tokens } = await oauth.getToken(code);
69
+ const tokenRes = await fetch('https://oauth2.googleapis.com/token', {
70
+ method: 'POST',
71
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
72
+ body: new URLSearchParams({
73
+ grant_type: 'authorization_code',
74
+ code,
75
+ client_id: clientId,
76
+ client_secret: clientSecret,
77
+ redirect_uri: REDIRECT_URI,
78
+ }),
79
+ });
80
+ const tokens = (await tokenRes.json());
81
+ if (!tokenRes.ok)
82
+ throw new Error(`${tokens.error ?? tokenRes.status} ${tokens.error_description ?? ''}`.trim());
68
83
  const refreshToken = tokens.refresh_token;
69
84
  if (!refreshToken) {
70
85
  console.error('\n❌ refresh_token 미발급. 이미 권한 부여한 경우 일 수 있음.');
@@ -1 +1 @@
1
- {"version":3,"file":"get_token.js","sourceRoot":"","sources":["../../../src/plugins/drive/get_token.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"get_token.js","sourceRoot":"","sources":["../../../src/plugins/drive/get_token.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  * Drive 파일 1개 → Qdrant 색인/삭제 공통 로직.
3
3
  * 전체 reindex (reindex.ts) 와 증분 sync (sync.ts) 가 공유.
4
4
  */
5
- import type { drive_v3 } from 'googleapis';
5
+ import type { DriveClient } from './client.js';
6
6
  import { type RawChunk } from './chunker.js';
7
7
  import { type ChunkPayload } from './qdrant.js';
8
8
  import { DRIVE_ROOTS, MAX_FILE_BYTES } from './settings.js';
@@ -64,6 +64,6 @@ export declare function buildChunkPayload(chunk: RawChunk, file: IndexableFile,
64
64
  * - B-1: 재색인 시 청크 수가 줄면 옛 청크(chunk_index >= 새 수)를 삭제해 유령 청크(폐기된 사실) 잔류 방지.
65
65
  * - B-9: 증분 경로는 wait:true 로 색인 직후 검색 가시성 + 실패 인지.
66
66
  */
67
- export declare function indexFile(drive: drive_v3.Drive, file: IndexableFile): Promise<number>;
67
+ export declare function indexFile(drive: DriveClient, file: IndexableFile): Promise<number>;
68
68
  /** 특정 파일의 모든 chunk 를 Qdrant 에서 삭제 (파일 삭제·trashed 시). */
69
69
  export declare function deleteFileVectors(fileId: string): Promise<void>;