crewly 1.20.29 → 1.20.31

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 (112) 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/agent/agent-registration.service.d.ts.map +1 -1
  64. package/dist/backend/backend/src/services/agent/agent-registration.service.js +22 -4
  65. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  66. package/dist/backend/backend/src/services/canva/canva-token.service.d.ts +98 -0
  67. package/dist/backend/backend/src/services/canva/canva-token.service.d.ts.map +1 -0
  68. package/dist/backend/backend/src/services/canva/canva-token.service.js +198 -0
  69. package/dist/backend/backend/src/services/canva/canva-token.service.js.map +1 -0
  70. package/dist/backend/backend/src/services/canva/canva.service.d.ts +184 -0
  71. package/dist/backend/backend/src/services/canva/canva.service.d.ts.map +1 -0
  72. package/dist/backend/backend/src/services/canva/canva.service.js +274 -0
  73. package/dist/backend/backend/src/services/canva/canva.service.js.map +1 -0
  74. package/dist/backend/backend/src/services/google/docs.service.d.ts +117 -0
  75. package/dist/backend/backend/src/services/google/docs.service.d.ts.map +1 -0
  76. package/dist/backend/backend/src/services/google/docs.service.js +152 -0
  77. package/dist/backend/backend/src/services/google/docs.service.js.map +1 -0
  78. package/dist/backend/backend/src/services/google/drive.service.d.ts +157 -0
  79. package/dist/backend/backend/src/services/google/drive.service.d.ts.map +1 -0
  80. package/dist/backend/backend/src/services/google/drive.service.js +203 -0
  81. package/dist/backend/backend/src/services/google/drive.service.js.map +1 -0
  82. package/dist/backend/backend/src/services/google/google-api.client.d.ts +15 -7
  83. package/dist/backend/backend/src/services/google/google-api.client.d.ts.map +1 -1
  84. package/dist/backend/backend/src/services/google/google-api.client.js +13 -6
  85. package/dist/backend/backend/src/services/google/google-api.client.js.map +1 -1
  86. package/dist/backend/backend/src/services/google/sheets.service.d.ts +118 -0
  87. package/dist/backend/backend/src/services/google/sheets.service.d.ts.map +1 -0
  88. package/dist/backend/backend/src/services/google/sheets.service.js +158 -0
  89. package/dist/backend/backend/src/services/google/sheets.service.js.map +1 -0
  90. package/dist/backend/backend/src/services/google/slides.service.d.ts +136 -0
  91. package/dist/backend/backend/src/services/google/slides.service.d.ts.map +1 -0
  92. package/dist/backend/backend/src/services/google/slides.service.js +153 -0
  93. package/dist/backend/backend/src/services/google/slides.service.js.map +1 -0
  94. package/dist/backend/backend/src/utils/tool-call-markup.utils.d.ts +45 -0
  95. package/dist/backend/backend/src/utils/tool-call-markup.utils.d.ts.map +1 -0
  96. package/dist/backend/backend/src/utils/tool-call-markup.utils.js +83 -0
  97. package/dist/backend/backend/src/utils/tool-call-markup.utils.js.map +1 -0
  98. package/dist/backend/build-info.json +2 -2
  99. package/dist/cli/backend/src/constants.d.ts +69 -0
  100. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  101. package/dist/cli/backend/src/constants.js +73 -0
  102. package/dist/cli/backend/src/constants.js.map +1 -1
  103. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  104. package/dist/cli/backend/src/services/agent/agent-registration.service.js +22 -4
  105. package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
  106. package/dist/cli/backend/src/utils/tool-call-markup.utils.d.ts +45 -0
  107. package/dist/cli/backend/src/utils/tool-call-markup.utils.d.ts.map +1 -0
  108. package/dist/cli/backend/src/utils/tool-call-markup.utils.js +83 -0
  109. package/dist/cli/backend/src/utils/tool-call-markup.utils.js.map +1 -0
  110. package/frontend/dist/assets/{index-d1bd0dec.js → index-96b51cd9.js} +243 -243
  111. package/frontend/dist/index.html +1 -1
  112. package/package.json +1 -1
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Canva controller — `/api/canva/*` on this instance.
3
+ *
4
+ * Grant management goes through Cloud (status / connect-url / disconnect);
5
+ * designs, exports and assets go straight to api.canva.com with the token
6
+ * Cloud mints. Backs the canva-* skills.
7
+ *
8
+ * @module controllers/canva/canva.controller
9
+ */
10
+ import { CANVA_CONSTANTS } from '../../constants.js';
11
+ import { LoggerService } from '../../services/core/logger.service.js';
12
+ import { CanvaTokenService, CanvaError } from '../../services/canva/canva-token.service.js';
13
+ import { CanvaService } from '../../services/canva/canva.service.js';
14
+ const logger = LoggerService.getInstance().createComponentLogger('CanvaController');
15
+ let deps = null;
16
+ function getDeps() {
17
+ if (!deps) {
18
+ const tokens = CanvaTokenService.getInstance();
19
+ deps = { tokens, canva: new CanvaService({ tokens }) };
20
+ }
21
+ return deps;
22
+ }
23
+ /**
24
+ * Replace the dependency set (tests).
25
+ *
26
+ * @param next - Deps or null to rebuild lazily
27
+ */
28
+ export function setCanvaControllerDeps(next) {
29
+ deps = next;
30
+ }
31
+ function resolveReturnUrl(req) {
32
+ const explicit = typeof req.query.returnUrl === 'string' ? req.query.returnUrl : '';
33
+ if (/^https?:\/\//i.test(explicit))
34
+ return explicit;
35
+ return `${req.protocol}://${req.get('host')}${CANVA_CONSTANTS.SETTINGS_RETURN_PATH}`;
36
+ }
37
+ function connectUrlOrNull(req) {
38
+ try {
39
+ return getDeps().tokens.buildConnectUrl(resolveReturnUrl(req));
40
+ }
41
+ catch {
42
+ return null;
43
+ }
44
+ }
45
+ /**
46
+ * Answer a failure with `{ success:false, error, message, hint }`.
47
+ *
48
+ * @param req - Request (for the connect URL hint)
49
+ * @param res - Response
50
+ * @param err - The failure
51
+ */
52
+ export function sendCanvaError(req, res, err) {
53
+ const CODES = CANVA_CONSTANTS.ERROR_CODES;
54
+ if (err instanceof CanvaError) {
55
+ let hint;
56
+ switch (err.code) {
57
+ case CODES.NOT_CONNECTED:
58
+ hint = connectUrlOrNull(req) ?? 'Sign in to Crewly Cloud (Settings → Cloud), then connect Canva under Settings → Integrations.';
59
+ break;
60
+ case CODES.NOT_LOGGED_IN:
61
+ hint = 'Sign in to Crewly Cloud first (Settings → Cloud).';
62
+ break;
63
+ case CODES.NOT_CONFIGURED:
64
+ hint = 'Crewly Cloud is not configured for Canva; nothing to do on this instance.';
65
+ break;
66
+ case CODES.VALIDATION:
67
+ hint = 'Fix the request and retry.';
68
+ break;
69
+ default:
70
+ hint = err.status === 401 ? 'The Canva token was rejected; retry once — the cache has been cleared.' : 'Canva or Crewly Cloud failed; retry later.';
71
+ }
72
+ res.status(err.status).json({ success: false, error: err.code, message: err.message, hint });
73
+ return;
74
+ }
75
+ const message = err instanceof Error ? err.message : String(err);
76
+ logger.error('Unexpected Canva failure', { error: message });
77
+ res.status(500).json({ success: false, error: 'internal', message, hint: 'Check the backend log.' });
78
+ }
79
+ function q(req, name) {
80
+ const v = req.query[name];
81
+ return typeof v === 'string' ? v.trim() : '';
82
+ }
83
+ function qInt(req, name) {
84
+ const v = q(req, name);
85
+ return v ? Number.parseInt(v, 10) : undefined;
86
+ }
87
+ /** GET /api/canva/status */
88
+ export async function getStatus(req, res) {
89
+ try {
90
+ res.json({ success: true, data: await getDeps().tokens.status() });
91
+ }
92
+ catch (err) {
93
+ sendCanvaError(req, res, err);
94
+ }
95
+ }
96
+ /** GET /api/canva/connect-url — `{ url }` to open in the browser. */
97
+ export async function getConnectUrl(req, res) {
98
+ try {
99
+ res.json({ success: true, data: { url: getDeps().tokens.buildConnectUrl(resolveReturnUrl(req)) } });
100
+ }
101
+ catch (err) {
102
+ sendCanvaError(req, res, err);
103
+ }
104
+ }
105
+ /** DELETE /api/canva/disconnect */
106
+ export async function disconnect(req, res) {
107
+ try {
108
+ res.json({ success: true, data: await getDeps().tokens.disconnect() });
109
+ }
110
+ catch (err) {
111
+ sendCanvaError(req, res, err);
112
+ }
113
+ }
114
+ /** GET /api/canva/designs?q=&ownership=&sort=&limit=&continuation= */
115
+ export async function listDesigns(req, res) {
116
+ try {
117
+ const ownership = q(req, 'ownership');
118
+ const sort = q(req, 'sort');
119
+ const out = await getDeps().canva.listDesigns({
120
+ query: q(req, 'q') || undefined,
121
+ ownership: ownership === 'owned' || ownership === 'shared' || ownership === 'any' ? ownership : undefined,
122
+ sortBy: ['relevance', 'modified_descending', 'modified_ascending', 'title_descending', 'title_ascending'].find((s) => s === sort),
123
+ limit: qInt(req, 'limit'),
124
+ continuation: q(req, 'continuation') || undefined,
125
+ });
126
+ res.json({ success: true, data: { count: out.designs.length, designs: out.designs, ...(out.continuation ? { continuation: out.continuation } : {}) } });
127
+ }
128
+ catch (err) {
129
+ sendCanvaError(req, res, err);
130
+ }
131
+ }
132
+ /** GET /api/canva/designs/:id */
133
+ export async function getDesign(req, res) {
134
+ try {
135
+ res.json({ success: true, data: await getDeps().canva.getDesign(String(req.params.id ?? '')) });
136
+ }
137
+ catch (err) {
138
+ sendCanvaError(req, res, err);
139
+ }
140
+ }
141
+ /** POST /api/canva/designs — `{ title?, preset?, width?, height?, assetId? }` */
142
+ export async function createDesign(req, res) {
143
+ try {
144
+ const body = (req.body ?? {});
145
+ const design = await getDeps().canva.createDesign({ title: body.title, preset: body.preset, width: body.width, height: body.height, assetId: body.assetId });
146
+ logger.info('Canva design created', { id: design.id, title: design.title });
147
+ res.json({ success: true, data: design });
148
+ }
149
+ catch (err) {
150
+ sendCanvaError(req, res, err);
151
+ }
152
+ }
153
+ /** POST /api/canva/designs/:id/export — `{ format, quality?, videoQuality?, pages? }` */
154
+ export async function exportDesign(req, res) {
155
+ try {
156
+ const body = (req.body ?? {});
157
+ const out = await getDeps().canva.exportDesign({
158
+ designId: String(req.params.id ?? ''),
159
+ format: String(body.format ?? ''),
160
+ quality: body.quality,
161
+ videoQuality: body.videoQuality,
162
+ pages: Array.isArray(body.pages) ? body.pages : undefined,
163
+ });
164
+ res.json({ success: out.status === 'success', data: out });
165
+ }
166
+ catch (err) {
167
+ sendCanvaError(req, res, err);
168
+ }
169
+ }
170
+ /** POST /api/canva/assets — `{ name, content (base64) }` */
171
+ export async function uploadAsset(req, res) {
172
+ try {
173
+ const body = (req.body ?? {});
174
+ const bytes = typeof body.content === 'string' ? Buffer.from(body.content, 'base64') : Buffer.alloc(0);
175
+ const asset = await getDeps().canva.uploadAsset(String(body.name ?? ''), bytes);
176
+ logger.info('Canva asset uploaded', { id: asset.id, name: asset.name, bytes: bytes.length });
177
+ res.json({ success: true, data: asset });
178
+ }
179
+ catch (err) {
180
+ sendCanvaError(req, res, err);
181
+ }
182
+ }
183
+ //# sourceMappingURL=canva.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canva.controller.js","sourceRoot":"","sources":["../../../../../../backend/src/controllers/canva/canva.controller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Canva routes — mounted at `/api/canva`.
3
+ *
4
+ * - GET /status — grant status
5
+ * - GET /connect-url — Cloud consent-start URL
6
+ * - DELETE /disconnect — revoke + forget
7
+ * - GET /designs — ?q=&ownership=&sort=&limit=&continuation=
8
+ * - GET /designs/:id — one design
9
+ * - POST /designs — { title?, preset?, width?, height?, assetId? }
10
+ * - POST /designs/:id/export — { format, quality?, videoQuality?, pages? }
11
+ * - POST /assets — { name, content: base64 }
12
+ *
13
+ * @module controllers/canva/canva.routes
14
+ */
15
+ import { Router } from 'express';
16
+ /**
17
+ * Creates the Canva router.
18
+ *
19
+ * @returns Express router
20
+ */
21
+ export declare function createCanvaRouter(): Router;
22
+ //# sourceMappingURL=canva.routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canva.routes.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/controllers/canva/canva.routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAGjC;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAW1C"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Canva routes — mounted at `/api/canva`.
3
+ *
4
+ * - GET /status — grant status
5
+ * - GET /connect-url — Cloud consent-start URL
6
+ * - DELETE /disconnect — revoke + forget
7
+ * - GET /designs — ?q=&ownership=&sort=&limit=&continuation=
8
+ * - GET /designs/:id — one design
9
+ * - POST /designs — { title?, preset?, width?, height?, assetId? }
10
+ * - POST /designs/:id/export — { format, quality?, videoQuality?, pages? }
11
+ * - POST /assets — { name, content: base64 }
12
+ *
13
+ * @module controllers/canva/canva.routes
14
+ */
15
+ import { Router } from 'express';
16
+ import { getStatus, getConnectUrl, disconnect, listDesigns, getDesign, createDesign, exportDesign, uploadAsset } from './canva.controller.js';
17
+ /**
18
+ * Creates the Canva router.
19
+ *
20
+ * @returns Express router
21
+ */
22
+ export function createCanvaRouter() {
23
+ const router = Router();
24
+ router.get('/status', getStatus);
25
+ router.get('/connect-url', getConnectUrl);
26
+ router.delete('/disconnect', disconnect);
27
+ router.get('/designs', listDesigns);
28
+ router.get('/designs/:id', getDesign);
29
+ router.post('/designs', createDesign);
30
+ router.post('/designs/:id/export', exportDesign);
31
+ router.post('/assets', uploadAsset);
32
+ return router;
33
+ }
34
+ //# sourceMappingURL=canva.routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canva.routes.js","sourceRoot":"","sources":["../../../../../../backend/src/controllers/canva/canva.routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAE9I;;;;GAIG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC;IAC1C,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;IACzC,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IACpC,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;IACtC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IACtC,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE,YAAY,CAAC,CAAC;IACjD,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACpC,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -15,11 +15,19 @@ import type { Request, Response } from 'express';
15
15
  import { GoogleWorkspaceTokenService } from '../../services/google/google-workspace-token.service.js';
16
16
  import { GmailService } from '../../services/google/gmail.service.js';
17
17
  import { CalendarService } from '../../services/google/calendar.service.js';
18
+ import { DriveService } from '../../services/google/drive.service.js';
19
+ import { DocsService } from '../../services/google/docs.service.js';
20
+ import { SheetsService } from '../../services/google/sheets.service.js';
21
+ import { SlidesService } from '../../services/google/slides.service.js';
18
22
  /** The services the handlers use; swappable for tests. */
19
23
  export interface GoogleControllerDeps {
20
24
  tokens: GoogleWorkspaceTokenService;
21
25
  gmail: GmailService;
22
26
  calendar: CalendarService;
27
+ drive: DriveService;
28
+ docs: DocsService;
29
+ sheets: SheetsService;
30
+ slides: SlidesService;
23
31
  }
24
32
  /**
25
33
  * Replace (or, with null, reset) the services the handlers use. Tests only.
@@ -97,4 +105,96 @@ export declare function calendarList(req: Request, res: Response): Promise<void>
97
105
  * @param res - Response
98
106
  */
99
107
  export declare function calendarCreate(req: Request, res: Response): Promise<void>;
108
+ /**
109
+ * GET /api/google/drive/files?q=&mimeType=&folderId=&max= — search.
110
+ *
111
+ * @param req - Incoming request
112
+ * @param res - Response
113
+ */
114
+ export declare function driveSearch(req: Request, res: Response): Promise<void>;
115
+ /**
116
+ * GET /api/google/drive/files/:id — metadata.
117
+ *
118
+ * @param req - Incoming request
119
+ * @param res - Response
120
+ */
121
+ export declare function driveGet(req: Request, res: Response): Promise<void>;
122
+ /**
123
+ * GET /api/google/drive/files/:id/content — exported text / downloaded body.
124
+ *
125
+ * @param req - Incoming request
126
+ * @param res - Response
127
+ */
128
+ export declare function driveContent(req: Request, res: Response): Promise<void>;
129
+ /**
130
+ * POST /api/google/drive/files — body `{ name, content, encoding?, mimeType?, folderId?, convertTo? }`.
131
+ *
132
+ * @param req - Incoming request
133
+ * @param res - Response
134
+ */
135
+ export declare function driveUpload(req: Request, res: Response): Promise<void>;
136
+ /**
137
+ * GET /api/google/docs/:id — document as text.
138
+ *
139
+ * @param req - Incoming request
140
+ * @param res - Response
141
+ */
142
+ export declare function docsRead(req: Request, res: Response): Promise<void>;
143
+ /**
144
+ * POST /api/google/docs — body `{ title, text? }`.
145
+ *
146
+ * @param req - Incoming request
147
+ * @param res - Response
148
+ */
149
+ export declare function docsCreate(req: Request, res: Response): Promise<void>;
150
+ /**
151
+ * POST /api/google/docs/:id/append — body `{ text }`.
152
+ *
153
+ * @param req - Incoming request
154
+ * @param res - Response
155
+ */
156
+ export declare function docsAppend(req: Request, res: Response): Promise<void>;
157
+ /**
158
+ * GET /api/google/sheets/:id — title + tabs.
159
+ *
160
+ * @param req - Incoming request
161
+ * @param res - Response
162
+ */
163
+ export declare function sheetsInfo(req: Request, res: Response): Promise<void>;
164
+ /**
165
+ * GET /api/google/sheets/:id/values?range= — cell values.
166
+ *
167
+ * @param req - Incoming request
168
+ * @param res - Response
169
+ */
170
+ export declare function sheetsRead(req: Request, res: Response): Promise<void>;
171
+ /**
172
+ * POST /api/google/sheets — body `{ title, sheetTitle?, rows? }`.
173
+ *
174
+ * @param req - Incoming request
175
+ * @param res - Response
176
+ */
177
+ export declare function sheetsCreate(req: Request, res: Response): Promise<void>;
178
+ /**
179
+ * POST /api/google/sheets/:id/values — body `{ range?, rows, mode?: 'append' | 'update' }`
180
+ * (default append).
181
+ *
182
+ * @param req - Incoming request
183
+ * @param res - Response
184
+ */
185
+ export declare function sheetsWrite(req: Request, res: Response): Promise<void>;
186
+ /**
187
+ * GET /api/google/slides/:id — deck as text per slide.
188
+ *
189
+ * @param req - Incoming request
190
+ * @param res - Response
191
+ */
192
+ export declare function slidesRead(req: Request, res: Response): Promise<void>;
193
+ /**
194
+ * POST /api/google/slides — body `{ title, slides: [{ title, bullets? }] }`.
195
+ *
196
+ * @param req - Incoming request
197
+ * @param res - Response
198
+ */
199
+ export declare function slidesCreate(req: Request, res: Response): Promise<void>;
100
200
  //# sourceMappingURL=google.controller.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"google.controller.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/controllers/google/google.controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGjD,OAAO,EACL,2BAA2B,EAE5B,MAAM,yDAAyD,CAAC;AACjE,OAAO,EAAE,YAAY,EAAoC,MAAM,wCAAwC,CAAC;AACxG,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAI5E,0DAA0D;AAC1D,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,2BAA2B,CAAC;IACpC,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE,eAAe,CAAC;CAC3B;AAkBD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI,GAAG,IAAI,CAE/E;AA+BD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CA6B/E;AA0BD;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAO1E;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAO9E;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAO3E;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAW5E;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAO1E;AAED;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB1E;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAY7E;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB/E"}
1
+ {"version":3,"file":"google.controller.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/controllers/google/google.controller.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,10 @@ import { LoggerService } from '../../services/core/logger.service.js';
16
16
  import { GoogleWorkspaceTokenService, GoogleWorkspaceError, } from '../../services/google/google-workspace-token.service.js';
17
17
  import { GmailService, buildRfc822 } from '../../services/google/gmail.service.js';
18
18
  import { CalendarService } from '../../services/google/calendar.service.js';
19
+ import { DriveService } from '../../services/google/drive.service.js';
20
+ import { DocsService } from '../../services/google/docs.service.js';
21
+ import { SheetsService } from '../../services/google/sheets.service.js';
22
+ import { SlidesService } from '../../services/google/slides.service.js';
19
23
  const logger = LoggerService.getInstance().createComponentLogger('GoogleController');
20
24
  let deps = null;
21
25
  /**
@@ -27,7 +31,15 @@ let deps = null;
27
31
  function getDeps() {
28
32
  if (!deps) {
29
33
  const tokens = GoogleWorkspaceTokenService.getInstance();
30
- deps = { tokens, gmail: new GmailService({ tokens }), calendar: new CalendarService({ tokens }) };
34
+ deps = {
35
+ tokens,
36
+ gmail: new GmailService({ tokens }),
37
+ calendar: new CalendarService({ tokens }),
38
+ drive: new DriveService({ tokens }),
39
+ docs: new DocsService({ tokens }),
40
+ sheets: new SheetsService({ tokens }),
41
+ slides: new SlidesService({ tokens }),
42
+ };
31
43
  }
32
44
  return deps;
33
45
  }
@@ -290,4 +302,228 @@ export async function calendarCreate(req, res) {
290
302
  sendGoogleError(req, res, err);
291
303
  }
292
304
  }
305
+ // ---------------------------------------------------------------------------
306
+ // Drive
307
+ // ---------------------------------------------------------------------------
308
+ /**
309
+ * GET /api/google/drive/files?q=&mimeType=&folderId=&max= — search.
310
+ *
311
+ * @param req - Incoming request
312
+ * @param res - Response
313
+ */
314
+ export async function driveSearch(req, res) {
315
+ try {
316
+ const files = await getDeps().drive.search({
317
+ query: q(req, 'q') || undefined,
318
+ mimeType: q(req, 'mimeType') || undefined,
319
+ folderId: q(req, 'folderId') || undefined,
320
+ max: qInt(req, 'max'),
321
+ });
322
+ res.json({ success: true, data: { count: files.length, files } });
323
+ }
324
+ catch (err) {
325
+ sendGoogleError(req, res, err);
326
+ }
327
+ }
328
+ /**
329
+ * GET /api/google/drive/files/:id — metadata.
330
+ *
331
+ * @param req - Incoming request
332
+ * @param res - Response
333
+ */
334
+ export async function driveGet(req, res) {
335
+ try {
336
+ res.json({ success: true, data: await getDeps().drive.get(String(req.params.id ?? '')) });
337
+ }
338
+ catch (err) {
339
+ sendGoogleError(req, res, err);
340
+ }
341
+ }
342
+ /**
343
+ * GET /api/google/drive/files/:id/content — exported text / downloaded body.
344
+ *
345
+ * @param req - Incoming request
346
+ * @param res - Response
347
+ */
348
+ export async function driveContent(req, res) {
349
+ try {
350
+ res.json({ success: true, data: await getDeps().drive.readContent(String(req.params.id ?? '')) });
351
+ }
352
+ catch (err) {
353
+ sendGoogleError(req, res, err);
354
+ }
355
+ }
356
+ /**
357
+ * POST /api/google/drive/files — body `{ name, content, encoding?, mimeType?, folderId?, convertTo? }`.
358
+ *
359
+ * @param req - Incoming request
360
+ * @param res - Response
361
+ */
362
+ export async function driveUpload(req, res) {
363
+ try {
364
+ const body = (req.body ?? {});
365
+ const file = await getDeps().drive.upload({
366
+ name: String(body.name ?? ''),
367
+ content: typeof body.content === 'string' ? body.content : '',
368
+ encoding: body.encoding === 'base64' ? 'base64' : 'utf8',
369
+ mimeType: body.mimeType,
370
+ folderId: body.folderId,
371
+ convertTo: body.convertTo,
372
+ });
373
+ logger.info('Drive file uploaded', { id: file.id, name: file.name });
374
+ res.json({ success: true, data: file });
375
+ }
376
+ catch (err) {
377
+ sendGoogleError(req, res, err);
378
+ }
379
+ }
380
+ // ---------------------------------------------------------------------------
381
+ // Docs
382
+ // ---------------------------------------------------------------------------
383
+ /**
384
+ * GET /api/google/docs/:id — document as text.
385
+ *
386
+ * @param req - Incoming request
387
+ * @param res - Response
388
+ */
389
+ export async function docsRead(req, res) {
390
+ try {
391
+ res.json({ success: true, data: await getDeps().docs.read(String(req.params.id ?? '')) });
392
+ }
393
+ catch (err) {
394
+ sendGoogleError(req, res, err);
395
+ }
396
+ }
397
+ /**
398
+ * POST /api/google/docs — body `{ title, text? }`.
399
+ *
400
+ * @param req - Incoming request
401
+ * @param res - Response
402
+ */
403
+ export async function docsCreate(req, res) {
404
+ try {
405
+ const body = (req.body ?? {});
406
+ const doc = await getDeps().docs.create({ title: String(body.title ?? ''), text: typeof body.text === 'string' ? body.text : undefined });
407
+ logger.info('Google Doc created', { id: doc.id, title: doc.title });
408
+ res.json({ success: true, data: doc });
409
+ }
410
+ catch (err) {
411
+ sendGoogleError(req, res, err);
412
+ }
413
+ }
414
+ /**
415
+ * POST /api/google/docs/:id/append — body `{ text }`.
416
+ *
417
+ * @param req - Incoming request
418
+ * @param res - Response
419
+ */
420
+ export async function docsAppend(req, res) {
421
+ try {
422
+ const body = (req.body ?? {});
423
+ res.json({ success: true, data: await getDeps().docs.append(String(req.params.id ?? ''), String(body.text ?? '')) });
424
+ }
425
+ catch (err) {
426
+ sendGoogleError(req, res, err);
427
+ }
428
+ }
429
+ // ---------------------------------------------------------------------------
430
+ // Sheets
431
+ // ---------------------------------------------------------------------------
432
+ /**
433
+ * GET /api/google/sheets/:id — title + tabs.
434
+ *
435
+ * @param req - Incoming request
436
+ * @param res - Response
437
+ */
438
+ export async function sheetsInfo(req, res) {
439
+ try {
440
+ res.json({ success: true, data: await getDeps().sheets.info(String(req.params.id ?? '')) });
441
+ }
442
+ catch (err) {
443
+ sendGoogleError(req, res, err);
444
+ }
445
+ }
446
+ /**
447
+ * GET /api/google/sheets/:id/values?range= — cell values.
448
+ *
449
+ * @param req - Incoming request
450
+ * @param res - Response
451
+ */
452
+ export async function sheetsRead(req, res) {
453
+ try {
454
+ res.json({ success: true, data: await getDeps().sheets.read(String(req.params.id ?? ''), q(req, 'range') || undefined) });
455
+ }
456
+ catch (err) {
457
+ sendGoogleError(req, res, err);
458
+ }
459
+ }
460
+ /**
461
+ * POST /api/google/sheets — body `{ title, sheetTitle?, rows? }`.
462
+ *
463
+ * @param req - Incoming request
464
+ * @param res - Response
465
+ */
466
+ export async function sheetsCreate(req, res) {
467
+ try {
468
+ const body = (req.body ?? {});
469
+ const info = await getDeps().sheets.create({ title: String(body.title ?? ''), sheetTitle: body.sheetTitle, rows: body.rows });
470
+ logger.info('Google Sheet created', { id: info.id, title: info.title });
471
+ res.json({ success: true, data: info });
472
+ }
473
+ catch (err) {
474
+ sendGoogleError(req, res, err);
475
+ }
476
+ }
477
+ /**
478
+ * POST /api/google/sheets/:id/values — body `{ range?, rows, mode?: 'append' | 'update' }`
479
+ * (default append).
480
+ *
481
+ * @param req - Incoming request
482
+ * @param res - Response
483
+ */
484
+ export async function sheetsWrite(req, res) {
485
+ try {
486
+ const body = (req.body ?? {});
487
+ const input = { spreadsheetId: String(req.params.id ?? ''), range: body.range, rows: body.rows };
488
+ const result = body.mode === 'update' ? await getDeps().sheets.update(input) : await getDeps().sheets.append(input);
489
+ res.json({ success: true, data: { mode: body.mode === 'update' ? 'update' : 'append', ...result } });
490
+ }
491
+ catch (err) {
492
+ sendGoogleError(req, res, err);
493
+ }
494
+ }
495
+ // ---------------------------------------------------------------------------
496
+ // Slides
497
+ // ---------------------------------------------------------------------------
498
+ /**
499
+ * GET /api/google/slides/:id — deck as text per slide.
500
+ *
501
+ * @param req - Incoming request
502
+ * @param res - Response
503
+ */
504
+ export async function slidesRead(req, res) {
505
+ try {
506
+ res.json({ success: true, data: await getDeps().slides.read(String(req.params.id ?? '')) });
507
+ }
508
+ catch (err) {
509
+ sendGoogleError(req, res, err);
510
+ }
511
+ }
512
+ /**
513
+ * POST /api/google/slides — body `{ title, slides: [{ title, bullets? }] }`.
514
+ *
515
+ * @param req - Incoming request
516
+ * @param res - Response
517
+ */
518
+ export async function slidesCreate(req, res) {
519
+ try {
520
+ const body = (req.body ?? {});
521
+ const deck = await getDeps().slides.create({ title: String(body.title ?? ''), slides: Array.isArray(body.slides) ? body.slides : [] });
522
+ logger.info('Google Slides deck created', { id: deck.id, title: deck.title, slides: deck.slideCount });
523
+ res.json({ success: true, data: deck });
524
+ }
525
+ catch (err) {
526
+ sendGoogleError(req, res, err);
527
+ }
528
+ }
293
529
  //# sourceMappingURL=google.controller.js.map