google-drive-normalizer.mjs
44 lines 1.4 KB
Raw
sha256:700fafdd1afa490919f9515d660ca6e75456bcd5bb67513abcd8757a634c01f6 docs: record AIP-b SD-21 land (KN #308) Human 11 days ago
1 /**
2 * Pure Google Drive metadata normalization and query validation.
3 */
4
5 export const ALLOWED_DRIVE_MIMES = Object.freeze([
6 'application/vnd.google-apps.document',
7 'text/markdown',
8 'text/plain',
9 'application/pdf',
10 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
11 ]);
12
13 const ALLOWED_MIME_SET = new Set(ALLOWED_DRIVE_MIMES);
14 export const DRIVE_FILE_ID_RE = /^[A-Za-z0-9_-]{1,128}$/;
15 export const LIST_Q_RE = /^[A-Za-z0-9 ._-]{1,128}$/;
16
17 /**
18 * Return true only for the frozen D15 note MIME allowlist. Drive folders are
19 * deliberately absent because they are containers, not importable notes.
20 * @param {unknown} mime
21 */
22 export function isImportableMime(mime) {
23 return typeof mime === 'string' && ALLOWED_MIME_SET.has(mime);
24 }
25
26 /**
27 * Convert an untrusted provider id to a bounded path segment.
28 * @param {unknown} providerId
29 */
30 export function safeId(providerId) {
31 return String(providerId ?? '').replace(/[^A-Za-z0-9_-]/g, '').slice(0, 64);
32 }
33
34 /**
35 * Build a Drive API `name contains` expression only after strict allowlist
36 * validation. No caller-supplied query syntax is accepted.
37 * @param {unknown} q
38 * @returns {string|null}
39 */
40 export function buildDriveNameContainsQuery(q) {
41 if (typeof q !== 'string' || !LIST_Q_RE.test(q)) return null;
42 const escaped = q.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
43 return `name contains '${escaped}'`;
44 }
File History 1 commit
sha256:700fafdd1afa490919f9515d660ca6e75456bcd5bb67513abcd8757a634c01f6 docs: record AIP-b SD-21 land (KN #308) Human 11 days ago