@canva/cli 1.9.0 → 1.10.0

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 (39) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/cli.js +1 -1
  3. package/package.json +1 -1
  4. package/templates/base/package.json +0 -1
  5. package/templates/base/tsconfig.json +5 -3
  6. package/templates/base/utils/backend/base_backend/create.ts +3 -3
  7. package/templates/base/utils/backend/bearer_middleware/bearer_middleware.ts +2 -4
  8. package/templates/base/utils/backend/jwt_middleware/jwt_middleware.ts +2 -4
  9. package/templates/base/utils/use_add_element.ts +10 -0
  10. package/templates/base/webpack.config.ts +1 -1
  11. package/templates/common/utils/backend/base_backend/create.ts +3 -3
  12. package/templates/common/utils/backend/jwt_middleware/jwt_middleware.ts +2 -4
  13. package/templates/common/utils/table_wrapper.ts +80 -37
  14. package/templates/common/utils/use_add_element.ts +10 -0
  15. package/templates/common/utils/use_overlay_hook.ts +6 -4
  16. package/templates/dam/backend/routers/dam.ts +35 -17
  17. package/templates/dam/package.json +0 -1
  18. package/templates/dam/tsconfig.json +5 -3
  19. package/templates/dam/utils/backend/base_backend/create.ts +3 -3
  20. package/templates/dam/utils/backend/jwt_middleware/jwt_middleware.ts +2 -4
  21. package/templates/dam/webpack.config.ts +1 -1
  22. package/templates/data_connector/package.json +1 -1
  23. package/templates/data_connector/src/utils/data_table.ts +2 -1
  24. package/templates/data_connector/src/utils/tests/data_table.test.ts +2 -2
  25. package/templates/data_connector/tsconfig.json +5 -3
  26. package/templates/data_connector/webpack.config.ts +1 -1
  27. package/templates/gen_ai/backend/routers/image.ts +4 -6
  28. package/templates/gen_ai/package.json +1 -1
  29. package/templates/gen_ai/src/components/image_grid.tsx +6 -2
  30. package/templates/gen_ai/src/components/prompt_input.tsx +4 -1
  31. package/templates/gen_ai/tsconfig.json +5 -3
  32. package/templates/gen_ai/utils/backend/base_backend/create.ts +3 -3
  33. package/templates/gen_ai/utils/backend/bearer_middleware/bearer_middleware.ts +2 -4
  34. package/templates/gen_ai/webpack.config.ts +1 -1
  35. package/templates/hello_world/package.json +1 -1
  36. package/templates/hello_world/src/tests/app.tests.tsx +1 -1
  37. package/templates/hello_world/tsconfig.json +5 -3
  38. package/templates/hello_world/utils/use_add_element.ts +10 -0
  39. package/templates/hello_world/webpack.config.ts +1 -1
@@ -1,8 +1,6 @@
1
1
  /* eslint-disable no-console */
2
2
  import debug from "debug";
3
3
  import type { NextFunction, Request, Response } from "express";
4
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
5
- import Express from "express-serve-static-core";
6
4
  import jwt from "jsonwebtoken";
7
5
  import { JwksClient, SigningKeyNotFoundError } from "jwks-rsa";
8
6
 
@@ -115,7 +113,7 @@ export function createJwtMiddleware(
115
113
  userId: payload.userId,
116
114
  };
117
115
 
118
- next();
116
+ return next();
119
117
  } catch (e) {
120
118
  if (e instanceof JWTAuthorizationError) {
121
119
  return sendUnauthorizedResponse(res, e.message);
@@ -136,7 +134,7 @@ export function createJwtMiddleware(
136
134
  return sendUnauthorizedResponse(res, "Token expired");
137
135
  }
138
136
 
139
- next(e);
137
+ return next(e);
140
138
  }
141
139
  };
142
140
  }
@@ -196,7 +196,7 @@ function buildDevConfig(options?: DevConfig): {
196
196
  return {};
197
197
  }
198
198
 
199
- const { port, enableHmr, appOrigin, appId, enableHttps, certFile, keyFile } =
199
+ const { port, enableHmr, appOrigin, enableHttps, certFile, keyFile } =
200
200
  options;
201
201
  const host = "localhost";
202
202
 
@@ -42,8 +42,8 @@
42
42
  "@pmmmwh/react-refresh-webpack-plugin": "0.6.1",
43
43
  "@svgr/webpack": "8.1.0",
44
44
  "@testing-library/react": "16.3.0",
45
+ "@types/debug": "4.1.12",
45
46
  "@types/express": "4.17.21",
46
- "@types/express-serve-static-core": "5.0.7",
47
47
  "@types/jest": "29.5.14",
48
48
  "@types/jsonwebtoken": "9.0.10",
49
49
  "@types/node": "20.19.2",
@@ -12,7 +12,8 @@ import type { APIResponseItem } from "src/api";
12
12
  export interface DataTableColumn<T extends APIResponseItem> {
13
13
  label: string;
14
14
  getValue: keyof T | ((result: T) => boolean | string | number | Date);
15
- toCell: (value) => DataTableCell;
15
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
+ toCell: (value: any) => DataTableCell;
16
17
  }
17
18
 
18
19
  export function toDataTable<T extends APIResponseItem>(
@@ -92,8 +92,8 @@ describe("data table utils", () => {
92
92
  const result = toDataTable(testItems, columns, 10);
93
93
 
94
94
  // Check the custom column values
95
- expect(result.rows[0].cells[5].value).toBe("Test Item 1 (42)");
96
- expect(result.rows[1].cells[5].value).toBe("Test Item 2 (0)");
95
+ expect(result.rows[0]?.cells[5]?.value).toBe("Test Item 1 (42)");
96
+ expect(result.rows[1]?.cells[5]?.value).toBe("Test Item 2 (0)");
97
97
  });
98
98
 
99
99
  test("cell formatter functions create correct cell structures", () => {
@@ -28,7 +28,10 @@
28
28
  "sourceMap": true,
29
29
  "inlineSources": true,
30
30
  "module": "ESNext",
31
- "noImplicitAny": false,
31
+ "noImplicitAny": true,
32
+ "noImplicitReturns": true,
33
+ "noFallthroughCasesInSwitch": true,
34
+ "noUncheckedIndexedAccess": true,
32
35
  "removeComments": true,
33
36
  "preserveConstEnums": true,
34
37
  "allowSyntheticDefaultImports": true,
@@ -44,8 +47,7 @@
44
47
  "./utils/**/*",
45
48
  "./scripts/**/*",
46
49
  "./declarations/declarations.d.ts",
47
- "./styles/**/*",
48
- "./node_modules/@types/**/*"
50
+ "./styles/**/*"
49
51
  ],
50
52
  "ts-node": {
51
53
  "compilerOptions": {
@@ -196,7 +196,7 @@ function buildDevConfig(options?: DevConfig): {
196
196
  return {};
197
197
  }
198
198
 
199
- const { port, enableHmr, appOrigin, appId, enableHttps, certFile, keyFile } =
199
+ const { port, enableHmr, appOrigin, enableHttps, certFile, keyFile } =
200
200
  options;
201
201
  const host = "localhost";
202
202
 
@@ -151,7 +151,7 @@ export const createImageRouter = () => {
151
151
  // Add the job to the jobQueue along with the timeoutId
152
152
  jobQueue.push({ jobId, prompt, timeoutId });
153
153
 
154
- res.status(200).send({
154
+ return res.status(200).send({
155
155
  jobId,
156
156
  });
157
157
  });
@@ -208,15 +208,13 @@ export const createImageRouter = () => {
208
208
  }
209
209
 
210
210
  const index = jobQueue.findIndex((job) => job.jobId === jobId);
211
- if (index !== -1) {
211
+ const job = jobQueue[index];
212
+ if (index !== -1 && job) {
212
213
  cancelledJobs.push({ jobId });
213
214
  // If the job is found, remove it from the jobQueue
214
- const { timeoutId } = jobQueue[index];
215
215
  jobQueue.splice(index, 1);
216
216
  // Also clear the timeout associated with this job if it exists
217
- if (timeoutId) {
218
- clearTimeout(timeoutId);
219
- }
217
+ clearTimeout(job.timeoutId);
220
218
  return res.status(200).send("Job successfully cancelled.");
221
219
  }
222
220
 
@@ -44,9 +44,9 @@
44
44
  "@pmmmwh/react-refresh-webpack-plugin": "0.6.1",
45
45
  "@svgr/webpack": "8.1.0",
46
46
  "@testing-library/react": "16.3.0",
47
+ "@types/cors": "2.8.19",
47
48
  "@types/debug": "4.1.12",
48
49
  "@types/express": "4.17.21",
49
- "@types/express-serve-static-core": "5.0.7",
50
50
  "@types/jest": "29.5.14",
51
51
  "@types/jsonwebtoken": "9.0.10",
52
52
  "@types/node": "20.19.2",
@@ -34,7 +34,9 @@ export const ImageGrid = () => {
34
34
  ) => {
35
35
  const parentNode = event.currentTarget.parentElement;
36
36
  try {
37
- parentNode?.classList.add(styles.hidden);
37
+ if (styles.hidden) {
38
+ parentNode?.classList.add(styles.hidden);
39
+ }
38
40
 
39
41
  await ui.startDragToPoint(event, {
40
42
  type: "image",
@@ -50,7 +52,9 @@ export const ImageGrid = () => {
50
52
  },
51
53
  });
52
54
  } finally {
53
- parentNode?.classList.remove(styles.hidden);
55
+ if (styles.hidden) {
56
+ parentNode?.classList.remove(styles.hidden);
57
+ }
54
58
  }
55
59
  };
56
60
 
@@ -59,8 +59,11 @@ const generateExamplePrompt = (currentPrompt: string): string => {
59
59
  const MAX_ATTEMPTS = 3;
60
60
 
61
61
  while (currentPrompt === newPrompt && attempts < MAX_ATTEMPTS) {
62
- newPrompt =
62
+ const randomPrompt =
63
63
  examplePrompts[Math.floor(Math.random() * examplePrompts.length)];
64
+ if (randomPrompt) {
65
+ newPrompt = randomPrompt;
66
+ }
64
67
  attempts++;
65
68
  }
66
69
 
@@ -28,7 +28,10 @@
28
28
  "sourceMap": true,
29
29
  "inlineSources": true,
30
30
  "module": "ESNext",
31
- "noImplicitAny": false,
31
+ "noImplicitAny": true,
32
+ "noImplicitReturns": true,
33
+ "noFallthroughCasesInSwitch": true,
34
+ "noUncheckedIndexedAccess": true,
32
35
  "removeComments": true,
33
36
  "preserveConstEnums": true,
34
37
  "allowSyntheticDefaultImports": true,
@@ -44,8 +47,7 @@
44
47
  "./utils/**/*",
45
48
  "./scripts/**/*",
46
49
  "./declarations/declarations.d.ts",
47
- "./styles/**/*",
48
- "./node_modules/@types/**/*"
50
+ "./styles/**/*"
49
51
  ],
50
52
  "ts-node": {
51
53
  "compilerOptions": {
@@ -41,12 +41,12 @@ export function createBaseServer(router: express.Router): BaseServer {
41
41
  app.disable("x-powered-by");
42
42
 
43
43
  // Health check endpoint
44
- app.get("/healthz", (req, res: Response) => {
44
+ app.get("/healthz", (req, res) => {
45
45
  res.sendStatus(200);
46
46
  });
47
47
 
48
48
  // logging middleware
49
- app.use((req: Request, res: Response, next: NextFunction) => {
49
+ app.use((req, _res, next) => {
50
50
  serverDebug(`${new Date().toISOString()}: ${req.method} ${req.url}`);
51
51
  next();
52
52
  });
@@ -62,7 +62,7 @@ export function createBaseServer(router: express.Router): BaseServer {
62
62
  });
63
63
 
64
64
  // default error handler
65
- app.use((err, req, res, next) => {
65
+ app.use((err: Error, _req: Request, res: Response, _next: NextFunction) => {
66
66
  console.error(err.stack);
67
67
  res.status(500).send({
68
68
  error: "something went wrong",
@@ -1,8 +1,6 @@
1
1
  /* eslint-disable no-console */
2
2
  import debug from "debug";
3
3
  import type { NextFunction, Request, Response } from "express";
4
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
5
- import Express from "express-serve-static-core";
6
4
 
7
5
  /**
8
6
  * Prefix your start command with `DEBUG=express:middleware:bearer` to enable debug logging
@@ -47,13 +45,13 @@ export function createBearerMiddleware(
47
45
 
48
46
  req["user_id"] = user;
49
47
 
50
- next();
48
+ return next();
51
49
  } catch (e) {
52
50
  if (e instanceof AuthorizationError) {
53
51
  return sendUnauthorizedResponse(res, e.message);
54
52
  }
55
53
 
56
- next(e);
54
+ return next(e);
57
55
  }
58
56
  };
59
57
  }
@@ -196,7 +196,7 @@ function buildDevConfig(options?: DevConfig): {
196
196
  return {};
197
197
  }
198
198
 
199
- const { port, enableHmr, appOrigin, appId, enableHttps, certFile, keyFile } =
199
+ const { port, enableHmr, appOrigin, enableHttps, certFile, keyFile } =
200
200
  options;
201
201
  const host = "localhost";
202
202
 
@@ -39,8 +39,8 @@
39
39
  "@pmmmwh/react-refresh-webpack-plugin": "0.6.1",
40
40
  "@svgr/webpack": "8.1.0",
41
41
  "@testing-library/react": "16.3.0",
42
+ "@types/debug": "4.1.12",
42
43
  "@types/express": "4.17.21",
43
- "@types/express-serve-static-core": "5.0.7",
44
44
  "@types/jest": "29.5.14",
45
45
  "@types/jsonwebtoken": "9.0.10",
46
46
  "@types/node": "20.19.2",
@@ -73,7 +73,7 @@ describe("Hello World Tests", () => {
73
73
  expect(mockRequestOpenExternalUrl).toHaveBeenCalled();
74
74
 
75
75
  // assert that the requestOpenExternalUrl function was called with the expected arguments
76
- expect(mockRequestOpenExternalUrl.mock.calls[0][0]).toEqual({
76
+ expect(mockRequestOpenExternalUrl.mock.calls[0]?.[0]).toEqual({
77
77
  url: DOCS_URL,
78
78
  });
79
79
  });
@@ -28,7 +28,10 @@
28
28
  "sourceMap": true,
29
29
  "inlineSources": true,
30
30
  "module": "ESNext",
31
- "noImplicitAny": false,
31
+ "noImplicitAny": true,
32
+ "noImplicitReturns": true,
33
+ "noFallthroughCasesInSwitch": true,
34
+ "noUncheckedIndexedAccess": true,
32
35
  "removeComments": true,
33
36
  "preserveConstEnums": true,
34
37
  "allowSyntheticDefaultImports": true,
@@ -44,8 +47,7 @@
44
47
  "./utils/**/*",
45
48
  "./scripts/**/*",
46
49
  "./declarations/declarations.d.ts",
47
- "./styles/**/*",
48
- "./node_modules/@types/**/*"
50
+ "./styles/**/*"
49
51
  ],
50
52
  "ts-node": {
51
53
  "compilerOptions": {
@@ -30,6 +30,11 @@ export const useAddElement = () => {
30
30
  } else if (features.isSupported(addElementAtCursor)) {
31
31
  return addElementAtCursor(element);
32
32
  }
33
+ // eslint-disable-next-line no-console
34
+ console.warn(
35
+ "Neither addElementAtPoint nor addElementAtCursor are supported",
36
+ );
37
+ return Promise.resolve();
33
38
  };
34
39
  });
35
40
 
@@ -40,6 +45,11 @@ export const useAddElement = () => {
40
45
  } else if (isSupported(addElementAtCursor)) {
41
46
  return addElementAtCursor(element);
42
47
  }
48
+ // eslint-disable-next-line no-console
49
+ console.warn(
50
+ "Neither addElementAtPoint nor addElementAtCursor are supported",
51
+ );
52
+ return Promise.resolve();
43
53
  };
44
54
  setAddElement(() => addElement);
45
55
  }, [isSupported]);
@@ -196,7 +196,7 @@ function buildDevConfig(options?: DevConfig): {
196
196
  return {};
197
197
  }
198
198
 
199
- const { port, enableHmr, appOrigin, appId, enableHttps, certFile, keyFile } =
199
+ const { port, enableHmr, appOrigin, enableHttps, certFile, keyFile } =
200
200
  options;
201
201
  const host = "localhost";
202
202