crewly 1.20.29 → 1.20.30

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.
Files changed (98) hide show
  1. package/config/skills/agent/core/canva-create/SKILL.md +53 -0
  2. package/config/skills/agent/core/canva-create/execute.sh +88 -0
  3. package/config/skills/agent/core/canva-create/execute.test.sh +54 -0
  4. package/config/skills/agent/core/canva-designs/SKILL.md +51 -0
  5. package/config/skills/agent/core/canva-designs/execute.sh +96 -0
  6. package/config/skills/agent/core/canva-designs/execute.test.sh +54 -0
  7. package/config/skills/agent/core/canva-export/SKILL.md +52 -0
  8. package/config/skills/agent/core/canva-export/execute.sh +111 -0
  9. package/config/skills/agent/core/canva-export/execute.test.sh +55 -0
  10. package/config/skills/agent/core/canva-upload/SKILL.md +49 -0
  11. package/config/skills/agent/core/canva-upload/execute.sh +72 -0
  12. package/config/skills/agent/core/canva-upload/execute.test.sh +54 -0
  13. package/config/skills/agent/core/docs-read/SKILL.md +50 -0
  14. package/config/skills/agent/core/docs-read/execute.sh +68 -0
  15. package/config/skills/agent/core/docs-read/execute.test.sh +52 -0
  16. package/config/skills/agent/core/docs-write/SKILL.md +55 -0
  17. package/config/skills/agent/core/docs-write/execute.sh +90 -0
  18. package/config/skills/agent/core/docs-write/execute.test.sh +54 -0
  19. package/config/skills/agent/core/drive-read/SKILL.md +53 -0
  20. package/config/skills/agent/core/drive-read/execute.sh +79 -0
  21. package/config/skills/agent/core/drive-read/execute.test.sh +55 -0
  22. package/config/skills/agent/core/drive-search/SKILL.md +55 -0
  23. package/config/skills/agent/core/drive-search/execute.sh +87 -0
  24. package/config/skills/agent/core/drive-search/execute.test.sh +54 -0
  25. package/config/skills/agent/core/drive-upload/SKILL.md +54 -0
  26. package/config/skills/agent/core/drive-upload/execute.sh +117 -0
  27. package/config/skills/agent/core/drive-upload/execute.test.sh +57 -0
  28. package/config/skills/agent/core/sheets-read/SKILL.md +53 -0
  29. package/config/skills/agent/core/sheets-read/execute.sh +81 -0
  30. package/config/skills/agent/core/sheets-read/execute.test.sh +52 -0
  31. package/config/skills/agent/core/sheets-write/SKILL.md +56 -0
  32. package/config/skills/agent/core/sheets-write/execute.sh +103 -0
  33. package/config/skills/agent/core/sheets-write/execute.test.sh +57 -0
  34. package/config/skills/agent/core/slides-create/SKILL.md +61 -0
  35. package/config/skills/agent/core/slides-create/execute.sh +92 -0
  36. package/config/skills/agent/core/slides-create/execute.test.sh +54 -0
  37. package/config/skills/agent/core/slides-read/SKILL.md +49 -0
  38. package/config/skills/agent/core/slides-read/execute.sh +67 -0
  39. package/config/skills/agent/core/slides-read/execute.test.sh +50 -0
  40. package/dist/backend/backend/src/constants.d.ts +69 -0
  41. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  42. package/dist/backend/backend/src/constants.js +73 -0
  43. package/dist/backend/backend/src/constants.js.map +1 -1
  44. package/dist/backend/backend/src/controllers/canva/canva.controller.d.ts +48 -0
  45. package/dist/backend/backend/src/controllers/canva/canva.controller.d.ts.map +1 -0
  46. package/dist/backend/backend/src/controllers/canva/canva.controller.js +183 -0
  47. package/dist/backend/backend/src/controllers/canva/canva.controller.js.map +1 -0
  48. package/dist/backend/backend/src/controllers/canva/canva.routes.d.ts +22 -0
  49. package/dist/backend/backend/src/controllers/canva/canva.routes.d.ts.map +1 -0
  50. package/dist/backend/backend/src/controllers/canva/canva.routes.js +34 -0
  51. package/dist/backend/backend/src/controllers/canva/canva.routes.js.map +1 -0
  52. package/dist/backend/backend/src/controllers/google/google.controller.d.ts +100 -0
  53. package/dist/backend/backend/src/controllers/google/google.controller.d.ts.map +1 -1
  54. package/dist/backend/backend/src/controllers/google/google.controller.js +237 -1
  55. package/dist/backend/backend/src/controllers/google/google.controller.js.map +1 -1
  56. package/dist/backend/backend/src/controllers/google/google.routes.d.ts +13 -0
  57. package/dist/backend/backend/src/controllers/google/google.routes.d.ts.map +1 -1
  58. package/dist/backend/backend/src/controllers/google/google.routes.js +27 -1
  59. package/dist/backend/backend/src/controllers/google/google.routes.js.map +1 -1
  60. package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
  61. package/dist/backend/backend/src/routes/api.routes.js +3 -0
  62. package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
  63. package/dist/backend/backend/src/services/canva/canva-token.service.d.ts +98 -0
  64. package/dist/backend/backend/src/services/canva/canva-token.service.d.ts.map +1 -0
  65. package/dist/backend/backend/src/services/canva/canva-token.service.js +198 -0
  66. package/dist/backend/backend/src/services/canva/canva-token.service.js.map +1 -0
  67. package/dist/backend/backend/src/services/canva/canva.service.d.ts +184 -0
  68. package/dist/backend/backend/src/services/canva/canva.service.d.ts.map +1 -0
  69. package/dist/backend/backend/src/services/canva/canva.service.js +274 -0
  70. package/dist/backend/backend/src/services/canva/canva.service.js.map +1 -0
  71. package/dist/backend/backend/src/services/google/docs.service.d.ts +117 -0
  72. package/dist/backend/backend/src/services/google/docs.service.d.ts.map +1 -0
  73. package/dist/backend/backend/src/services/google/docs.service.js +152 -0
  74. package/dist/backend/backend/src/services/google/docs.service.js.map +1 -0
  75. package/dist/backend/backend/src/services/google/drive.service.d.ts +157 -0
  76. package/dist/backend/backend/src/services/google/drive.service.d.ts.map +1 -0
  77. package/dist/backend/backend/src/services/google/drive.service.js +203 -0
  78. package/dist/backend/backend/src/services/google/drive.service.js.map +1 -0
  79. package/dist/backend/backend/src/services/google/google-api.client.d.ts +15 -7
  80. package/dist/backend/backend/src/services/google/google-api.client.d.ts.map +1 -1
  81. package/dist/backend/backend/src/services/google/google-api.client.js +13 -6
  82. package/dist/backend/backend/src/services/google/google-api.client.js.map +1 -1
  83. package/dist/backend/backend/src/services/google/sheets.service.d.ts +118 -0
  84. package/dist/backend/backend/src/services/google/sheets.service.d.ts.map +1 -0
  85. package/dist/backend/backend/src/services/google/sheets.service.js +158 -0
  86. package/dist/backend/backend/src/services/google/sheets.service.js.map +1 -0
  87. package/dist/backend/backend/src/services/google/slides.service.d.ts +136 -0
  88. package/dist/backend/backend/src/services/google/slides.service.d.ts.map +1 -0
  89. package/dist/backend/backend/src/services/google/slides.service.js +153 -0
  90. package/dist/backend/backend/src/services/google/slides.service.js.map +1 -0
  91. package/dist/backend/build-info.json +2 -2
  92. package/dist/cli/backend/src/constants.d.ts +69 -0
  93. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  94. package/dist/cli/backend/src/constants.js +73 -0
  95. package/dist/cli/backend/src/constants.js.map +1 -1
  96. package/frontend/dist/assets/{index-d1bd0dec.js → index-96b51cd9.js} +243 -243
  97. package/frontend/dist/index.html +1 -1
  98. package/package.json +1 -1
@@ -0,0 +1,152 @@
1
+ /**
2
+ * DocsService — Google Docs over the owner's Workspace grant.
3
+ *
4
+ * Reads any document the owner can see (`documents.readonly` /
5
+ * `drive.readonly`) and creates or appends to documents Crewly created
6
+ * (`drive.file`). Appending to a document the owner made elsewhere needs
7
+ * the `documents` scope, which the grant does not carry yet; Google then
8
+ * answers 403 and the error says so.
9
+ *
10
+ * @module services/google/docs.service
11
+ */
12
+ import { GOOGLE_WORKSPACE_CONSTANTS } from '../../constants.js';
13
+ import { GoogleWorkspaceError } from './google-workspace-token.service.js';
14
+ import { googleRequest } from './google-api.client.js';
15
+ import { requireId } from './drive.service.js';
16
+ const HEADING_PREFIX = {
17
+ TITLE: '# ',
18
+ HEADING_1: '# ',
19
+ HEADING_2: '## ',
20
+ HEADING_3: '### ',
21
+ HEADING_4: '#### ',
22
+ HEADING_5: '##### ',
23
+ HEADING_6: '###### ',
24
+ };
25
+ /**
26
+ * Flatten a paragraph to one line.
27
+ *
28
+ * @param p - Paragraph
29
+ * @returns Text without the trailing newline
30
+ */
31
+ function paragraphText(p) {
32
+ const raw = (p.elements ?? []).map((e) => e.textRun?.content ?? '').join('');
33
+ const line = raw.replace(/\n$/, '');
34
+ const prefix = HEADING_PREFIX[p.paragraphStyle?.namedStyleType ?? ''] ?? (p.bullet ? '- ' : '');
35
+ return `${prefix}${line}`;
36
+ }
37
+ /**
38
+ * Flatten a document body to plain text.
39
+ *
40
+ * @param content - `body.content`
41
+ * @returns Lines joined with `\n`
42
+ */
43
+ export function flattenDocBody(content) {
44
+ const lines = [];
45
+ for (const el of content ?? []) {
46
+ if (el.paragraph) {
47
+ lines.push(paragraphText(el.paragraph));
48
+ }
49
+ else if (el.table) {
50
+ for (const row of el.table.tableRows ?? []) {
51
+ const cells = (row.tableCells ?? []).map((cell) => flattenDocBody(cell.content).replace(/\n+/g, ' ').trim());
52
+ lines.push(cells.join(' | '));
53
+ }
54
+ }
55
+ }
56
+ return lines.join('\n').replace(/\n{3,}/g, '\n\n').trim();
57
+ }
58
+ /**
59
+ * The document's end index (where `insertText` appends).
60
+ *
61
+ * @param doc - Document
62
+ * @returns Index just before the final newline (Docs refuses inserts after it)
63
+ */
64
+ export function docEndIndex(doc) {
65
+ const content = doc.body?.content ?? [];
66
+ const last = content[content.length - 1];
67
+ const end = last?.endIndex ?? 1;
68
+ return Math.max(1, end - 1);
69
+ }
70
+ /**
71
+ * Docs: read, create, append.
72
+ */
73
+ export class DocsService {
74
+ deps;
75
+ base = GOOGLE_WORKSPACE_CONSTANTS.DOCS_API_BASE;
76
+ /**
77
+ * @param deps - Token provider and optional fetch override
78
+ */
79
+ constructor(deps) {
80
+ this.deps = deps;
81
+ }
82
+ /**
83
+ * `documents.get`, flattened to text.
84
+ *
85
+ * @param id - Document id
86
+ * @returns Title + text
87
+ */
88
+ async read(id) {
89
+ const documentId = requireId(id);
90
+ const doc = await googleRequest(this.deps, `${this.base}/documents/${encodeURIComponent(documentId)}`);
91
+ return toDocText(doc);
92
+ }
93
+ /**
94
+ * `documents.create` + one `insertText` for the body.
95
+ *
96
+ * @param input - Title and optional body
97
+ * @returns The new document (text as written)
98
+ * @throws GoogleWorkspaceError(400, validation) without a title
99
+ */
100
+ async create(input) {
101
+ const title = (input.title ?? '').trim();
102
+ if (!title)
103
+ throw new GoogleWorkspaceError(400, GOOGLE_WORKSPACE_CONSTANTS.ERROR_CODES.VALIDATION, '"title" is required');
104
+ const created = await googleRequest(this.deps, `${this.base}/documents`, { method: 'POST', body: { title } });
105
+ const documentId = created.documentId ?? '';
106
+ const text = (input.text ?? '').replace(/\r\n/g, '\n');
107
+ if (text.trim()) {
108
+ await googleRequest(this.deps, `${this.base}/documents/${encodeURIComponent(documentId)}:batchUpdate`, {
109
+ method: 'POST',
110
+ body: { requests: [{ insertText: { location: { index: 1 }, text } }] },
111
+ });
112
+ }
113
+ return { id: documentId, title: created.title ?? title, text, webViewLink: docLink(documentId) };
114
+ }
115
+ /**
116
+ * Append text at the end of a document (`documents.get` for the end
117
+ * index, then `insertText`).
118
+ *
119
+ * @param id - Document id
120
+ * @param text - Text to append (a newline is prepended when the doc is not empty)
121
+ * @returns The updated document, flattened
122
+ * @throws GoogleWorkspaceError(400, validation) without text
123
+ */
124
+ async append(id, text) {
125
+ const documentId = requireId(id);
126
+ const body = (text ?? '').replace(/\r\n/g, '\n');
127
+ if (!body.trim())
128
+ throw new GoogleWorkspaceError(400, GOOGLE_WORKSPACE_CONSTANTS.ERROR_CODES.VALIDATION, '"text" is required');
129
+ const doc = await googleRequest(this.deps, `${this.base}/documents/${encodeURIComponent(documentId)}`);
130
+ const index = docEndIndex(doc);
131
+ await googleRequest(this.deps, `${this.base}/documents/${encodeURIComponent(documentId)}:batchUpdate`, {
132
+ method: 'POST',
133
+ body: { requests: [{ insertText: { location: { index }, text: index > 1 ? `\n${body}` : body } }] },
134
+ });
135
+ const after = await googleRequest(this.deps, `${this.base}/documents/${encodeURIComponent(documentId)}`);
136
+ return toDocText(after);
137
+ }
138
+ }
139
+ function toDocText(doc) {
140
+ const id = doc.documentId ?? '';
141
+ return { id, title: doc.title ?? '', text: flattenDocBody(doc.body?.content), webViewLink: docLink(id) };
142
+ }
143
+ /**
144
+ * Browser link for a document.
145
+ *
146
+ * @param id - Document id
147
+ * @returns URL
148
+ */
149
+ export function docLink(id) {
150
+ return `https://docs.google.com/document/d/${id}/edit`;
151
+ }
152
+ //# sourceMappingURL=docs.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docs.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/google/docs.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * DriveService — Google Drive over the owner's Workspace grant.
3
+ *
4
+ * Works within the scopes the grant already carries: `drive.readonly`
5
+ * (search, metadata, download / export of anything the owner can see) and
6
+ * `drive.file` (upload; the created files are then editable by Crewly).
7
+ * Google-native files (Docs / Sheets / Slides) are read through `export`
8
+ * as text / CSV so an agent gets something it can reason about.
9
+ *
10
+ * @module services/google/drive.service
11
+ */
12
+ import { type GoogleApiDeps } from './google-api.client.js';
13
+ /** Drive file metadata (the fields Crewly asks for). */
14
+ export interface DriveFile {
15
+ id: string;
16
+ name: string;
17
+ mimeType: string;
18
+ modifiedTime?: string;
19
+ size?: number;
20
+ webViewLink?: string;
21
+ owners?: string[];
22
+ parents?: string[];
23
+ }
24
+ /** Search input. */
25
+ export interface DriveSearchInput {
26
+ /** Free text; matched against name and full text. Empty = most recent files. */
27
+ query?: string;
28
+ /** Restrict to a MIME type (e.g. `application/vnd.google-apps.spreadsheet`). */
29
+ mimeType?: string;
30
+ /** Restrict to a folder id. */
31
+ folderId?: string;
32
+ max?: number;
33
+ }
34
+ /** What `readContent` returns. */
35
+ export interface DriveContent {
36
+ file: DriveFile;
37
+ /** MIME type of `content` (`text/plain`, `text/csv`, or the file's own). */
38
+ contentType: string;
39
+ /** UTF-8 text for text-like files; base64 for binary files. */
40
+ content: string;
41
+ encoding: 'utf8' | 'base64';
42
+ bytes: number;
43
+ }
44
+ /** Upload input. */
45
+ export interface DriveUploadInput {
46
+ name: string;
47
+ mimeType?: string;
48
+ /** UTF-8 text, or base64 when `encoding` is `base64`. */
49
+ content: string;
50
+ encoding?: 'utf8' | 'base64';
51
+ folderId?: string;
52
+ /** Convert to the Google-native type (`application/vnd.google-apps.document` …) on upload. */
53
+ convertTo?: string;
54
+ }
55
+ interface DriveWireFile {
56
+ id?: string;
57
+ name?: string;
58
+ mimeType?: string;
59
+ modifiedTime?: string;
60
+ size?: string;
61
+ webViewLink?: string;
62
+ owners?: Array<{
63
+ emailAddress?: string;
64
+ }>;
65
+ parents?: string[];
66
+ }
67
+ /**
68
+ * Trim a Drive file resource to {@link DriveFile}.
69
+ *
70
+ * @param wire - Google's file resource
71
+ * @returns The trimmed file
72
+ */
73
+ export declare function toDriveFile(wire: DriveWireFile): DriveFile;
74
+ /**
75
+ * Escape a value for a Drive `q` string literal.
76
+ *
77
+ * @param value - Raw text
78
+ * @returns Escaped text (backslashes and single quotes)
79
+ */
80
+ export declare function escapeDriveQuery(value: string): string;
81
+ /**
82
+ * Build the Drive `q` expression for a search.
83
+ *
84
+ * @param input - Search input
85
+ * @returns The `q` string
86
+ */
87
+ export declare function buildDriveQuery(input: DriveSearchInput): string;
88
+ /**
89
+ * Whether a MIME type is something an agent can read as text.
90
+ *
91
+ * @param mimeType - MIME type
92
+ * @returns True for text/*, JSON, XML, CSV and friends
93
+ */
94
+ export declare function isTextMime(mimeType: string): boolean;
95
+ /**
96
+ * Drive: search, metadata, content, upload.
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * const drive = new DriveService({ tokens });
101
+ * const hits = await drive.search({ query: 'Q3 plan' });
102
+ * ```
103
+ */
104
+ export declare class DriveService {
105
+ private readonly deps;
106
+ private readonly base;
107
+ private readonly uploadBase;
108
+ /**
109
+ * @param deps - Token provider and optional fetch override
110
+ */
111
+ constructor(deps: GoogleApiDeps);
112
+ /**
113
+ * `files.list` — most recently modified first.
114
+ *
115
+ * @param input - Query / MIME / folder / cap
116
+ * @returns Matching files
117
+ * @throws GoogleWorkspaceError on auth / Google failures
118
+ */
119
+ search(input?: DriveSearchInput): Promise<DriveFile[]>;
120
+ /**
121
+ * `files.get` metadata.
122
+ *
123
+ * @param id - File id
124
+ * @returns The file
125
+ * @throws GoogleWorkspaceError(400, validation) without an id; Google 404 passes through
126
+ */
127
+ get(id: string): Promise<DriveFile>;
128
+ /**
129
+ * File content: Google-native types are exported (Docs → text/plain,
130
+ * Sheets → text/csv, Slides → text/plain); other files are downloaded and
131
+ * returned as UTF-8 when text-like, else base64.
132
+ *
133
+ * @param id - File id
134
+ * @returns Content with its type and encoding
135
+ * @throws GoogleWorkspaceError(413, validation) when the file exceeds DRIVE_MAX_CONTENT_BYTES
136
+ */
137
+ readContent(id: string): Promise<DriveContent>;
138
+ /**
139
+ * Multipart `files.create` — a new file in My Drive (or a folder),
140
+ * optionally converted to a Google-native type.
141
+ *
142
+ * @param input - Name, MIME, content, folder, conversion
143
+ * @returns The created file
144
+ * @throws GoogleWorkspaceError(400, validation) for a missing name/content or oversized content
145
+ */
146
+ upload(input: DriveUploadInput): Promise<DriveFile>;
147
+ }
148
+ /**
149
+ * Validate a file / document id.
150
+ *
151
+ * @param id - Candidate id
152
+ * @returns The trimmed id
153
+ * @throws GoogleWorkspaceError(400, validation) when empty
154
+ */
155
+ export declare function requireId(id: string | undefined): string;
156
+ export {};
157
+ //# sourceMappingURL=drive.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drive.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/google/drive.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,203 @@
1
+ /**
2
+ * DriveService — Google Drive over the owner's Workspace grant.
3
+ *
4
+ * Works within the scopes the grant already carries: `drive.readonly`
5
+ * (search, metadata, download / export of anything the owner can see) and
6
+ * `drive.file` (upload; the created files are then editable by Crewly).
7
+ * Google-native files (Docs / Sheets / Slides) are read through `export`
8
+ * as text / CSV so an agent gets something it can reason about.
9
+ *
10
+ * @module services/google/drive.service
11
+ */
12
+ import { randomBytes } from 'crypto';
13
+ import { GOOGLE_WORKSPACE_CONSTANTS } from '../../constants.js';
14
+ import { GoogleWorkspaceError } from './google-workspace-token.service.js';
15
+ import { buildGoogleUrl, googleRequest } from './google-api.client.js';
16
+ import { clampMax } from './gmail.service.js';
17
+ const FILE_FIELDS = 'id,name,mimeType,modifiedTime,size,webViewLink,owners(emailAddress),parents';
18
+ /**
19
+ * Trim a Drive file resource to {@link DriveFile}.
20
+ *
21
+ * @param wire - Google's file resource
22
+ * @returns The trimmed file
23
+ */
24
+ export function toDriveFile(wire) {
25
+ return {
26
+ id: wire.id ?? '',
27
+ name: wire.name ?? '',
28
+ mimeType: wire.mimeType ?? '',
29
+ ...(wire.modifiedTime ? { modifiedTime: wire.modifiedTime } : {}),
30
+ ...(wire.size ? { size: Number(wire.size) } : {}),
31
+ ...(wire.webViewLink ? { webViewLink: wire.webViewLink } : {}),
32
+ ...(wire.owners?.length ? { owners: wire.owners.map((o) => o.emailAddress ?? '').filter(Boolean) } : {}),
33
+ ...(wire.parents?.length ? { parents: wire.parents } : {}),
34
+ };
35
+ }
36
+ /**
37
+ * Escape a value for a Drive `q` string literal.
38
+ *
39
+ * @param value - Raw text
40
+ * @returns Escaped text (backslashes and single quotes)
41
+ */
42
+ export function escapeDriveQuery(value) {
43
+ return value.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
44
+ }
45
+ /**
46
+ * Build the Drive `q` expression for a search.
47
+ *
48
+ * @param input - Search input
49
+ * @returns The `q` string
50
+ */
51
+ export function buildDriveQuery(input) {
52
+ const terms = ['trashed = false'];
53
+ const text = (input.query ?? '').trim();
54
+ if (text) {
55
+ const escaped = escapeDriveQuery(text);
56
+ terms.push(`(name contains '${escaped}' or fullText contains '${escaped}')`);
57
+ }
58
+ if (input.mimeType?.trim())
59
+ terms.push(`mimeType = '${escapeDriveQuery(input.mimeType.trim())}'`);
60
+ if (input.folderId?.trim())
61
+ terms.push(`'${escapeDriveQuery(input.folderId.trim())}' in parents`);
62
+ return terms.join(' and ');
63
+ }
64
+ /**
65
+ * Whether a MIME type is something an agent can read as text.
66
+ *
67
+ * @param mimeType - MIME type
68
+ * @returns True for text/*, JSON, XML, CSV and friends
69
+ */
70
+ export function isTextMime(mimeType) {
71
+ return /^text\//.test(mimeType) || /\b(json|xml|csv|javascript|yaml|markdown)\b/.test(mimeType);
72
+ }
73
+ /**
74
+ * Drive: search, metadata, content, upload.
75
+ *
76
+ * @example
77
+ * ```ts
78
+ * const drive = new DriveService({ tokens });
79
+ * const hits = await drive.search({ query: 'Q3 plan' });
80
+ * ```
81
+ */
82
+ export class DriveService {
83
+ deps;
84
+ base = GOOGLE_WORKSPACE_CONSTANTS.DRIVE_API_BASE;
85
+ uploadBase = GOOGLE_WORKSPACE_CONSTANTS.DRIVE_UPLOAD_BASE;
86
+ /**
87
+ * @param deps - Token provider and optional fetch override
88
+ */
89
+ constructor(deps) {
90
+ this.deps = deps;
91
+ }
92
+ /**
93
+ * `files.list` — most recently modified first.
94
+ *
95
+ * @param input - Query / MIME / folder / cap
96
+ * @returns Matching files
97
+ * @throws GoogleWorkspaceError on auth / Google failures
98
+ */
99
+ async search(input = {}) {
100
+ const max = clampMax(input.max, GOOGLE_WORKSPACE_CONSTANTS.DRIVE_DEFAULT_MAX_RESULTS, GOOGLE_WORKSPACE_CONSTANTS.DRIVE_MAX_RESULTS_CEILING);
101
+ const data = await googleRequest(this.deps, buildGoogleUrl(`${this.base}/files`, {
102
+ q: buildDriveQuery(input),
103
+ pageSize: max,
104
+ orderBy: 'modifiedTime desc',
105
+ fields: `files(${FILE_FIELDS})`,
106
+ supportsAllDrives: 'true',
107
+ includeItemsFromAllDrives: 'true',
108
+ }));
109
+ return (data.files ?? []).map(toDriveFile);
110
+ }
111
+ /**
112
+ * `files.get` metadata.
113
+ *
114
+ * @param id - File id
115
+ * @returns The file
116
+ * @throws GoogleWorkspaceError(400, validation) without an id; Google 404 passes through
117
+ */
118
+ async get(id) {
119
+ const fileId = requireId(id);
120
+ const wire = await googleRequest(this.deps, buildGoogleUrl(`${this.base}/files/${encodeURIComponent(fileId)}`, { fields: FILE_FIELDS, supportsAllDrives: 'true' }));
121
+ return toDriveFile(wire);
122
+ }
123
+ /**
124
+ * File content: Google-native types are exported (Docs → text/plain,
125
+ * Sheets → text/csv, Slides → text/plain); other files are downloaded and
126
+ * returned as UTF-8 when text-like, else base64.
127
+ *
128
+ * @param id - File id
129
+ * @returns Content with its type and encoding
130
+ * @throws GoogleWorkspaceError(413, validation) when the file exceeds DRIVE_MAX_CONTENT_BYTES
131
+ */
132
+ async readContent(id) {
133
+ const file = await this.get(id);
134
+ const exportMime = GOOGLE_WORKSPACE_CONSTANTS.DRIVE_EXPORT_MIME[file.mimeType];
135
+ if (exportMime) {
136
+ const text = await googleRequest(this.deps, buildGoogleUrl(`${this.base}/files/${encodeURIComponent(file.id)}/export`, { mimeType: exportMime }), { responseType: 'text' });
137
+ return { file, contentType: exportMime, content: text, encoding: 'utf8', bytes: Buffer.byteLength(text, 'utf8') };
138
+ }
139
+ if (file.mimeType.startsWith('application/vnd.google-apps.')) {
140
+ throw new GoogleWorkspaceError(400, GOOGLE_WORKSPACE_CONSTANTS.ERROR_CODES.VALIDATION, `Cannot read a ${file.mimeType} as text`);
141
+ }
142
+ if ((file.size ?? 0) > GOOGLE_WORKSPACE_CONSTANTS.DRIVE_MAX_CONTENT_BYTES) {
143
+ throw new GoogleWorkspaceError(413, GOOGLE_WORKSPACE_CONSTANTS.ERROR_CODES.VALIDATION, `File is larger than ${GOOGLE_WORKSPACE_CONSTANTS.DRIVE_MAX_CONTENT_BYTES} bytes; open it via webViewLink instead`);
144
+ }
145
+ const raw = await googleRequest(this.deps, buildGoogleUrl(`${this.base}/files/${encodeURIComponent(file.id)}`, { alt: 'media', supportsAllDrives: 'true' }), { responseType: 'text' });
146
+ if (isTextMime(file.mimeType)) {
147
+ return { file, contentType: file.mimeType, content: raw, encoding: 'utf8', bytes: Buffer.byteLength(raw, 'utf8') };
148
+ }
149
+ // fetch's text() decoded as UTF-8; re-encode as latin1 to recover the bytes for small binaries.
150
+ const buf = Buffer.from(raw, 'latin1');
151
+ return { file, contentType: file.mimeType, content: buf.toString('base64'), encoding: 'base64', bytes: buf.length };
152
+ }
153
+ /**
154
+ * Multipart `files.create` — a new file in My Drive (or a folder),
155
+ * optionally converted to a Google-native type.
156
+ *
157
+ * @param input - Name, MIME, content, folder, conversion
158
+ * @returns The created file
159
+ * @throws GoogleWorkspaceError(400, validation) for a missing name/content or oversized content
160
+ */
161
+ async upload(input) {
162
+ const CODES = GOOGLE_WORKSPACE_CONSTANTS.ERROR_CODES;
163
+ const name = (input.name ?? '').trim();
164
+ if (!name)
165
+ throw new GoogleWorkspaceError(400, CODES.VALIDATION, '"name" is required');
166
+ if (typeof input.content !== 'string' || input.content.length === 0) {
167
+ throw new GoogleWorkspaceError(400, CODES.VALIDATION, '"content" is required');
168
+ }
169
+ const bytes = input.encoding === 'base64' ? Buffer.from(input.content, 'base64') : Buffer.from(input.content, 'utf8');
170
+ if (bytes.length > GOOGLE_WORKSPACE_CONSTANTS.DRIVE_MAX_CONTENT_BYTES) {
171
+ throw new GoogleWorkspaceError(400, CODES.VALIDATION, `content exceeds ${GOOGLE_WORKSPACE_CONSTANTS.DRIVE_MAX_CONTENT_BYTES} bytes`);
172
+ }
173
+ const mimeType = input.mimeType?.trim() || (input.encoding === 'base64' ? 'application/octet-stream' : 'text/plain');
174
+ const metadata = { name };
175
+ if (input.convertTo?.trim())
176
+ metadata.mimeType = input.convertTo.trim();
177
+ if (input.folderId?.trim())
178
+ metadata.parents = [input.folderId.trim()];
179
+ const boundary = `crewly-${randomBytes(12).toString('hex')}`;
180
+ const body = Buffer.concat([
181
+ Buffer.from(`--${boundary}\r\nContent-Type: application/json; charset=UTF-8\r\n\r\n${JSON.stringify(metadata)}\r\n`, 'utf8'),
182
+ Buffer.from(`--${boundary}\r\nContent-Type: ${mimeType}\r\n\r\n`, 'utf8'),
183
+ bytes,
184
+ Buffer.from(`\r\n--${boundary}--`, 'utf8'),
185
+ ]);
186
+ const wire = await googleRequest(this.deps, buildGoogleUrl(`${this.uploadBase}/files`, { uploadType: 'multipart', fields: FILE_FIELDS, supportsAllDrives: 'true' }), { method: 'POST', rawBody: body, contentType: `multipart/related; boundary=${boundary}` });
187
+ return toDriveFile(wire);
188
+ }
189
+ }
190
+ /**
191
+ * Validate a file / document id.
192
+ *
193
+ * @param id - Candidate id
194
+ * @returns The trimmed id
195
+ * @throws GoogleWorkspaceError(400, validation) when empty
196
+ */
197
+ export function requireId(id) {
198
+ const value = (id ?? '').trim();
199
+ if (!value)
200
+ throw new GoogleWorkspaceError(400, GOOGLE_WORKSPACE_CONSTANTS.ERROR_CODES.VALIDATION, '"id" is required');
201
+ return value;
202
+ }
203
+ //# sourceMappingURL=drive.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drive.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/google/drive.service.ts"],"names":[],"mappings":"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"}
@@ -26,19 +26,27 @@ export interface GoogleApiDeps {
26
26
  * @returns The full URL string
27
27
  */
28
28
  export declare function buildGoogleUrl(base: string, params?: Record<string, string | number | string[] | undefined>): string;
29
+ /** Request options for {@link googleRequest}. */
30
+ export interface GoogleRequestInit {
31
+ method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
32
+ /** JSON body (serialised, `Content-Type: application/json`). */
33
+ body?: unknown;
34
+ /** Pre-encoded body (multipart upload, binary) — needs `contentType`. */
35
+ rawBody?: string | Buffer;
36
+ contentType?: string;
37
+ /** `text` returns the body verbatim (Drive export / `alt=media`); default `json`. */
38
+ responseType?: 'json' | 'text';
39
+ }
29
40
  /**
30
- * Authenticated JSON call to a Google API.
41
+ * Authenticated call to a Google API.
31
42
  *
32
43
  * @param deps - Token provider + fetch
33
44
  * @param url - Absolute URL (use {@link buildGoogleUrl})
34
- * @param init - Method and optional JSON body
35
- * @returns The parsed JSON response
45
+ * @param init - Method, body and response type
46
+ * @returns The parsed JSON response (or the raw text with `responseType: 'text'`)
36
47
  * @throws GoogleWorkspaceError — token failures pass through; Google 401 →
37
48
  * 401 google_error (cache dropped), 403/404/429 keep their status, other
38
49
  * failures → 502 google_error, unreachable → 502 network
39
50
  */
40
- export declare function googleRequest<T>(deps: GoogleApiDeps, url: string, init?: {
41
- method?: 'GET' | 'POST';
42
- body?: unknown;
43
- }): Promise<T>;
51
+ export declare function googleRequest<T>(deps: GoogleApiDeps, url: string, init?: GoogleRequestInit): Promise<T>;
44
52
  //# sourceMappingURL=google-api.client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"google-api.client.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/google/google-api.client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,yEAAyE;AACzE,MAAM,WAAW,mBAAmB;IAClC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,UAAU,IAAI,IAAI,CAAC;CACpB;AAED,qEAAqE;AACrE,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,mBAAmB,CAAC;IAC5B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAwBD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAM,GAAG,MAAM,CAWxH;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CAAC,CAAC,EACnC,IAAI,EAAE,aAAa,EACnB,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,GACrD,OAAO,CAAC,CAAC,CAAC,CAsCZ"}
1
+ {"version":3,"file":"google-api.client.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/google/google-api.client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,yEAAyE;AACzE,MAAM,WAAW,mBAAmB;IAClC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,UAAU,IAAI,IAAI,CAAC;CACpB;AAED,qEAAqE;AACrE,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,mBAAmB,CAAC;IAC5B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAwBD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAM,GAAG,MAAM,CAWxH;AAED,iDAAiD;AACjD,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACrD,gEAAgE;IAChE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qFAAqF;IACrF,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAChC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CAAC,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,iBAAsB,GAAG,OAAO,CAAC,CAAC,CAAC,CA4CjH"}
@@ -51,12 +51,12 @@ export function buildGoogleUrl(base, params = {}) {
51
51
  return url.toString();
52
52
  }
53
53
  /**
54
- * Authenticated JSON call to a Google API.
54
+ * Authenticated call to a Google API.
55
55
  *
56
56
  * @param deps - Token provider + fetch
57
57
  * @param url - Absolute URL (use {@link buildGoogleUrl})
58
- * @param init - Method and optional JSON body
59
- * @returns The parsed JSON response
58
+ * @param init - Method, body and response type
59
+ * @returns The parsed JSON response (or the raw text with `responseType: 'text'`)
60
60
  * @throws GoogleWorkspaceError — token failures pass through; Google 401 →
61
61
  * 401 google_error (cache dropped), 403/404/429 keep their status, other
62
62
  * failures → 502 google_error, unreachable → 502 network
@@ -65,16 +65,21 @@ export async function googleRequest(deps, url, init = {}) {
65
65
  const token = await deps.tokens.getAccessToken();
66
66
  const fetchImpl = deps.fetchImpl ?? fetch;
67
67
  const CODES = GOOGLE_WORKSPACE_CONSTANTS.ERROR_CODES;
68
+ const wantsText = init.responseType === 'text';
68
69
  let res;
69
70
  try {
70
71
  res = await fetchImpl(url, {
71
72
  method: init.method ?? 'GET',
72
73
  headers: {
73
74
  Authorization: `Bearer ${token}`,
74
- Accept: 'application/json',
75
- ...(init.body !== undefined ? { 'Content-Type': 'application/json' } : {}),
75
+ Accept: wantsText ? '*/*' : 'application/json',
76
+ ...(init.rawBody !== undefined
77
+ ? { 'Content-Type': init.contentType ?? 'application/octet-stream' }
78
+ : init.body !== undefined
79
+ ? { 'Content-Type': 'application/json' }
80
+ : {}),
76
81
  },
77
- body: init.body !== undefined ? JSON.stringify(init.body) : undefined,
82
+ body: init.rawBody !== undefined ? init.rawBody : init.body !== undefined ? JSON.stringify(init.body) : undefined,
78
83
  signal: AbortSignal.timeout(GOOGLE_WORKSPACE_CONSTANTS.REQUEST_TIMEOUT_MS),
79
84
  });
80
85
  }
@@ -92,6 +97,8 @@ export async function googleRequest(deps, url, init = {}) {
92
97
  const passthrough = res.status === 403 || res.status === 404 || res.status === 429;
93
98
  throw new GoogleWorkspaceError(passthrough ? res.status : 502, CODES.GOOGLE_ERROR, message);
94
99
  }
100
+ if (wantsText)
101
+ return text;
95
102
  if (!text)
96
103
  return {};
97
104
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"google-api.client.js","sourceRoot":"","sources":["../../../../../../backend/src/services/google/google-api.client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"google-api.client.js","sourceRoot":"","sources":["../../../../../../backend/src/services/google/google-api.client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAmB3E;;;;;;GAMG;AACH,SAAS,kBAAkB,CAAC,IAAY;IACtC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAoB,CAAC;QACnD,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ;YAAE,OAAO,MAAM,CAAC,KAAK,CAAC;QAC1D,OAAO,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/C,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,SAAiE,EAAE;IAC9G,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;YAAE,SAAS;QAClD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,KAAK,MAAM,CAAC,IAAI,KAAK;gBAAE,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACzD,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC;AAcD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAI,IAAmB,EAAE,GAAW,EAAE,OAA0B,EAAE;IACnG,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;IACjD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC;IAC1C,MAAM,KAAK,GAAG,0BAA0B,CAAC,WAAW,CAAC;IACrD,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,KAAK,MAAM,CAAC;IAE/C,IAAI,GAAa,CAAC;IAClB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE;YACzB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK;YAC5B,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,KAAK,EAAE;gBAChC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,kBAAkB;gBAC9C,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS;oBAC5B,CAAC,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,WAAW,IAAI,0BAA0B,EAAE;oBACpE,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS;wBACvB,CAAC,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE;wBACxC,CAAC,CAAC,EAAE,CAAC;aACV;YACD,IAAI,EAAE,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;YACjH,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,0BAA0B,CAAC,kBAAkB,CAAC;SAC3E,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,MAAM,IAAI,oBAAoB,CAAC,GAAG,EAAE,KAAK,CAAC,OAAO,EAAE,uBAAuB,OAAO,EAAE,CAAC,CAAC;IACvF,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,0BAA0B,GAAG,CAAC,MAAM,GAAG,CAAC;QACpF,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvB,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YACzB,MAAM,IAAI,oBAAoB,CAAC,GAAG,EAAE,KAAK,CAAC,YAAY,EAAE,qCAAqC,OAAO,EAAE,CAAC,CAAC;QAC1G,CAAC;QACD,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC;QACnF,MAAM,IAAI,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC9F,CAAC;IACD,IAAI,SAAS;QAAE,OAAO,IAAoB,CAAC;IAC3C,IAAI,CAAC,IAAI;QAAE,OAAO,EAAO,CAAC;IAC1B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAM,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,oBAAoB,CAAC,GAAG,EAAE,KAAK,CAAC,YAAY,EAAE,sCAAsC,CAAC,CAAC;IAClG,CAAC;AACH,CAAC"}