@canva/cli 1.8.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.
- package/CHANGELOG.md +22 -0
- package/cli.js +266 -366
- package/lib/cjs/index.cjs +6 -6
- package/lib/esm/index.mjs +6 -6
- package/package.json +1 -1
- package/templates/base/backend/database/database.ts +2 -2
- package/templates/base/backend/routers/auth.ts +5 -5
- package/templates/base/backend/routers/oauth.ts +4 -4
- package/templates/base/package.json +1 -2
- package/templates/base/scripts/copy_env.ts +2 -2
- package/templates/base/scripts/ssl/ssl.ts +3 -3
- package/templates/base/scripts/start/app_runner.ts +29 -7
- package/templates/base/scripts/start/context.ts +2 -2
- package/templates/base/scripts/start/start.ts +1 -1
- package/templates/base/scripts/start.tests.ts +1 -1
- package/templates/base/tsconfig.json +7 -4
- package/templates/base/utils/backend/base_backend/create.ts +7 -7
- package/templates/base/utils/backend/bearer_middleware/bearer_middleware.ts +3 -5
- package/templates/base/utils/backend/jwt_middleware/jwt_middleware.ts +5 -10
- package/templates/base/utils/use_add_element.ts +10 -0
- package/templates/base/webpack.config.ts +4 -4
- package/templates/common/utils/backend/base_backend/create.ts +7 -7
- package/templates/common/utils/backend/jwt_middleware/jwt_middleware.ts +5 -10
- package/templates/common/utils/table_wrapper.ts +80 -37
- package/templates/common/utils/use_add_element.ts +10 -0
- package/templates/common/utils/use_overlay_hook.ts +6 -4
- package/templates/dam/backend/routers/dam.ts +37 -19
- package/templates/dam/backend/server.ts +2 -2
- package/templates/dam/package.json +1 -2
- package/templates/dam/scripts/copy_env.ts +2 -2
- package/templates/dam/scripts/ssl/ssl.ts +3 -3
- package/templates/dam/scripts/start/app_runner.ts +29 -7
- package/templates/dam/scripts/start/context.ts +2 -2
- package/templates/dam/scripts/start/start.ts +1 -1
- package/templates/dam/tsconfig.json +7 -4
- package/templates/dam/utils/backend/base_backend/create.ts +7 -7
- package/templates/dam/utils/backend/jwt_middleware/jwt_middleware.ts +5 -10
- package/templates/dam/webpack.config.ts +4 -4
- package/templates/data_connector/package.json +2 -2
- package/templates/data_connector/scripts/copy_env.ts +2 -2
- package/templates/data_connector/scripts/ssl/ssl.ts +3 -3
- package/templates/data_connector/scripts/start/app_runner.ts +29 -7
- package/templates/data_connector/scripts/start/context.ts +2 -2
- package/templates/data_connector/scripts/start/start.ts +1 -1
- package/templates/data_connector/src/utils/data_table.ts +2 -1
- package/templates/data_connector/src/utils/tests/data_table.test.ts +2 -2
- package/templates/data_connector/tsconfig.json +7 -4
- package/templates/data_connector/webpack.config.ts +4 -4
- package/templates/gen_ai/backend/database/database.ts +2 -2
- package/templates/gen_ai/backend/routers/image.ts +5 -7
- package/templates/gen_ai/backend/server.ts +2 -2
- package/templates/gen_ai/package.json +2 -2
- package/templates/gen_ai/scripts/copy_env.ts +2 -2
- package/templates/gen_ai/scripts/ssl/ssl.ts +3 -3
- package/templates/gen_ai/scripts/start/app_runner.ts +29 -7
- package/templates/gen_ai/scripts/start/context.ts +2 -2
- package/templates/gen_ai/scripts/start/start.ts +1 -1
- package/templates/gen_ai/src/components/image_grid.tsx +6 -2
- package/templates/gen_ai/src/components/prompt_input.tsx +4 -1
- package/templates/gen_ai/tsconfig.json +7 -4
- package/templates/gen_ai/utils/backend/base_backend/create.ts +7 -7
- package/templates/gen_ai/utils/backend/bearer_middleware/bearer_middleware.ts +3 -5
- package/templates/gen_ai/webpack.config.ts +4 -4
- package/templates/hello_world/package.json +2 -2
- package/templates/hello_world/scripts/copy_env.ts +2 -2
- package/templates/hello_world/scripts/ssl/ssl.ts +3 -3
- package/templates/hello_world/scripts/start/app_runner.ts +29 -7
- package/templates/hello_world/scripts/start/context.ts +2 -2
- package/templates/hello_world/scripts/start/start.ts +1 -1
- package/templates/hello_world/src/tests/app.tests.tsx +1 -1
- package/templates/hello_world/tsconfig.json +7 -4
- package/templates/hello_world/utils/use_add_element.ts +10 -0
- package/templates/hello_world/webpack.config.ts +4 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/* eslint-disable no-console */
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import path from "path";
|
|
5
5
|
|
|
6
6
|
const envPath = path.resolve(__dirname, "..", ".env");
|
|
7
7
|
const templatePath = path.resolve(__dirname, "..", ".env.template");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import crypto from "crypto";
|
|
2
|
+
import fs from "fs/promises";
|
|
3
3
|
import { pki } from "node-forge";
|
|
4
|
-
import
|
|
4
|
+
import path from "path";
|
|
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,12 +1,13 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
import { generatePreviewUrl } from "@canva/cli";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
3
|
+
import ngrok from "@ngrok/ngrok";
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import Table from "cli-table3";
|
|
6
|
+
import nodemon from "nodemon";
|
|
7
7
|
import open from "open";
|
|
8
|
-
import
|
|
9
|
-
import
|
|
8
|
+
import os from "os";
|
|
9
|
+
import webpack from "webpack";
|
|
10
|
+
import WebpackDevServer from "webpack-dev-server";
|
|
10
11
|
import { buildConfig } from "../../webpack.config";
|
|
11
12
|
import type { Certificate } from "../ssl/ssl";
|
|
12
13
|
import { createOrRetrieveCertificate } from "../ssl/ssl";
|
|
@@ -18,6 +19,22 @@ export const errorChalk = chalk.bgRed.bold;
|
|
|
18
19
|
export const highlightChalk = chalk.greenBright.bold;
|
|
19
20
|
export const linkChalk = chalk.cyan;
|
|
20
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Returns the appropriate modifier key text based on the user's operating system.
|
|
24
|
+
* @returns "cmd" for macOS, "ctrl" for Windows and Linux
|
|
25
|
+
*/
|
|
26
|
+
export function getModifierKey(): string {
|
|
27
|
+
const platform = os.platform();
|
|
28
|
+
switch (platform) {
|
|
29
|
+
case "darwin": // macOS
|
|
30
|
+
return "cmd";
|
|
31
|
+
case "win32": // Windows
|
|
32
|
+
return "ctrl";
|
|
33
|
+
default: // Linux and others
|
|
34
|
+
return "ctrl";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
21
38
|
export class AppRunner {
|
|
22
39
|
async run(ctx: Context) {
|
|
23
40
|
console.log(
|
|
@@ -189,9 +206,14 @@ export class AppRunner {
|
|
|
189
206
|
return;
|
|
190
207
|
}
|
|
191
208
|
|
|
209
|
+
const modifierKey = getModifierKey();
|
|
210
|
+
|
|
192
211
|
table.push([
|
|
193
212
|
previewCellHeader,
|
|
194
|
-
{
|
|
213
|
+
{
|
|
214
|
+
content: `Preview URL (${modifierKey} + click)`,
|
|
215
|
+
href: generatePreviewResult.data,
|
|
216
|
+
},
|
|
195
217
|
]);
|
|
196
218
|
|
|
197
219
|
if (openPreview) {
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
"experimentalDecorators": true,
|
|
19
19
|
"importHelpers": true,
|
|
20
20
|
"noImplicitOverride": true,
|
|
21
|
-
"moduleResolution": "
|
|
21
|
+
"moduleResolution": "bundler",
|
|
22
|
+
"esModuleInterop": true,
|
|
22
23
|
"rootDir": ".",
|
|
23
24
|
"outDir": "dist",
|
|
24
25
|
"strict": true,
|
|
@@ -27,7 +28,10 @@
|
|
|
27
28
|
"sourceMap": true,
|
|
28
29
|
"inlineSources": true,
|
|
29
30
|
"module": "ESNext",
|
|
30
|
-
"noImplicitAny":
|
|
31
|
+
"noImplicitAny": true,
|
|
32
|
+
"noImplicitReturns": true,
|
|
33
|
+
"noFallthroughCasesInSwitch": true,
|
|
34
|
+
"noUncheckedIndexedAccess": true,
|
|
31
35
|
"removeComments": true,
|
|
32
36
|
"preserveConstEnums": true,
|
|
33
37
|
"allowSyntheticDefaultImports": true,
|
|
@@ -43,8 +47,7 @@
|
|
|
43
47
|
"./utils/**/*",
|
|
44
48
|
"./scripts/**/*",
|
|
45
49
|
"./declarations/declarations.d.ts",
|
|
46
|
-
"./styles/**/*"
|
|
47
|
-
"./node_modules/@types/**/*"
|
|
50
|
+
"./styles/**/*"
|
|
48
51
|
],
|
|
49
52
|
"ts-node": {
|
|
50
53
|
"compilerOptions": {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
import debug from "debug";
|
|
3
|
-
import
|
|
3
|
+
import express from "express";
|
|
4
4
|
import type { NextFunction, Request, Response } from "express";
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
5
|
+
import fs from "fs";
|
|
6
|
+
import http from "http";
|
|
7
|
+
import https from "https";
|
|
8
8
|
|
|
9
9
|
const serverDebug = debug("server");
|
|
10
10
|
|
|
@@ -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
|
|
44
|
+
app.get("/healthz", (req, res) => {
|
|
45
45
|
res.sendStatus(200);
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
// logging middleware
|
|
49
|
-
app.use((req
|
|
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,
|
|
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,10 +1,7 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
|
-
import
|
|
3
|
-
import * as debug from "debug";
|
|
2
|
+
import debug from "debug";
|
|
4
3
|
import type { NextFunction, Request, Response } from "express";
|
|
5
|
-
|
|
6
|
-
import Express from "express-serve-static-core";
|
|
7
|
-
import * as jwt from "jsonwebtoken";
|
|
4
|
+
import jwt from "jsonwebtoken";
|
|
8
5
|
import { JwksClient, SigningKeyNotFoundError } from "jwks-rsa";
|
|
9
6
|
|
|
10
7
|
/**
|
|
@@ -116,7 +113,7 @@ export function createJwtMiddleware(
|
|
|
116
113
|
userId: payload.userId,
|
|
117
114
|
};
|
|
118
115
|
|
|
119
|
-
next();
|
|
116
|
+
return next();
|
|
120
117
|
} catch (e) {
|
|
121
118
|
if (e instanceof JWTAuthorizationError) {
|
|
122
119
|
return sendUnauthorizedResponse(res, e.message);
|
|
@@ -125,9 +122,7 @@ export function createJwtMiddleware(
|
|
|
125
122
|
if (e instanceof SigningKeyNotFoundError) {
|
|
126
123
|
return sendUnauthorizedResponse(
|
|
127
124
|
res,
|
|
128
|
-
`Public key not found.
|
|
129
|
-
"Ensure you have the correct App_ID set",
|
|
130
|
-
)}.`,
|
|
125
|
+
`Public key not found. Ensure you have the correct App_ID set`,
|
|
131
126
|
);
|
|
132
127
|
}
|
|
133
128
|
|
|
@@ -139,7 +134,7 @@ export function createJwtMiddleware(
|
|
|
139
134
|
return sendUnauthorizedResponse(res, "Token expired");
|
|
140
135
|
}
|
|
141
136
|
|
|
142
|
-
next(e);
|
|
137
|
+
return next(e);
|
|
143
138
|
}
|
|
144
139
|
};
|
|
145
140
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { Configuration } from "webpack";
|
|
2
2
|
import { DefinePlugin, optimize } from "webpack";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import path from "path";
|
|
4
|
+
import TerserPlugin from "terser-webpack-plugin";
|
|
5
5
|
import { transform } from "@formatjs/ts-transformer";
|
|
6
|
-
import
|
|
6
|
+
import chalk from "chalk";
|
|
7
7
|
import { config } from "dotenv";
|
|
8
8
|
import { Configuration as DevServerConfiguration } from "webpack-dev-server";
|
|
9
9
|
|
|
@@ -196,7 +196,7 @@ function buildDevConfig(options?: DevConfig): {
|
|
|
196
196
|
return {};
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
-
const { port, enableHmr, appOrigin,
|
|
199
|
+
const { port, enableHmr, appOrigin, enableHttps, certFile, keyFile } =
|
|
200
200
|
options;
|
|
201
201
|
const host = "localhost";
|
|
202
202
|
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@canva/app-i18n-kit": "^1.1.1",
|
|
23
|
-
"@canva/app-ui-kit": "^5.2.
|
|
23
|
+
"@canva/app-ui-kit": "^5.2.1",
|
|
24
24
|
"@canva/asset": "^2.2.1",
|
|
25
25
|
"@canva/design": "^2.7.3",
|
|
26
26
|
"@canva/error": "^2.1.0",
|
|
@@ -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",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/* eslint-disable no-console */
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import path from "path";
|
|
5
5
|
|
|
6
6
|
const envPath = path.resolve(__dirname, "..", ".env");
|
|
7
7
|
const templatePath = path.resolve(__dirname, "..", ".env.template");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import crypto from "crypto";
|
|
2
|
+
import fs from "fs/promises";
|
|
3
3
|
import { pki } from "node-forge";
|
|
4
|
-
import
|
|
4
|
+
import path from "path";
|
|
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,12 +1,13 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
import { generatePreviewUrl } from "@canva/cli";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
3
|
+
import ngrok from "@ngrok/ngrok";
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import Table from "cli-table3";
|
|
6
|
+
import nodemon from "nodemon";
|
|
7
7
|
import open from "open";
|
|
8
|
-
import
|
|
9
|
-
import
|
|
8
|
+
import os from "os";
|
|
9
|
+
import webpack from "webpack";
|
|
10
|
+
import WebpackDevServer from "webpack-dev-server";
|
|
10
11
|
import { buildConfig } from "../../webpack.config";
|
|
11
12
|
import type { Certificate } from "../ssl/ssl";
|
|
12
13
|
import { createOrRetrieveCertificate } from "../ssl/ssl";
|
|
@@ -18,6 +19,22 @@ export const errorChalk = chalk.bgRed.bold;
|
|
|
18
19
|
export const highlightChalk = chalk.greenBright.bold;
|
|
19
20
|
export const linkChalk = chalk.cyan;
|
|
20
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Returns the appropriate modifier key text based on the user's operating system.
|
|
24
|
+
* @returns "cmd" for macOS, "ctrl" for Windows and Linux
|
|
25
|
+
*/
|
|
26
|
+
export function getModifierKey(): string {
|
|
27
|
+
const platform = os.platform();
|
|
28
|
+
switch (platform) {
|
|
29
|
+
case "darwin": // macOS
|
|
30
|
+
return "cmd";
|
|
31
|
+
case "win32": // Windows
|
|
32
|
+
return "ctrl";
|
|
33
|
+
default: // Linux and others
|
|
34
|
+
return "ctrl";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
21
38
|
export class AppRunner {
|
|
22
39
|
async run(ctx: Context) {
|
|
23
40
|
console.log(
|
|
@@ -189,9 +206,14 @@ export class AppRunner {
|
|
|
189
206
|
return;
|
|
190
207
|
}
|
|
191
208
|
|
|
209
|
+
const modifierKey = getModifierKey();
|
|
210
|
+
|
|
192
211
|
table.push([
|
|
193
212
|
previewCellHeader,
|
|
194
|
-
{
|
|
213
|
+
{
|
|
214
|
+
content: `Preview URL (${modifierKey} + click)`,
|
|
215
|
+
href: generatePreviewResult.data,
|
|
216
|
+
},
|
|
195
217
|
]);
|
|
196
218
|
|
|
197
219
|
if (openPreview) {
|
|
@@ -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
|
-
|
|
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]
|
|
96
|
-
expect(result.rows[1]
|
|
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", () => {
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
"experimentalDecorators": true,
|
|
19
19
|
"importHelpers": true,
|
|
20
20
|
"noImplicitOverride": true,
|
|
21
|
-
"moduleResolution": "
|
|
21
|
+
"moduleResolution": "bundler",
|
|
22
|
+
"esModuleInterop": true,
|
|
22
23
|
"rootDir": ".",
|
|
23
24
|
"outDir": "dist",
|
|
24
25
|
"strict": true,
|
|
@@ -27,7 +28,10 @@
|
|
|
27
28
|
"sourceMap": true,
|
|
28
29
|
"inlineSources": true,
|
|
29
30
|
"module": "ESNext",
|
|
30
|
-
"noImplicitAny":
|
|
31
|
+
"noImplicitAny": true,
|
|
32
|
+
"noImplicitReturns": true,
|
|
33
|
+
"noFallthroughCasesInSwitch": true,
|
|
34
|
+
"noUncheckedIndexedAccess": true,
|
|
31
35
|
"removeComments": true,
|
|
32
36
|
"preserveConstEnums": true,
|
|
33
37
|
"allowSyntheticDefaultImports": true,
|
|
@@ -43,8 +47,7 @@
|
|
|
43
47
|
"./utils/**/*",
|
|
44
48
|
"./scripts/**/*",
|
|
45
49
|
"./declarations/declarations.d.ts",
|
|
46
|
-
"./styles/**/*"
|
|
47
|
-
"./node_modules/@types/**/*"
|
|
50
|
+
"./styles/**/*"
|
|
48
51
|
],
|
|
49
52
|
"ts-node": {
|
|
50
53
|
"compilerOptions": {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { Configuration } from "webpack";
|
|
2
2
|
import { DefinePlugin, optimize } from "webpack";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import path from "path";
|
|
4
|
+
import TerserPlugin from "terser-webpack-plugin";
|
|
5
5
|
import { transform } from "@formatjs/ts-transformer";
|
|
6
|
-
import
|
|
6
|
+
import chalk from "chalk";
|
|
7
7
|
import { config } from "dotenv";
|
|
8
8
|
import { Configuration as DevServerConfiguration } from "webpack-dev-server";
|
|
9
9
|
|
|
@@ -196,7 +196,7 @@ function buildDevConfig(options?: DevConfig): {
|
|
|
196
196
|
return {};
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
-
const { port, enableHmr, appOrigin,
|
|
199
|
+
const { port, enableHmr, appOrigin, enableHttps, certFile, keyFile } =
|
|
200
200
|
options;
|
|
201
201
|
const host = "localhost";
|
|
202
202
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* Use this code as a learning resource, but do not deploy it in a real backend without significant modifications
|
|
9
9
|
* to ensure reliability, security, and scalability.
|
|
10
10
|
*/
|
|
11
|
-
import
|
|
11
|
+
import express from "express";
|
|
12
12
|
|
|
13
13
|
interface ImageResponse {
|
|
14
14
|
fullsize: { width: number; height: number; url: string };
|
|
@@ -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
|
-
|
|
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
|
-
|
|
218
|
-
clearTimeout(timeoutId);
|
|
219
|
-
}
|
|
217
|
+
clearTimeout(job.timeoutId);
|
|
220
218
|
return res.status(200).send("Job successfully cancelled.");
|
|
221
219
|
}
|
|
222
220
|
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@canva/app-i18n-kit": "^1.1.1",
|
|
22
|
-
"@canva/app-ui-kit": "^5.2.
|
|
22
|
+
"@canva/app-ui-kit": "^5.2.1",
|
|
23
23
|
"@canva/asset": "^2.2.1",
|
|
24
24
|
"@canva/design": "^2.7.3",
|
|
25
25
|
"@canva/error": "^2.1.0",
|
|
@@ -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",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/* eslint-disable no-console */
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import path from "path";
|
|
5
5
|
|
|
6
6
|
const envPath = path.resolve(__dirname, "..", ".env");
|
|
7
7
|
const templatePath = path.resolve(__dirname, "..", ".env.template");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import crypto from "crypto";
|
|
2
|
+
import fs from "fs/promises";
|
|
3
3
|
import { pki } from "node-forge";
|
|
4
|
-
import
|
|
4
|
+
import path from "path";
|
|
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,12 +1,13 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
import { generatePreviewUrl } from "@canva/cli";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
3
|
+
import ngrok from "@ngrok/ngrok";
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import Table from "cli-table3";
|
|
6
|
+
import nodemon from "nodemon";
|
|
7
7
|
import open from "open";
|
|
8
|
-
import
|
|
9
|
-
import
|
|
8
|
+
import os from "os";
|
|
9
|
+
import webpack from "webpack";
|
|
10
|
+
import WebpackDevServer from "webpack-dev-server";
|
|
10
11
|
import { buildConfig } from "../../webpack.config";
|
|
11
12
|
import type { Certificate } from "../ssl/ssl";
|
|
12
13
|
import { createOrRetrieveCertificate } from "../ssl/ssl";
|
|
@@ -18,6 +19,22 @@ export const errorChalk = chalk.bgRed.bold;
|
|
|
18
19
|
export const highlightChalk = chalk.greenBright.bold;
|
|
19
20
|
export const linkChalk = chalk.cyan;
|
|
20
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Returns the appropriate modifier key text based on the user's operating system.
|
|
24
|
+
* @returns "cmd" for macOS, "ctrl" for Windows and Linux
|
|
25
|
+
*/
|
|
26
|
+
export function getModifierKey(): string {
|
|
27
|
+
const platform = os.platform();
|
|
28
|
+
switch (platform) {
|
|
29
|
+
case "darwin": // macOS
|
|
30
|
+
return "cmd";
|
|
31
|
+
case "win32": // Windows
|
|
32
|
+
return "ctrl";
|
|
33
|
+
default: // Linux and others
|
|
34
|
+
return "ctrl";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
21
38
|
export class AppRunner {
|
|
22
39
|
async run(ctx: Context) {
|
|
23
40
|
console.log(
|
|
@@ -189,9 +206,14 @@ export class AppRunner {
|
|
|
189
206
|
return;
|
|
190
207
|
}
|
|
191
208
|
|
|
209
|
+
const modifierKey = getModifierKey();
|
|
210
|
+
|
|
192
211
|
table.push([
|
|
193
212
|
previewCellHeader,
|
|
194
|
-
{
|
|
213
|
+
{
|
|
214
|
+
content: `Preview URL (${modifierKey} + click)`,
|
|
215
|
+
href: generatePreviewResult.data,
|
|
216
|
+
},
|
|
195
217
|
]);
|
|
196
218
|
|
|
197
219
|
if (openPreview) {
|
|
@@ -34,7 +34,9 @@ export const ImageGrid = () => {
|
|
|
34
34
|
) => {
|
|
35
35
|
const parentNode = event.currentTarget.parentElement;
|
|
36
36
|
try {
|
|
37
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|