@canva/cli 0.0.1-beta.34 → 0.0.1-beta.36

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 (94) hide show
  1. package/README.md +4 -9
  2. package/cli.js +682 -600
  3. package/lib/cjs/index.cjs +4 -4
  4. package/lib/esm/index.mjs +4 -4
  5. package/package.json +3 -3
  6. package/templates/base/backend/routers/auth.ts +4 -4
  7. package/templates/base/backend/routers/oauth.ts +3 -3
  8. package/templates/base/package.json +19 -19
  9. package/templates/base/scripts/ssl/ssl.ts +1 -1
  10. package/templates/base/scripts/start/app_runner.ts +6 -6
  11. package/templates/base/scripts/start/start.ts +1 -1
  12. package/templates/base/utils/backend/base_backend/create.ts +3 -3
  13. package/templates/base/utils/backend/bearer_middleware/bearer_middleware.ts +2 -2
  14. package/templates/base/utils/backend/jwt_middleware/jwt_middleware.ts +4 -4
  15. package/templates/base/utils/backend/jwt_middleware/tests/jwt_middleware.tests.ts +1 -1
  16. package/templates/base/utils/use_add_element.ts +1 -1
  17. package/templates/base/utils/use_feature_support.ts +1 -1
  18. package/templates/base/webpack.config.ts +2 -20
  19. package/templates/common/jest.config.mjs +1 -1
  20. package/templates/common/utils/backend/base_backend/create.ts +3 -3
  21. package/templates/common/utils/backend/jwt_middleware/jwt_middleware.ts +4 -4
  22. package/templates/common/utils/backend/jwt_middleware/tests/jwt_middleware.tests.ts +1 -1
  23. package/templates/common/utils/tests/table_wrapper.tests.ts +1 -1
  24. package/templates/common/utils/use_add_element.ts +1 -1
  25. package/templates/common/utils/use_feature_support.ts +1 -1
  26. package/templates/dam/backend/routers/dam.ts +2 -2
  27. package/templates/dam/backend/server.ts +1 -1
  28. package/templates/dam/canva-app.json +16 -0
  29. package/templates/dam/package.json +26 -26
  30. package/templates/dam/scripts/ssl/ssl.ts +1 -1
  31. package/templates/dam/scripts/start/app_runner.ts +6 -6
  32. package/templates/dam/scripts/start/start.ts +1 -1
  33. package/templates/dam/src/app.tsx +1 -1
  34. package/templates/dam/src/index.tsx +1 -1
  35. package/templates/dam/utils/backend/base_backend/create.ts +3 -3
  36. package/templates/dam/utils/backend/jwt_middleware/jwt_middleware.ts +4 -4
  37. package/templates/dam/utils/backend/jwt_middleware/tests/jwt_middleware.tests.ts +1 -1
  38. package/templates/dam/webpack.config.ts +2 -20
  39. package/templates/data_connector/README.md +2 -2
  40. package/templates/data_connector/canva-app.json +21 -0
  41. package/templates/data_connector/package.json +26 -26
  42. package/templates/data_connector/scripts/ssl/ssl.ts +1 -1
  43. package/templates/data_connector/scripts/start/app_runner.ts +6 -6
  44. package/templates/data_connector/scripts/start/start.ts +1 -1
  45. package/templates/data_connector/src/api/data_source.ts +1 -1
  46. package/templates/data_connector/src/api/data_sources/designs.tsx +9 -9
  47. package/templates/data_connector/src/api/data_sources/templates.tsx +9 -9
  48. package/templates/data_connector/src/api/fetch_data_table.ts +1 -1
  49. package/templates/data_connector/src/api/tests/data_source.test.tsx +2 -2
  50. package/templates/data_connector/src/app.tsx +5 -5
  51. package/templates/data_connector/src/components/footer.tsx +1 -1
  52. package/templates/data_connector/src/components/header.tsx +1 -1
  53. package/templates/data_connector/src/context/app_context.tsx +1 -1
  54. package/templates/data_connector/src/entrypoint.tsx +7 -7
  55. package/templates/data_connector/src/home.tsx +2 -2
  56. package/templates/data_connector/src/index.tsx +5 -6
  57. package/templates/data_connector/src/pages/error.tsx +2 -2
  58. package/templates/data_connector/src/pages/login.tsx +7 -7
  59. package/templates/data_connector/src/routes/routes.tsx +1 -1
  60. package/templates/data_connector/src/utils/data_table.ts +1 -1
  61. package/templates/data_connector/src/utils/fetch_result.ts +1 -1
  62. package/templates/data_connector/src/utils/tests/data_table.test.ts +5 -5
  63. package/templates/data_connector/webpack.config.ts +2 -20
  64. package/templates/gen_ai/backend/server.ts +1 -1
  65. package/templates/gen_ai/canva-app.json +20 -0
  66. package/templates/gen_ai/package.json +30 -30
  67. package/templates/gen_ai/scripts/ssl/ssl.ts +1 -1
  68. package/templates/gen_ai/scripts/start/app_runner.ts +6 -6
  69. package/templates/gen_ai/scripts/start/start.ts +1 -1
  70. package/templates/gen_ai/src/app.tsx +3 -3
  71. package/templates/gen_ai/src/components/footer.tsx +4 -4
  72. package/templates/gen_ai/src/components/image_grid.tsx +1 -1
  73. package/templates/gen_ai/src/components/loading_results.tsx +8 -8
  74. package/templates/gen_ai/src/components/prompt_input.tsx +3 -3
  75. package/templates/gen_ai/src/components/remaining_credits.tsx +1 -1
  76. package/templates/gen_ai/src/components/report_box.tsx +1 -1
  77. package/templates/gen_ai/src/components/tests/remaining_credit.tests.tsx +2 -2
  78. package/templates/gen_ai/src/home.tsx +2 -2
  79. package/templates/gen_ai/src/pages/error.tsx +2 -2
  80. package/templates/gen_ai/src/pages/results.tsx +1 -1
  81. package/templates/gen_ai/utils/backend/base_backend/create.ts +3 -3
  82. package/templates/gen_ai/utils/backend/bearer_middleware/bearer_middleware.ts +2 -2
  83. package/templates/gen_ai/webpack.config.ts +2 -20
  84. package/templates/hello_world/canva-app.json +16 -0
  85. package/templates/hello_world/package.json +24 -24
  86. package/templates/hello_world/scripts/ssl/ssl.ts +1 -1
  87. package/templates/hello_world/scripts/start/app_runner.ts +6 -6
  88. package/templates/hello_world/scripts/start/start.ts +1 -1
  89. package/templates/hello_world/src/app.tsx +1 -1
  90. package/templates/hello_world/src/index.tsx +1 -1
  91. package/templates/hello_world/src/tests/app.tests.tsx +3 -3
  92. package/templates/hello_world/utils/use_add_element.ts +1 -1
  93. package/templates/hello_world/utils/use_feature_support.ts +1 -1
  94. package/templates/hello_world/webpack.config.ts +2 -20
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable no-console */
2
2
  import * as debug from "debug";
3
- import type { Request, Response, NextFunction } from "express";
3
+ import type { NextFunction, Request, Response } from "express";
4
4
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
5
5
  import Express from "express-serve-static-core";
6
6
 
@@ -45,7 +45,7 @@ export function createBearerMiddleware(
45
45
  throw new AuthorizationError("Token is invalid");
46
46
  }
47
47
 
48
- req.user_id = user;
48
+ req["user_id"] = user;
49
49
 
50
50
  next();
51
51
  } catch (e) {
@@ -1,11 +1,11 @@
1
1
  /* eslint-disable no-console */
2
2
  import * as chalk from "chalk";
3
3
  import * as debug from "debug";
4
- import type { Request, Response, NextFunction } from "express";
5
- import * as jwt from "jsonwebtoken";
6
- import { JwksClient, SigningKeyNotFoundError } from "jwks-rsa";
4
+ import type { NextFunction, Request, Response } from "express";
7
5
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
8
6
  import Express from "express-serve-static-core";
7
+ import * as jwt from "jsonwebtoken";
8
+ import { JwksClient, SigningKeyNotFoundError } from "jwks-rsa";
9
9
 
10
10
  /**
11
11
  * Prefix your start command with `DEBUG=express:middleware:jwt` to enable debug logging
@@ -110,7 +110,7 @@ export function createJwtMiddleware(
110
110
  return sendUnauthorizedResponse(res);
111
111
  }
112
112
 
113
- req.canva = {
113
+ req["canva"] = {
114
114
  appId: payload.aud,
115
115
  brandId: payload.brandId,
116
116
  userId: payload.userId,
@@ -446,7 +446,7 @@ describe("createJwtMiddleware", () => {
446
446
  expect(res.status).not.toHaveBeenCalled();
447
447
  expect(res.json).not.toHaveBeenCalled();
448
448
 
449
- expect(req.canva).toEqual({
449
+ expect(req["canva"]).toEqual({
450
450
  userId: FAKE_USER_ID,
451
451
  brandId: FAKE_BRAND_ID,
452
452
  appId: FAKE_APP_ID,
@@ -7,9 +7,9 @@ import type {
7
7
  VideoElement,
8
8
  } from "@canva/design";
9
9
  import { addElementAtCursor, addElementAtPoint } from "@canva/design";
10
- import { useFeatureSupport } from "./use_feature_support";
11
10
  import { features } from "@canva/platform";
12
11
  import { useEffect, useState } from "react";
12
+ import { useFeatureSupport } from "./use_feature_support";
13
13
 
14
14
  type AddElementParams =
15
15
  | ImageElement
@@ -1,6 +1,6 @@
1
1
  import { features } from "@canva/platform";
2
2
  import type { Feature } from "@canva/platform";
3
- import { useState, useEffect } from "react";
3
+ import { useEffect, useState } from "react";
4
4
 
5
5
  /**
6
6
  * This hook allows re-rendering of a React component whenever
@@ -24,7 +24,7 @@ export function buildConfig({
24
24
  appEntry = path.join(process.cwd(), "src", "index.tsx"),
25
25
  backendHost = process.env.CANVA_BACKEND_HOST,
26
26
  // For IN_HARNESS, refer to the following docs for more information: https://www.canva.dev/docs/apps/test-harness/
27
- inHarness = process.env.IN_HARNESS === "true",
27
+ inHarness = process.env.IN_HARNESS?.toLowerCase() === "true",
28
28
  }: {
29
29
  devConfig?: DevConfig;
30
30
  appEntry?: string;
@@ -182,7 +182,7 @@ export function buildConfig({
182
182
  new DefinePlugin({
183
183
  BACKEND_HOST: JSON.stringify(backendHost),
184
184
  }),
185
- // Apps can only submit a single JS file via the developer portal
185
+ // Apps can only submit a single JS file via the Developer Portal
186
186
  new optimize.LimitChunkCountPlugin({ maxChunks: 1 }),
187
187
  ].filter(Boolean),
188
188
  ...buildDevConfig(devConfig),
@@ -236,24 +236,6 @@ function buildDevConfig(options?: DevConfig): {
236
236
  "Access-Control-Allow-Private-Network": "true",
237
237
  },
238
238
  };
239
- } else if (enableHmr && appId) {
240
- // Deprecated - App ID should not be used to configure HMR in the future and can be safely removed
241
- // after a few months.
242
-
243
- console.warn(
244
- "Enabling Hot Module Replacement (HMR) with an App ID is deprecated, please see the README.md on how to update.",
245
- );
246
-
247
- const appDomain = `app-${appId.toLowerCase().trim()}.canva-apps.com`;
248
- devServer = {
249
- ...devServer,
250
- allowedHosts: [host, appDomain],
251
- headers: {
252
- "Access-Control-Allow-Origin": `https://${appDomain}`,
253
- "Access-Control-Allow-Credentials": "true",
254
- "Access-Control-Allow-Private-Network": "true",
255
- },
256
- };
257
239
  } else {
258
240
  if (enableHmr && !appOrigin) {
259
241
  console.warn(
@@ -1,5 +1,5 @@
1
1
  import { pathsToModuleNameMapper } from "ts-jest";
2
- import tsconfig from "./tsconfig.json" assert { type: "json" };
2
+ import tsconfig from "./tsconfig.json" with { type: "json" };
3
3
 
4
4
  const { compilerOptions } = tsconfig;
5
5
 
@@ -1,10 +1,10 @@
1
1
  /* eslint-disable no-console */
2
+ import debug from "debug";
2
3
  import * as express from "express";
4
+ import type { NextFunction, Request, Response } from "express";
5
+ import * as fs from "fs";
3
6
  import * as http from "http";
4
7
  import * as https from "https";
5
- import * as fs from "fs";
6
- import type { Request, Response, NextFunction } from "express";
7
- import debug from "debug";
8
8
 
9
9
  const serverDebug = debug("server");
10
10
 
@@ -1,11 +1,11 @@
1
1
  /* eslint-disable no-console */
2
2
  import * as chalk from "chalk";
3
3
  import * as debug from "debug";
4
- import type { Request, Response, NextFunction } from "express";
5
- import * as jwt from "jsonwebtoken";
6
- import { JwksClient, SigningKeyNotFoundError } from "jwks-rsa";
4
+ import type { NextFunction, Request, Response } from "express";
7
5
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
8
6
  import Express from "express-serve-static-core";
7
+ import * as jwt from "jsonwebtoken";
8
+ import { JwksClient, SigningKeyNotFoundError } from "jwks-rsa";
9
9
 
10
10
  /**
11
11
  * Prefix your start command with `DEBUG=express:middleware:jwt` to enable debug logging
@@ -110,7 +110,7 @@ export function createJwtMiddleware(
110
110
  return sendUnauthorizedResponse(res);
111
111
  }
112
112
 
113
- req.canva = {
113
+ req["canva"] = {
114
114
  appId: payload.aud,
115
115
  brandId: payload.brandId,
116
116
  userId: payload.userId,
@@ -446,7 +446,7 @@ describe("createJwtMiddleware", () => {
446
446
  expect(res.status).not.toHaveBeenCalled();
447
447
  expect(res.json).not.toHaveBeenCalled();
448
448
 
449
- expect(req.canva).toEqual({
449
+ expect(req["canva"]).toEqual({
450
450
  userId: FAKE_USER_ID,
451
451
  brandId: FAKE_BRAND_ID,
452
452
  appId: FAKE_APP_ID,
@@ -1,5 +1,5 @@
1
- import { TableWrapper } from "../table_wrapper";
2
1
  import type { Cell, TableElement } from "@canva/design";
2
+ import { TableWrapper } from "../table_wrapper";
3
3
 
4
4
  describe("TableWrapper", () => {
5
5
  describe("create", () => {
@@ -7,9 +7,9 @@ import type {
7
7
  VideoElement,
8
8
  } from "@canva/design";
9
9
  import { addElementAtCursor, addElementAtPoint } from "@canva/design";
10
- import { useFeatureSupport } from "./use_feature_support";
11
10
  import { features } from "@canva/platform";
12
11
  import { useEffect, useState } from "react";
12
+ import { useFeatureSupport } from "./use_feature_support";
13
13
 
14
14
  type AddElementParams =
15
15
  | ImageElement
@@ -1,6 +1,6 @@
1
1
  import { features } from "@canva/platform";
2
2
  import type { Feature } from "@canva/platform";
3
- import { useState, useEffect } from "react";
3
+ import { useEffect, useState } from "react";
4
4
 
5
5
  /**
6
6
  * This hook allows re-rendering of a React component whenever
@@ -1,6 +1,6 @@
1
- import * as express from "express";
2
- import * as crypto from "crypto";
3
1
  import type { Container, Resource } from "@canva/app-components";
2
+ import * as crypto from "crypto";
3
+ import * as express from "express";
4
4
 
5
5
  /**
6
6
  * Generates a unique hash for a url.
@@ -1,5 +1,5 @@
1
- import * as express from "express";
2
1
  import * as cors from "cors";
2
+ import * as express from "express";
3
3
  import { createBaseServer } from "../utils/backend/base_backend/create";
4
4
  import { createDamRouter } from "./routers/dam";
5
5
 
@@ -0,0 +1,16 @@
1
+ {
2
+ "manifest_schema_version": 1,
3
+ "runtime": {
4
+ "permissions": [
5
+ {
6
+ "name": "canva:design:content:read",
7
+ "type": "mandatory"
8
+ },
9
+ {
10
+ "name": "canva:design:content:write",
11
+ "type": "mandatory"
12
+ }
13
+ ],
14
+ "supported_devices": ["desktop", "mobile"]
15
+ }
16
+ }
@@ -19,13 +19,13 @@
19
19
  },
20
20
  "dependencies": {
21
21
  "@canva/app-components": "^1.3.0",
22
- "@canva/app-i18n-kit": "^1.0.2",
22
+ "@canva/app-i18n-kit": "^1.0.3",
23
23
  "@canva/app-ui-kit": "^4.10.0",
24
- "@canva/asset": "^2.2.0",
25
- "@canva/design": "^2.6.0",
24
+ "@canva/asset": "^2.2.1",
25
+ "@canva/design": "^2.7.0",
26
26
  "@canva/error": "^2.1.0",
27
27
  "@canva/platform": "^2.2.0",
28
- "@canva/user": "^2.1.0",
28
+ "@canva/user": "^2.1.1",
29
29
  "cookie-parser": "1.4.7",
30
30
  "cors": "2.8.5",
31
31
  "react": "18.3.1",
@@ -35,60 +35,60 @@
35
35
  "devDependencies": {
36
36
  "@canva/app-eslint-plugin": "^1.0.0-beta.3",
37
37
  "@canva/cli": ">= 0.0.1-beta.13 < 0.0.2",
38
- "@formatjs/cli": "6.3.15",
39
- "@formatjs/ts-transformer": "3.13.27",
40
- "@ngrok/ngrok": "1.4.1",
41
- "@pmmmwh/react-refresh-webpack-plugin": "0.5.15",
38
+ "@formatjs/cli": "6.7.2",
39
+ "@formatjs/ts-transformer": "3.14.0",
40
+ "@ngrok/ngrok": "1.5.1",
41
+ "@pmmmwh/react-refresh-webpack-plugin": "0.6.1",
42
42
  "@svgr/webpack": "8.1.0",
43
- "@testing-library/react": "16.1.0",
44
- "@types/cors": "2.8.17",
43
+ "@testing-library/react": "16.3.0",
44
+ "@types/cors": "2.8.19",
45
45
  "@types/debug": "4.1.12",
46
46
  "@types/express": "4.17.21",
47
- "@types/express-serve-static-core": "4.19.6",
47
+ "@types/express-serve-static-core": "5.0.6",
48
48
  "@types/jest": "29.5.14",
49
- "@types/jsonwebtoken": "9.0.7",
50
- "@types/node": "20.10.0",
49
+ "@types/jsonwebtoken": "9.0.10",
50
+ "@types/node": "20.19.2",
51
51
  "@types/node-fetch": "2.6.12",
52
52
  "@types/node-forge": "1.3.11",
53
53
  "@types/nodemon": "1.19.6",
54
54
  "@types/prompts": "2.4.9",
55
55
  "@types/react": "18.3.12",
56
56
  "@types/react-dom": "18.3.1",
57
- "@types/webpack-env": "1.18.5",
57
+ "@types/webpack-env": "1.18.8",
58
58
  "chalk": "4.1.2",
59
59
  "cli-table3": "0.6.5",
60
60
  "css-loader": "7.1.2",
61
61
  "css-modules-typescript-loader": "4.0.1",
62
- "cssnano": "7.0.6",
63
- "debug": "4.4.0",
64
- "dotenv": "16.4.7",
65
- "exponential-backoff": "3.1.1",
62
+ "cssnano": "7.0.7",
63
+ "debug": "4.4.1",
64
+ "dotenv": "16.6.0",
65
+ "exponential-backoff": "3.1.2",
66
66
  "express": "4.21.2",
67
67
  "express-basic-auth": "1.2.1",
68
68
  "jest": "29.7.0",
69
69
  "jest-css-modules-transform": "4.4.2",
70
70
  "jest-environment-jsdom": "29.7.0",
71
71
  "jsonwebtoken": "9.0.2",
72
- "jwks-rsa": "3.1.0",
72
+ "jwks-rsa": "3.2.0",
73
73
  "mini-css-extract-plugin": "2.9.2",
74
74
  "node-fetch": "3.3.2",
75
75
  "node-forge": "1.3.1",
76
76
  "nodemon": "3.0.1",
77
77
  "open": "8.4.2",
78
78
  "postcss-loader": "8.1.1",
79
- "prettier": "3.4.2",
79
+ "prettier": "3.6.2",
80
80
  "prompts": "2.4.2",
81
- "react-refresh": "0.16.0",
81
+ "react-refresh": "0.17.0",
82
82
  "style-loader": "4.0.0",
83
- "terser-webpack-plugin": "5.3.11",
83
+ "terser-webpack-plugin": "5.3.14",
84
84
  "tree-kill": "1.2.2",
85
- "ts-jest": "29.2.5",
85
+ "ts-jest": "29.4.0",
86
86
  "ts-loader": "9.5.2",
87
87
  "ts-node": "10.9.2",
88
- "typescript": "5.5.4",
88
+ "typescript": "5.8.2",
89
89
  "url-loader": "4.1.1",
90
- "webpack": "5.97.1",
91
- "webpack-cli": "5.1.4",
90
+ "webpack": "5.99.9",
91
+ "webpack-cli": "6.0.1",
92
92
  "webpack-dev-server": "5.2.2",
93
93
  "yargs": "17.7.2"
94
94
  }
@@ -1,7 +1,7 @@
1
1
  import * as crypto from "crypto";
2
+ import * as fs from "fs/promises";
2
3
  import { pki } from "node-forge";
3
4
  import * as path from "path";
4
- import * as fs from "fs/promises";
5
5
 
6
6
  const SSL_CERT_DIR = path.resolve(process.cwd(), "..", "..", ".ssl");
7
7
  const CERT_FILE = path.resolve(SSL_CERT_DIR, "certificate.pem");
@@ -1,16 +1,16 @@
1
1
  /* eslint-disable no-console */
2
- import type { Context } from "./context";
3
- import * as chalk from "chalk";
4
- import { buildConfig } from "../../webpack.config";
2
+ import { generatePreviewUrl } from "@canva/cli";
5
3
  import * as ngrok from "@ngrok/ngrok";
6
- import * as nodemon from "nodemon";
4
+ import * as chalk from "chalk";
7
5
  import * as Table from "cli-table3";
6
+ import * as nodemon from "nodemon";
7
+ import * as open from "open";
8
8
  import * as webpack from "webpack";
9
9
  import * as WebpackDevServer from "webpack-dev-server";
10
- import * as open from "open";
11
- import { generatePreviewUrl } from "@canva/cli";
10
+ import { buildConfig } from "../../webpack.config";
12
11
  import type { Certificate } from "../ssl/ssl";
13
12
  import { createOrRetrieveCertificate } from "../ssl/ssl";
13
+ import type { Context } from "./context";
14
14
 
15
15
  export const infoChalk = chalk.blue.bold;
16
16
  export const warnChalk = chalk.bgYellow.bold;
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import * as yargs from "yargs";
3
- import { AppRunner } from "./app_runner";
4
3
  import { hideBin } from "yargs/helpers";
4
+ import { AppRunner } from "./app_runner";
5
5
  import { Context } from "./context";
6
6
 
7
7
  const appRunner = new AppRunner();
@@ -1,8 +1,8 @@
1
1
  import { SearchableListView } from "@canva/app-components";
2
2
  import { Box } from "@canva/app-ui-kit";
3
3
  import "@canva/app-ui-kit/styles.css";
4
- import { useConfig } from "./config";
5
4
  import { findResources } from "./adapter";
5
+ import { useConfig } from "./config";
6
6
  import * as styles from "./index.css";
7
7
 
8
8
  export function App() {
@@ -1,8 +1,8 @@
1
+ import { AppI18nProvider } from "@canva/app-i18n-kit";
1
2
  import { AppUiProvider } from "@canva/app-ui-kit";
2
3
  import { createRoot } from "react-dom/client";
3
4
  import { App } from "./app";
4
5
  import "@canva/app-ui-kit/styles.css";
5
- import { AppI18nProvider } from "@canva/app-i18n-kit";
6
6
 
7
7
  const root = createRoot(document.getElementById("root") as Element);
8
8
  function render() {
@@ -1,10 +1,10 @@
1
1
  /* eslint-disable no-console */
2
+ import debug from "debug";
2
3
  import * as express from "express";
4
+ import type { NextFunction, Request, Response } from "express";
5
+ import * as fs from "fs";
3
6
  import * as http from "http";
4
7
  import * as https from "https";
5
- import * as fs from "fs";
6
- import type { Request, Response, NextFunction } from "express";
7
- import debug from "debug";
8
8
 
9
9
  const serverDebug = debug("server");
10
10
 
@@ -1,11 +1,11 @@
1
1
  /* eslint-disable no-console */
2
2
  import * as chalk from "chalk";
3
3
  import * as debug from "debug";
4
- import type { Request, Response, NextFunction } from "express";
5
- import * as jwt from "jsonwebtoken";
6
- import { JwksClient, SigningKeyNotFoundError } from "jwks-rsa";
4
+ import type { NextFunction, Request, Response } from "express";
7
5
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
8
6
  import Express from "express-serve-static-core";
7
+ import * as jwt from "jsonwebtoken";
8
+ import { JwksClient, SigningKeyNotFoundError } from "jwks-rsa";
9
9
 
10
10
  /**
11
11
  * Prefix your start command with `DEBUG=express:middleware:jwt` to enable debug logging
@@ -110,7 +110,7 @@ export function createJwtMiddleware(
110
110
  return sendUnauthorizedResponse(res);
111
111
  }
112
112
 
113
- req.canva = {
113
+ req["canva"] = {
114
114
  appId: payload.aud,
115
115
  brandId: payload.brandId,
116
116
  userId: payload.userId,
@@ -446,7 +446,7 @@ describe("createJwtMiddleware", () => {
446
446
  expect(res.status).not.toHaveBeenCalled();
447
447
  expect(res.json).not.toHaveBeenCalled();
448
448
 
449
- expect(req.canva).toEqual({
449
+ expect(req["canva"]).toEqual({
450
450
  userId: FAKE_USER_ID,
451
451
  brandId: FAKE_BRAND_ID,
452
452
  appId: FAKE_APP_ID,
@@ -24,7 +24,7 @@ export function buildConfig({
24
24
  appEntry = path.join(process.cwd(), "src", "index.tsx"),
25
25
  backendHost = process.env.CANVA_BACKEND_HOST,
26
26
  // For IN_HARNESS, refer to the following docs for more information: https://www.canva.dev/docs/apps/test-harness/
27
- inHarness = process.env.IN_HARNESS === "true",
27
+ inHarness = process.env.IN_HARNESS?.toLowerCase() === "true",
28
28
  }: {
29
29
  devConfig?: DevConfig;
30
30
  appEntry?: string;
@@ -182,7 +182,7 @@ export function buildConfig({
182
182
  new DefinePlugin({
183
183
  BACKEND_HOST: JSON.stringify(backendHost),
184
184
  }),
185
- // Apps can only submit a single JS file via the developer portal
185
+ // Apps can only submit a single JS file via the Developer Portal
186
186
  new optimize.LimitChunkCountPlugin({ maxChunks: 1 }),
187
187
  ].filter(Boolean),
188
188
  ...buildDevConfig(devConfig),
@@ -236,24 +236,6 @@ function buildDevConfig(options?: DevConfig): {
236
236
  "Access-Control-Allow-Private-Network": "true",
237
237
  },
238
238
  };
239
- } else if (enableHmr && appId) {
240
- // Deprecated - App ID should not be used to configure HMR in the future and can be safely removed
241
- // after a few months.
242
-
243
- console.warn(
244
- "Enabling Hot Module Replacement (HMR) with an App ID is deprecated, please see the README.md on how to update.",
245
- );
246
-
247
- const appDomain = `app-${appId.toLowerCase().trim()}.canva-apps.com`;
248
- devServer = {
249
- ...devServer,
250
- allowedHosts: [host, appDomain],
251
- headers: {
252
- "Access-Control-Allow-Origin": `https://${appDomain}`,
253
- "Access-Control-Allow-Credentials": "true",
254
- "Access-Control-Allow-Private-Network": "true",
255
- },
256
- };
257
239
  } else {
258
240
  if (enableHmr && !appOrigin) {
259
241
  console.warn(
@@ -60,9 +60,9 @@ To run it and authenticate with the Canva Connect API via OAuth you must first c
60
60
  - On the **Authentication** page, add an OAuth 2.0 provider with the following settings:
61
61
  > Provider: `CanvaConnect`
62
62
  >
63
- > Client ID: `(generated in step 1)
63
+ > Client ID: `(generated in step 1)`
64
64
  >
65
- > Client secret: `(generated in step 1)
65
+ > Client secret: `(generated in step 1)`
66
66
  >
67
67
  > Credential transfer mode: `Headers (default)`
68
68
  >
@@ -0,0 +1,21 @@
1
+ {
2
+ "manifest_schema_version": 1,
3
+ "runtime": {
4
+ "permissions": [
5
+ {
6
+ "name": "canva:design:content:read",
7
+ "type": "mandatory"
8
+ },
9
+ {
10
+ "name": "canva:design:content:write",
11
+ "type": "mandatory"
12
+ }
13
+ ],
14
+ "supported_devices": ["desktop", "mobile"]
15
+ },
16
+ "intent": {
17
+ "data_connector": {
18
+ "enrolled": true
19
+ }
20
+ }
21
+ }
@@ -19,72 +19,72 @@
19
19
  "postinstall": "ts-node ./scripts/copy_env.ts"
20
20
  },
21
21
  "dependencies": {
22
- "@canva/app-i18n-kit": "^1.0.2",
22
+ "@canva/app-i18n-kit": "^1.0.3",
23
23
  "@canva/app-ui-kit": "^4.10.0",
24
- "@canva/asset": "^2.2.0",
25
- "@canva/design": "^2.6.0",
24
+ "@canva/asset": "^2.2.1",
25
+ "@canva/design": "^2.7.0",
26
26
  "@canva/error": "^2.1.0",
27
27
  "@canva/intents": "^2.0.0",
28
28
  "@canva/platform": "^2.2.0",
29
- "@canva/user": "^2.1.0",
29
+ "@canva/user": "^2.1.1",
30
30
  "react": "18.3.1",
31
31
  "react-dom": "18.3.1",
32
- "react-error-boundary": "4.1.2",
32
+ "react-error-boundary": "6.0.0",
33
33
  "react-intl": "6.8.7",
34
- "react-router-dom": "6.28.0"
34
+ "react-router-dom": "7.6.3"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@canva/app-eslint-plugin": "^1.0.0-beta.3",
38
38
  "@canva/cli": ">= 0.0.1-beta.13 < 0.0.2",
39
- "@formatjs/cli": "6.3.15",
40
- "@formatjs/ts-transformer": "3.13.27",
41
- "@ngrok/ngrok": "1.4.1",
42
- "@pmmmwh/react-refresh-webpack-plugin": "0.5.15",
39
+ "@formatjs/cli": "6.7.2",
40
+ "@formatjs/ts-transformer": "3.14.0",
41
+ "@ngrok/ngrok": "1.5.1",
42
+ "@pmmmwh/react-refresh-webpack-plugin": "0.6.1",
43
43
  "@svgr/webpack": "8.1.0",
44
- "@testing-library/react": "16.1.0",
44
+ "@testing-library/react": "16.3.0",
45
45
  "@types/express": "4.17.21",
46
- "@types/express-serve-static-core": "4.19.6",
46
+ "@types/express-serve-static-core": "5.0.6",
47
47
  "@types/jest": "29.5.14",
48
- "@types/jsonwebtoken": "9.0.7",
49
- "@types/node": "20.10.0",
48
+ "@types/jsonwebtoken": "9.0.10",
49
+ "@types/node": "20.19.2",
50
50
  "@types/node-fetch": "2.6.12",
51
51
  "@types/node-forge": "1.3.11",
52
52
  "@types/nodemon": "1.19.6",
53
53
  "@types/react": "18.3.12",
54
54
  "@types/react-dom": "18.3.1",
55
- "@types/webpack-env": "1.18.5",
55
+ "@types/webpack-env": "1.18.8",
56
56
  "chalk": "4.1.2",
57
57
  "cli-table3": "0.6.5",
58
58
  "css-loader": "7.1.2",
59
59
  "css-modules-typescript-loader": "4.0.1",
60
- "cssnano": "7.0.6",
61
- "debug": "4.4.0",
62
- "dotenv": "16.4.7",
60
+ "cssnano": "7.0.7",
61
+ "debug": "4.4.1",
62
+ "dotenv": "16.6.0",
63
63
  "express": "4.21.2",
64
64
  "express-basic-auth": "1.2.1",
65
65
  "jest": "29.7.0",
66
66
  "jest-css-modules-transform": "4.4.2",
67
67
  "jest-environment-jsdom": "29.7.0",
68
68
  "jsonwebtoken": "9.0.2",
69
- "jwks-rsa": "3.1.0",
69
+ "jwks-rsa": "3.2.0",
70
70
  "mini-css-extract-plugin": "2.9.2",
71
71
  "node-fetch": "3.3.2",
72
72
  "node-forge": "1.3.1",
73
73
  "nodemon": "3.0.1",
74
74
  "open": "8.4.2",
75
75
  "postcss-loader": "8.1.1",
76
- "prettier": "3.4.2",
77
- "react-refresh": "0.16.0",
76
+ "prettier": "3.6.2",
77
+ "react-refresh": "0.17.0",
78
78
  "style-loader": "4.0.0",
79
- "terser-webpack-plugin": "5.3.11",
79
+ "terser-webpack-plugin": "5.3.14",
80
80
  "tree-kill": "1.2.2",
81
- "ts-jest": "29.2.5",
81
+ "ts-jest": "29.4.0",
82
82
  "ts-loader": "9.5.2",
83
83
  "ts-node": "10.9.2",
84
- "typescript": "5.5.4",
84
+ "typescript": "5.8.2",
85
85
  "url-loader": "4.1.1",
86
- "webpack": "5.97.1",
87
- "webpack-cli": "5.1.4",
86
+ "webpack": "5.99.9",
87
+ "webpack-cli": "6.0.1",
88
88
  "webpack-dev-server": "5.2.2",
89
89
  "yargs": "17.7.2"
90
90
  }
@@ -1,7 +1,7 @@
1
1
  import * as crypto from "crypto";
2
+ import * as fs from "fs/promises";
2
3
  import { pki } from "node-forge";
3
4
  import * as path from "path";
4
- import * as fs from "fs/promises";
5
5
 
6
6
  const SSL_CERT_DIR = path.resolve(process.cwd(), "..", "..", ".ssl");
7
7
  const CERT_FILE = path.resolve(SSL_CERT_DIR, "certificate.pem");