From 544e90631c0d5f0e02a6d562b0c5ee543235ef7c Mon Sep 17 00:00:00 2001 From: corb3nik Date: Mon, 14 Oct 2024 18:13:05 -0400 Subject: [PATCH] Add no-frontend template --- package.json | 2 +- .../no-frontend/.github/workflows/release.yml | 58 +++++++++ templates/no-frontend/.gitignore | 3 + templates/no-frontend/LICENSE | 121 ++++++++++++++++++ templates/no-frontend/README.md | 8 ++ templates/no-frontend/manifest.json | 20 +++ templates/no-frontend/package.json | 18 +++ .../no-frontend/packages/backend/package.json | 13 ++ .../no-frontend/packages/backend/src/index.ts | 15 +++ .../packages/backend/tsconfig.json | 7 + .../packages/backend/vite.config.ts | 21 +++ templates/no-frontend/pnpm-workspace.yaml | 2 + templates/no-frontend/scripts/clean.js | 8 ++ templates/no-frontend/scripts/pack.js | 55 ++++++++ templates/no-frontend/tsconfig.json | 24 ++++ 15 files changed, 374 insertions(+), 1 deletion(-) create mode 100644 templates/no-frontend/.github/workflows/release.yml create mode 100644 templates/no-frontend/.gitignore create mode 100644 templates/no-frontend/LICENSE create mode 100644 templates/no-frontend/README.md create mode 100644 templates/no-frontend/manifest.json create mode 100644 templates/no-frontend/package.json create mode 100644 templates/no-frontend/packages/backend/package.json create mode 100644 templates/no-frontend/packages/backend/src/index.ts create mode 100644 templates/no-frontend/packages/backend/tsconfig.json create mode 100644 templates/no-frontend/packages/backend/vite.config.ts create mode 100644 templates/no-frontend/pnpm-workspace.yaml create mode 100644 templates/no-frontend/scripts/clean.js create mode 100644 templates/no-frontend/scripts/pack.js create mode 100644 templates/no-frontend/tsconfig.json diff --git a/package.json b/package.json index 838833c..7128b22 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@caido-community/create-plugin", - "version": "0.0.3", + "version": "0.0.4", "description": "Initializer for Caido plugins", "author": "Caido Labs Inc. ", "homepage": "https://github.com/caido-community/create-plugin", diff --git a/templates/no-frontend/.github/workflows/release.yml b/templates/no-frontend/.github/workflows/release.yml new file mode 100644 index 0000000..5a5624f --- /dev/null +++ b/templates/no-frontend/.github/workflows/release.yml @@ -0,0 +1,58 @@ +name: 🚀 Release + +on: + workflow_dispatch: + +env: + NODE_VERSION: 20 + PNPM_VERSION: 9 + +jobs: + release: + name: Release + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - name: Checkout project + uses: actions/checkout@v4 + + - name: Check version + id: meta + run: | + VERSION=$(jq -r .version manifest.json) + echo "version=${VERSION}" >> $GITHUB_OUTPUT + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ env.PNPM_VERSION }} + run_install: true + + - name: Build package + run: pnpm build + + - name: Sign package + working-directory: dist + run: | + if [[ -z "${{ secrets.PRIVATE_KEY }}" ]]; then + echo "Set an ed25519 key as PRIVATE_KEY in GitHub Action secret to sign." + else + echo "${{ secrets.PRIVATE_KEY }}" > private_key.pem + openssl pkeyutl -sign -inkey private_key.pem -out plugin_package.zip.sig -rawin -in plugin_package.zip + rm private_key.pem + fi + + - name: Create release + uses: ncipollo/release-action@v1 + with: + tag: ${{ steps.meta.outputs.version }} + commit: ${{ github.sha }} + body: 'Release ${{ steps.meta.outputs.version }}' + artifacts: 'dist/plugin_package.zip,dist/plugin_package.zip.sig' diff --git a/templates/no-frontend/.gitignore b/templates/no-frontend/.gitignore new file mode 100644 index 0000000..0ca39c0 --- /dev/null +++ b/templates/no-frontend/.gitignore @@ -0,0 +1,3 @@ +node_modules +dist +.DS_Store diff --git a/templates/no-frontend/LICENSE b/templates/no-frontend/LICENSE new file mode 100644 index 0000000..0e259d4 --- /dev/null +++ b/templates/no-frontend/LICENSE @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/templates/no-frontend/README.md b/templates/no-frontend/README.md new file mode 100644 index 0000000..ff25f16 --- /dev/null +++ b/templates/no-frontend/README.md @@ -0,0 +1,8 @@ +# Vanilla JS Frontend Template + +This template should be used as a starting point for creating a new plugin with a vanilla JS frontend. + +## Features + +- [pnpm](https://pnpm.io/) as package manager +- [TypeScript](https://www.typescriptlang.org/) diff --git a/templates/no-frontend/manifest.json b/templates/no-frontend/manifest.json new file mode 100644 index 0000000..f36685f --- /dev/null +++ b/templates/no-frontend/manifest.json @@ -0,0 +1,20 @@ +{ + "id": "no-frontend", + "name": "No Frontend", + "version": "0.0.1", + "description": "Plugin template with no frontend", + "author": { + "name": "Caido Labs Inc.", + "email": "dev@caido.io", + "url": "https://github.com/caido-community/create-plugin/tree/main/templates/no-frontend" + }, + "plugins": [ + { + "kind": "backend", + "id": "backend", + "name": "Backend", + "runtime": "javascript", + "entrypoint": "backend/script.js" + } + ] +} diff --git a/templates/no-frontend/package.json b/templates/no-frontend/package.json new file mode 100644 index 0000000..66b0390 --- /dev/null +++ b/templates/no-frontend/package.json @@ -0,0 +1,18 @@ +{ + "name": "no-frontend", + "version": "0.0.1", + "description": "Plugin package template with no frontend", + "author": "Caido Labs Inc. ", + "license": "CC0-1.0", + "type": "module", + "scripts": { + "typecheck": "pnpm -r typecheck", + "build": "node scripts/clean.js && pnpm -r build && node scripts/pack.js" + }, + "devDependencies": { + "@caido/plugin-manifest": "0.1.3", + "jszip": "3.10.1", + "typescript": "5.5.4", + "vite": "5.2.7" + } +} diff --git a/templates/no-frontend/packages/backend/package.json b/templates/no-frontend/packages/backend/package.json new file mode 100644 index 0000000..19b032d --- /dev/null +++ b/templates/no-frontend/packages/backend/package.json @@ -0,0 +1,13 @@ +{ + "name": "backend", + "version": "0.0.0", + "type": "module", + "types": "src/index.ts", + "scripts": { + "typecheck": "tsc --noEmit", + "build": "vite build" + }, + "devDependencies": { + "@caido/sdk-backend": "0.42.0" + } +} diff --git a/templates/no-frontend/packages/backend/src/index.ts b/templates/no-frontend/packages/backend/src/index.ts new file mode 100644 index 0000000..70b1abc --- /dev/null +++ b/templates/no-frontend/packages/backend/src/index.ts @@ -0,0 +1,15 @@ +import type { DefineAPI, SDK } from "caido:plugin"; + +const generateRandomString = (sdk: SDK, length: number) => { + const randomString = Math.random().toString(36).substring(2, length + 2); + sdk.console.log(`Generating random string: ${randomString}`); + return randomString; +} + +export type API = DefineAPI<{ + generateRandomString: typeof generateRandomString; +}>; + +export function init(sdk: SDK) { + sdk.api.register("generateRandomString", generateRandomString); +} diff --git a/templates/no-frontend/packages/backend/tsconfig.json b/templates/no-frontend/packages/backend/tsconfig.json new file mode 100644 index 0000000..9dec401 --- /dev/null +++ b/templates/no-frontend/packages/backend/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "types": ["@caido/sdk-backend"] + }, + "include": ["./src/**/*.ts"] +} diff --git a/templates/no-frontend/packages/backend/vite.config.ts b/templates/no-frontend/packages/backend/vite.config.ts new file mode 100644 index 0000000..1631618 --- /dev/null +++ b/templates/no-frontend/packages/backend/vite.config.ts @@ -0,0 +1,21 @@ +import { defineConfig } from "vite"; +import { resolve } from "path"; +import { builtinModules } from "module"; + +export default defineConfig({ + build: { + lib: { + entry: resolve(__dirname, "src/index.ts"), + name: "plugin-template-backend", + fileName: (format) => "script.js", + formats: ["es"], + }, + outDir: "../../dist/backend", + rollupOptions: { + external: [/caido:.+/, ...builtinModules], + output: { + manualChunks: undefined, + }, + }, + }, +}); diff --git a/templates/no-frontend/pnpm-workspace.yaml b/templates/no-frontend/pnpm-workspace.yaml new file mode 100644 index 0000000..18ec407 --- /dev/null +++ b/templates/no-frontend/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - 'packages/*' diff --git a/templates/no-frontend/scripts/clean.js b/templates/no-frontend/scripts/clean.js new file mode 100644 index 0000000..37a581c --- /dev/null +++ b/templates/no-frontend/scripts/clean.js @@ -0,0 +1,8 @@ +import fs from "fs"; +import path from "path"; +import { fileURLToPath } from "url"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const DIST = path.join(__dirname, "../dist"); + +fs.rmSync(DIST, { recursive: true, force: true }); diff --git a/templates/no-frontend/scripts/pack.js b/templates/no-frontend/scripts/pack.js new file mode 100644 index 0000000..f0bb127 --- /dev/null +++ b/templates/no-frontend/scripts/pack.js @@ -0,0 +1,55 @@ +import JSZip from "jszip"; +import fs from "fs"; +import path from "path"; +import { fileURLToPath } from "url"; +import { validateManifest } from "@caido/plugin-manifest"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const DIST = path.resolve(__dirname, "../dist"); + +/** + * @param {string} dirPath + * @param {JSZip} zipFolder + */ +function addDirToZip(dirPath, zipFolder) { + const files = fs.readdirSync(dirPath); + files.forEach((file) => { + const filePath = path.join(dirPath, file); + const fileStat = fs.statSync(filePath); + if (fileStat.isDirectory()) { + const newZipFolder = zipFolder.folder(file); + addDirToZip(filePath, newZipFolder); + } else { + const fileContents = fs.readFileSync(filePath); + zipFolder.file(file, fileContents); + } + }); +} + +console.log("[*] Copying manifest file"); +const srcManifestPath = path.resolve(__dirname, "../manifest.json"); +const destManifestPath = path.join(DIST, "manifest.json"); +const data = JSON.parse(fs.readFileSync(srcManifestPath, "utf-8")); +if (!validateManifest(data)) { + process.exit(1); +} +fs.copyFileSync(srcManifestPath, destManifestPath); + +console.log("[*] Creating zip"); +const zip = new JSZip(); + +addDirToZip(DIST, zip); + +const zipPath = path.join(DIST, "plugin_package.zip"); +zip + .generateAsync({ + type: "nodebuffer", + compression: "DEFLATE", + compressionOptions: { + level: 9, + }, + }) + .then((content) => { + fs.writeFileSync(zipPath, content); + }) + .catch((err) => console.error("[-] Error creating zip:", err)); diff --git a/templates/no-frontend/tsconfig.json b/templates/no-frontend/tsconfig.json new file mode 100644 index 0000000..f986f70 --- /dev/null +++ b/templates/no-frontend/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "esnext", + "module": "esnext", + "lib": ["ESNext"], + + "jsx": "preserve", + "noImplicitAny": true, + "noUncheckedIndexedAccess": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true, + + "moduleResolution": "bundler", + "esModuleInterop": true, + "sourceMap": true, + "noUnusedLocals": true, + + "useDefineForClassFields": true, + "isolatedModules": true, + + "baseUrl": "." + } +}