From 9c6dc9e81dfc2f93e93bd03862aac97b52e184f1 Mon Sep 17 00:00:00 2001 From: Josh Wulf Date: Mon, 4 Nov 2024 16:49:26 +0530 Subject: [PATCH] chore: make compatible with deno --- .vscode/settings.json | 3 +- deno.json | 7 ++ packages/c8cli/deno.json | 3 + packages/c8cli/package.json | 28 +++++++ packages/c8cli/source/commands.ts | 75 +++++++++++++++++++ packages/c8cli/source/main.ts | 54 +++++++++++++ packages/c8cli/source/parse-arguments.ts | 26 +++++++ packages/c8cli/tests/parse-arguments.test.ts | 1 + packages/lossless-json/package.json | 11 +-- .../__tests__/LosslessJsonParser.unit.spec.ts | 2 +- .../{src => source}/__tests__/tsconfig.json | 4 +- .../lossless-json/{src => source}/index.ts | 3 +- packages/lossless-json/tsconfig.json | 17 +++-- packages/sdk-rest/package.json | 1 - .../sdk/src/modeler/lib/ModelerAPIClient.ts | 6 +- pnpm-lock.yaml | 16 ++-- 16 files changed, 226 insertions(+), 31 deletions(-) create mode 100644 deno.json create mode 100644 packages/c8cli/deno.json create mode 100644 packages/c8cli/package.json create mode 100644 packages/c8cli/source/commands.ts create mode 100644 packages/c8cli/source/main.ts create mode 100644 packages/c8cli/source/parse-arguments.ts create mode 100644 packages/c8cli/tests/parse-arguments.test.ts rename packages/lossless-json/{src => source}/__tests__/LosslessJsonParser.unit.spec.ts (99%) rename packages/lossless-json/{src => source}/__tests__/tsconfig.json (84%) rename packages/lossless-json/{src => source}/index.ts (99%) diff --git a/.vscode/settings.json b/.vscode/settings.json index 34dbb624..7063d67d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -26,5 +26,6 @@ }, "[typescriptreact]": { "editor.defaultFormatter": "samverschueren.linter-xo" - } + }, + "deno.enable": false } \ No newline at end of file diff --git a/deno.json b/deno.json new file mode 100644 index 00000000..cf52736c --- /dev/null +++ b/deno.json @@ -0,0 +1,7 @@ +{ + "workspace": { + "members": [ + "packages/c8cli" + ] + } +} \ No newline at end of file diff --git a/packages/c8cli/deno.json b/packages/c8cli/deno.json new file mode 100644 index 00000000..ad6e5aac --- /dev/null +++ b/packages/c8cli/deno.json @@ -0,0 +1,3 @@ +{ + "format": "tsconfig" +} \ No newline at end of file diff --git a/packages/c8cli/package.json b/packages/c8cli/package.json new file mode 100644 index 00000000..2faefc00 --- /dev/null +++ b/packages/c8cli/package.json @@ -0,0 +1,28 @@ +{ + "name": "@camunda8/c8cli", + "version": "1.0.0", + "description": "Cross-platform Camunda 8 CLI", + "main": "run.ts", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "clean": "rm -rf distribution", + "mkdirs": "mkdir -p distribution/linux-x86_64 && mkdir -p distribution/linux-arm64 && mkdir -p distribution/windows-x86_64 && mkdir -p distribution/darwin-x86_64 && mkdir -p distribution/darwin-arm64", + "build": "pnpm run clean && pnpm run mkdirs && pnpm run build:linux-x86_64 && pnpm run build:linux-arm64 && pnpm run build:windows-x86_64 && pnpm run build:darwin-x86_64 && pnpm run build:darwin-arm64", + "build:linux-x86_64": "deno compile --allow-all --target x86_64-unknown-linux-gnu --output distribution/linux-x86_64/c8cli source/main.ts", + "build:linux-arm64": "deno compile --allow-all --target aarch64-unknown-linux-gnu --output distribution/linux-arm64/c8cli source/main.ts", + "build:windows-x86_64": "deno compile --allow-all --target x86_64-pc-windows-msvc --output distribution/windows_x86_64/c8cli.exe source/main.ts", + "build:darwin-x86_64": "deno compile --allow-all --target x86_64-apple-darwin --output distribution/darwin-x86_64/c8cli source/main.ts", + "build:darwin-arm64": "deno compile --allow-all --node-modules-dir=auto --target aarch64-apple-darwin --output distribution/darwin-arm64/c8cli source/main.ts" + }, + "dependencies": { + "@camunda8/sdk-rest": "workspace:*" + }, + "keywords": [ + "Camunda 8", + "Camunda", + "cli" + ], + "engine": "deno", + "author": "Josh Wulf ", + "license": "ISC" +} \ No newline at end of file diff --git a/packages/c8cli/source/commands.ts b/packages/c8cli/source/commands.ts new file mode 100644 index 00000000..c2679eac --- /dev/null +++ b/packages/c8cli/source/commands.ts @@ -0,0 +1,75 @@ +import { CamundaRestClient } from "@camunda8/sdk-rest"; +import type { ParsedArguments } from "./parse-arguments.ts"; + +type CliCommandExecutor = ( + camunda: CamundaRestClient, + args: ParsedArguments, +) => Promise; + +type CliArgs = { + required: string[]; + optional: string[]; +}; + +export type CliCommand = { + description: string; + usage: string; + args: CliArgs; + run: CliCommandExecutor; +}; + +export function emitCommandHelp(command: CliCommand) { + console.log(`\nDescription: ${command.description}`); + console.log(`Usage: ${command.usage}`); + console.log(`Required Arguments: `, command.args.required.join(", ")); + console.log(`Optional Arguments: `, command.args.optional.join(", ")); +} + +export const commands: { + [key: string]: CliCommand; +} = { + "topology": { + description: "Get the Camunda 8 cluster topology", + usage: "c8cli topology", + args: { + required: [], + optional: [], + }, + run: async (camunda: CamundaRestClient) => { + const topology = await camunda.getTopology(); + console.log(topology); + return 0; + }, + }, + "license": { + description: "Get the Camunda 8 cluster license status", + usage: "c8cli license", + args: { + required: [], + optional: [], + }, + run: async (camunda: CamundaRestClient) => { + const status = await camunda.getLicenseStatus(); + console.log(status); + return 0; + }, + }, + "deploy-resource": { + description: + "Deploy a resource (BPMN | DMN | Form) from a file to a Camunda 8 cluster", + usage: "c8cli deploy-resource --file --tenantId ", + args: { + required: ["file"], + optional: ["tenantId"], + }, + run: async (camunda: CamundaRestClient, args: ParsedArguments) => { + const content = Deno.readFileSync(args.file as string); + const response = await camunda.deployResources({ + resources: { content, name: args.file }, + tenantId: args.tenantId, + }); + console.log(response); + return 0; + }, + }, +}; diff --git a/packages/c8cli/source/main.ts b/packages/c8cli/source/main.ts new file mode 100644 index 00000000..49de6e48 --- /dev/null +++ b/packages/c8cli/source/main.ts @@ -0,0 +1,54 @@ +import { CamundaRestClient } from "@camunda8/sdk-rest"; +import { commands, emitCommandHelp } from "./commands.ts"; +import { parseArguments } from "./parse-arguments.ts"; + +const command = Deno.args[0]; + +const noCommand = !command; +const unknownCommand = !Object.keys(commands).includes(command); +const helpCommand = Deno.args[0] === "--help"; + +if (noCommand || unknownCommand || helpCommand) { + console.log("\nCamunda 8 CLI\n"); + console.log("Usage:"); + for (const key of Object.keys(commands)) { + console.log(`c8cli ${key}\t - ${commands[key].description}`); + } + console.log(`\n`); + Deno.exit(0); +} + +const commandToRun = commands[command]; + +const firstArg = Deno.args[1]; + +const helpRequested = firstArg === "--help"; + +if (helpRequested) { + emitCommandHelp(commandToRun); + exit(0); +} else { + const args = parseArguments(); + const missingRequiredArgs = commandToRun.args.required.filter((key) => + !(key in args) + ); + if (missingRequiredArgs.length > 0) { + console.log( + `\nERROR: Missing required argument(s): ${ + missingRequiredArgs.join(", ") + }`, + ); + emitCommandHelp(commandToRun); + exit(1); + } + // TODO - unknown argument(s) passed + // TODO - "One of" arguments + const exitCode = await commandToRun.run(new CamundaRestClient(), args); + console.log("\n"); + exit(exitCode); +} + +function exit(code: number) { + console.log("\n"); + Deno.exit(code); +} diff --git a/packages/c8cli/source/parse-arguments.ts b/packages/c8cli/source/parse-arguments.ts new file mode 100644 index 00000000..eb0530db --- /dev/null +++ b/packages/c8cli/source/parse-arguments.ts @@ -0,0 +1,26 @@ +const args = Deno.args; +export type ParsedArguments = { [key: string]: string | boolean }; +const parsedArgs: ParsedArguments = {}; + +export function parseArguments() { + for (let i = 1; i < args.length; i++) { + const arg = args[i]; + + if (arg.startsWith("--")) { + const key = arg.replace("--", ""); + // Check for the next argument + if (i + 1 < args.length) { + const nextArg = args[i + 1]; + if (nextArg.startsWith("--")) { + parsedArgs[key] = true; + } else { + parsedArgs[key] = nextArg; + i++; + } + } else { + parsedArgs[key] = ""; + } + } + } + return parsedArgs; +} diff --git a/packages/c8cli/tests/parse-arguments.test.ts b/packages/c8cli/tests/parse-arguments.test.ts new file mode 100644 index 00000000..c2e3bce7 --- /dev/null +++ b/packages/c8cli/tests/parse-arguments.test.ts @@ -0,0 +1 @@ +import { parseArguments } from "../source/parse-arguments.ts"; diff --git a/packages/lossless-json/package.json b/packages/lossless-json/package.json index 4276d9aa..9ad40fbb 100644 --- a/packages/lossless-json/package.json +++ b/packages/lossless-json/package.json @@ -2,13 +2,14 @@ "name": "@camunda8/lossless-json", "version": "1.0.0", "description": "Lossless JSON parsing with optional Dto mapping", - "main": "dist/index.js", + "main": "distribution/index.js", + "type": "module", "scripts": { "test": "jest", "build": "npm run clean && tsc --project tsconfig.json", - "clean": "rm -rf ./dist && rm -f ./tsconfig.tsbuildinfo", - "lint": "eslint 'src/**/*.{ts,tsx}'", - "format": "prettier --write 'src/**/*.ts'" + "clean": "rm -rf ./distribution && rm -f ./tsconfig.tsbuildinfo", + "lint": "eslint 'source/**/*.{ts,tsx}'", + "format": "prettier --write 'source/**/*.ts'" }, "repository": { "type": "git", @@ -38,7 +39,7 @@ "^.+\\.(ts|tsx)$": [ "ts-jest", { - "tsconfig": "src/__tests__/tsconfig.json" + "tsconfig": "source/__tests__/tsconfig.json" } ] }, diff --git a/packages/lossless-json/src/__tests__/LosslessJsonParser.unit.spec.ts b/packages/lossless-json/source/__tests__/LosslessJsonParser.unit.spec.ts similarity index 99% rename from packages/lossless-json/src/__tests__/LosslessJsonParser.unit.spec.ts rename to packages/lossless-json/source/__tests__/LosslessJsonParser.unit.spec.ts index f5996771..cbee6c06 100644 --- a/packages/lossless-json/src/__tests__/LosslessJsonParser.unit.spec.ts +++ b/packages/lossless-json/source/__tests__/LosslessJsonParser.unit.spec.ts @@ -8,7 +8,7 @@ import { LosslessDto, losslessParse, losslessStringify, -} from '../' +} from '../index.js' test('LosslessJsonParser correctly handles nested Dtos', () => { class DecisionInstanceOutput extends LosslessDto { diff --git a/packages/lossless-json/src/__tests__/tsconfig.json b/packages/lossless-json/source/__tests__/tsconfig.json similarity index 84% rename from packages/lossless-json/src/__tests__/tsconfig.json rename to packages/lossless-json/source/__tests__/tsconfig.json index 11a2c01d..530dd3e6 100644 --- a/packages/lossless-json/src/__tests__/tsconfig.json +++ b/packages/lossless-json/source/__tests__/tsconfig.json @@ -5,5 +5,7 @@ "../**/*" // Includes all files in the src directory ], "compilerOptions": {}, - "exclude": ["node_modules"] + "exclude": [ + "node_modules" + ] } diff --git a/packages/lossless-json/src/index.ts b/packages/lossless-json/source/index.ts similarity index 99% rename from packages/lossless-json/src/index.ts rename to packages/lossless-json/source/index.ts index 425b8d68..98cca3fb 100644 --- a/packages/lossless-json/src/index.ts +++ b/packages/lossless-json/source/index.ts @@ -21,7 +21,7 @@ */ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { debug as d } from 'debug' +// import { debug as d } from 'debug' import { LosslessNumber, isLosslessNumber, @@ -31,6 +31,7 @@ import { } from 'lossless-json' import 'reflect-metadata' +const d = _namespace => (_msg, _data?) => null const debug = d('lossless-json-parser') const MetadataKey = { diff --git a/packages/lossless-json/tsconfig.json b/packages/lossless-json/tsconfig.json index 25a3669c..3fea2c19 100644 --- a/packages/lossless-json/tsconfig.json +++ b/packages/lossless-json/tsconfig.json @@ -2,19 +2,20 @@ "compilerOptions": { "composite": true /* Required because referenced by src/tsconfig.json */, /* Basic Options */ - "target": "es2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */, - "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, + "target": "es2022" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */, + "module": "Node16" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, "types": [ "jest", "node" ], + "moduleResolution": "Node16", "lib": [ - "es2020", + "es2022", ], "declaration": true /* Generates corresponding '.d.ts' file. */, "sourceMap": true /* Generates corresponding '.map' file. */, - "outDir": "./dist" /* Redirect output structure to the directory. */, - "rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, + "outDir": "distribution" /* Redirect output structure to the directory. */, + "rootDir": "./source" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, /* Strict Type-Checking Options */ "forceConsistentCasingInFileNames": true, "strict": true /* Enable all strict type-checking options. */, @@ -34,7 +35,7 @@ }, "exclude": [ "node_modules", - "src/__tests__/*", - "dist" + "source/__tests__/*", + "distribution" ] -} \ No newline at end of file +} diff --git a/packages/sdk-rest/package.json b/packages/sdk-rest/package.json index 855f1c8c..c68b7e7a 100644 --- a/packages/sdk-rest/package.json +++ b/packages/sdk-rest/package.json @@ -65,7 +65,6 @@ "dependencies": { "@camunda8/lossless-json": "workspace:*", "@camunda8/oauth": "workspace:*", - "@types/multiparty": "^4.2.1", "debug": "^4.3.7", "eventemitter3": "^5.0.1", "ky": "^1.7.2", diff --git a/packages/sdk/src/modeler/lib/ModelerAPIClient.ts b/packages/sdk/src/modeler/lib/ModelerAPIClient.ts index 454e987a..604c8d74 100644 --- a/packages/sdk/src/modeler/lib/ModelerAPIClient.ts +++ b/packages/sdk/src/modeler/lib/ModelerAPIClient.ts @@ -213,7 +213,7 @@ export class ModelerApiClient { async deleteFile(fileId: string): Promise { const headers = await this.getHeaders() const rest = await this.rest - return rest(`files/${fileId}`, { + return rest.delete(`files/${fileId}`, { headers, }).then(this.decodeResponseOrThrow) as Promise } @@ -241,7 +241,7 @@ export class ModelerApiClient { ): Promise { const headers = await this.getHeaders() const rest = await this.rest - return rest(`files/${fileId}`, { + return rest.post(`files/${fileId}`, { headers, body: JSON.stringify(update), }).then((res) => @@ -280,7 +280,7 @@ export class ModelerApiClient { ): Promise { const headers = await this.getHeaders() const rest = await this.rest - return rest(`files/search`, { + return rest.post(`files/search`, { headers, body: JSON.stringify(req), }).then((res) => diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7ae69d8e..a6faf86e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,6 +34,12 @@ importers: specifier: ^22.7.4 version: 22.7.8 + packages/c8cli: + dependencies: + '@camunda8/sdk-rest': + specifier: workspace:* + version: link:../sdk-rest + packages/certificates: dependencies: debug: @@ -387,9 +393,6 @@ importers: '@camunda8/oauth': specifier: workspace:* version: link:../oauth - '@types/multiparty': - specifier: ^4.2.1 - version: 4.2.1 debug: specifier: ^4.3.7 version: 4.3.7 @@ -2284,9 +2287,6 @@ packages: '@types/ms@0.7.34': resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} - '@types/multiparty@4.2.1': - resolution: {integrity: sha512-Wi6aK3FgvHLvCDxD7ngG4w8MsCK9h64EB53Gvc8t7FVX81tleiz8vFS3ebBohGxqHRzNGHaNwhfdxTGOGAXm6A==} - '@types/node-fetch@2.6.11': resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==} @@ -11989,10 +11989,6 @@ snapshots: '@types/ms@0.7.34': {} - '@types/multiparty@4.2.1': - dependencies: - '@types/node': 22.7.8 - '@types/node-fetch@2.6.11': dependencies: '@types/node': 22.7.8