From 03207ea7b684ec1a590e73e251b5ce1f3bb8c58a Mon Sep 17 00:00:00 2001 From: Pive01 Date: Tue, 25 Jun 2024 14:51:27 +0200 Subject: [PATCH 01/35] Created first raw version of react extension --- template/{ => react}/README.md | 2 +- template/{ => react}/cookiecutter.json | 0 .../{{cookiecutter.project_slug}}/Makefile | 13 ++- .../{{cookiecutter.project_slug}}/README.md | 0 .../{{cookiecutter.project_slug}}/setup.cfg | 19 +++- .../{{cookiecutter.project_slug}}/setup.py | 0 .../{{cookiecutter.project_slug}}/utf8_fail | 28 +++++ .../{{cookiecutter.module_name}}/__init__.py | 0 .../backend/web.py | 0 .../{{cookiecutter.module_name}}/extension.py | 44 ++++++++ .../frontend/.esbuild/esbuild.config.js | 102 ++++++++++++++++++ .../frontend/.esbuild/esbuild.shims.js | 7 ++ .../frontend/.esbuild/index.js | 11 ++ .../frontend/.esbuild/plugins/html/index.js | 93 ++++++++++++++++ .../frontend/__init__.py | 0 .../frontend/package.json | 37 +++++++ .../frontend/public/index.html | 43 ++++++++ .../frontend/public/manifest.json | 25 +++++ .../frontend/public/robots.txt | 3 + .../frontend/src/CustomRoutes.tsx | 12 +++ .../frontend/src/Dashboard.tsx | 17 +++ .../frontend/src/PageOne.tsx | 16 +++ .../frontend/src/index.css | 13 +++ .../frontend/src/index.html | 21 ++++ .../frontend/src/index.tsx | 19 ++++ .../frontend/src/react-app-env.d.ts | 1 + .../{{cookiecutter.module_name}}/util.py | 51 +++++++++ .../{{cookiecutter.module_name}}/extension.py | 22 ---- 28 files changed, 572 insertions(+), 27 deletions(-) rename template/{ => react}/README.md (87%) rename template/{ => react}/cookiecutter.json (100%) rename template/{ => react}/{{cookiecutter.project_slug}}/Makefile (63%) rename template/{ => react}/{{cookiecutter.project_slug}}/README.md (100%) rename template/{ => react}/{{cookiecutter.project_slug}}/setup.cfg (55%) rename template/{ => react}/{{cookiecutter.project_slug}}/setup.py (100%) create mode 100644 template/react/{{cookiecutter.project_slug}}/utf8_fail rename template/{ => react}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py (100%) create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.shims.js create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/index.js create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/plugins/html/index.js create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/__init__.py create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/index.html create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/manifest.json create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/robots.txt create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/CustomRoutes.tsx create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/Dashboard.tsx create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/PageOne.tsx create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.css create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.html create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/react-app-env.d.ts create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/util.py delete mode 100644 template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py diff --git a/template/README.md b/template/react/README.md similarity index 87% rename from template/README.md rename to template/react/README.md index 0213a57..ae0ce10 100644 --- a/template/README.md +++ b/template/react/README.md @@ -4,7 +4,7 @@ Extension Template This is a [cookiecutter](https://github.com/cookiecutter/cookiecutter) template that is used when you invoke. ```console -localstack extensions dev new +localstack extensions dev new --ui ``` It contains a simple python distribution config, and some boilerplate extension code. diff --git a/template/cookiecutter.json b/template/react/cookiecutter.json similarity index 100% rename from template/cookiecutter.json rename to template/react/cookiecutter.json diff --git a/template/{{cookiecutter.project_slug}}/Makefile b/template/react/{{cookiecutter.project_slug}}/Makefile similarity index 63% rename from template/{{cookiecutter.project_slug}}/Makefile rename to template/react/{{cookiecutter.project_slug}}/Makefile index 0f12f48..ad16da1 100644 --- a/template/{{cookiecutter.project_slug}}/Makefile +++ b/template/react/{{cookiecutter.project_slug}}/Makefile @@ -2,6 +2,7 @@ VENV_BIN = python3 -m venv VENV_DIR ?= .venv VENV_ACTIVATE = $(VENV_DIR)/bin/activate VENV_RUN = . $(VENV_ACTIVATE) +WEB_LOCATION_PREFIX = /_localstack/{{cookiecutter.module_name}}/ venv: $(VENV_ACTIVATE) @@ -17,10 +18,18 @@ clean: rm -rf .eggs/ rm -rf *.egg-info/ -install: venv +install-backend: venv $(VENV_RUN); python setup.py develop -dist: venv +install-frontend: venv + cd {{cookiecutter.module_name}}/frontend && yarn install + +build-frontend: + cd {{cookiecutter.module_name}}/frontend; rm -rf build && WEB_LOCATION_PREFIX=$(WEB_LOCATION_PREFIX) npm run build + +install: venv install-backend install-frontend + +dist: venv build-frontend $(VENV_RUN); python setup.py sdist bdist_wheel publish: clean-dist venv dist diff --git a/template/{{cookiecutter.project_slug}}/README.md b/template/react/{{cookiecutter.project_slug}}/README.md similarity index 100% rename from template/{{cookiecutter.project_slug}}/README.md rename to template/react/{{cookiecutter.project_slug}}/README.md diff --git a/template/{{cookiecutter.project_slug}}/setup.cfg b/template/react/{{cookiecutter.project_slug}}/setup.cfg similarity index 55% rename from template/{{cookiecutter.project_slug}}/setup.cfg rename to template/react/{{cookiecutter.project_slug}}/setup.cfg index 2bb3f02..0477963 100644 --- a/template/{{cookiecutter.project_slug}}/setup.cfg +++ b/template/react/{{cookiecutter.project_slug}}/setup.cfg @@ -13,8 +13,23 @@ long_description_content_type = text/markdown; charset=UTF-8 zip_safe = False packages = find: install_requires = - localstack>=1.0 - + localstack>=2.2 + localstack-core + localstack-ext + werkzeug + flask + rolo + [options.entry_points] localstack.extensions = {{ cookiecutter.project_slug }} = {{ cookiecutter.module_name }}.extension:MyExtension + +[options.package_data] +{{ cookiecutter.project_slug }} = + {{ cookiecutter.module_name }}/frontend/build/*.html + {{ cookiecutter.module_name }}/frontend/build/*.js + {{ cookiecutter.module_name }}/frontend/build/*.js.map + {{ cookiecutter.module_name }}/frontend/build/*.png + {{ cookiecutter.module_name }}/frontend/build/*.css + {{ cookiecutter.module_name }}/frontend/build/*.css.map + {{ cookiecutter.module_name }}/frontend/build/*.json diff --git a/template/{{cookiecutter.project_slug}}/setup.py b/template/react/{{cookiecutter.project_slug}}/setup.py similarity index 100% rename from template/{{cookiecutter.project_slug}}/setup.py rename to template/react/{{cookiecutter.project_slug}}/setup.py diff --git a/template/react/{{cookiecutter.project_slug}}/utf8_fail b/template/react/{{cookiecutter.project_slug}}/utf8_fail new file mode 100644 index 0000000..3930e7f --- /dev/null +++ b/template/react/{{cookiecutter.project_slug}}/utf8_fail @@ -0,0 +1,28 @@ +./{{cookiecutter.module_name}}/frontend/.git/index +./{{cookiecutter.module_name}}/frontend/.git/objects/74/b5e053450a48a6bdb4d71aad648e7af821975c +./{{cookiecutter.module_name}}/frontend/.git/objects/9d/fc1c058cebbef8b891c5062be6f31033d7d186 +./{{cookiecutter.module_name}}/frontend/.git/objects/8f/2609b7b3e0e3897ab3bcaad13caf6876e48699 +./{{cookiecutter.module_name}}/frontend/.git/objects/a5/3698aab3c66049c61980112dd0109dd2cd0845 +./{{cookiecutter.module_name}}/frontend/.git/objects/49/a2a16e0fbc7636ee16bf907257a5282b856493 +./{{cookiecutter.module_name}}/frontend/.git/objects/e9/e57dc4d41b9b46e05112e9f45b7ea6ac0ba15e +./{{cookiecutter.module_name}}/frontend/.git/objects/2a/68616d9846ed7d3bfb9f28ca1eb4d51b2c2f84 +./{{cookiecutter.module_name}}/frontend/.git/objects/ec/2585e8c0bb8188184ed1e0703c4c8f2a8419b0 +./{{cookiecutter.module_name}}/frontend/.git/objects/4d/29575de80483b005c29bfcac5061cd2f45313e +./{{cookiecutter.module_name}}/frontend/.git/objects/08/0d6c77ac21bb2ef88a6992b2b73ad93daaca92 +./{{cookiecutter.module_name}}/frontend/.git/objects/a1/1777cc471a4344702741ab1c8a588998b1311a +./{{cookiecutter.module_name}}/frontend/.git/objects/03/2464fb6ec40a523899b8c8a593242f3108a420 +./{{cookiecutter.module_name}}/frontend/.git/objects/64/31bc5fc6b2c932dfe5d0418fc667b86c18b9fc +./{{cookiecutter.module_name}}/frontend/.git/objects/8e/29b36dea7f04ae8729d8b33ecc05c3c9b0fe46 +./{{cookiecutter.module_name}}/frontend/.git/objects/13/b31acae787d809ccb930cb109be523fd3d5d2b +./{{cookiecutter.module_name}}/frontend/.git/objects/19/50edfd6c40f283a255c45d6a9737cdbf7a4ac9 +./{{cookiecutter.module_name}}/frontend/.git/objects/b8/7cb00449efa5b6131f56b7e45cc63eddf37373 +./{{cookiecutter.module_name}}/frontend/.git/objects/7f/f18e5bf7ad6a79c120ab2c3759ca4f5826e7a5 +./{{cookiecutter.module_name}}/frontend/.git/objects/7f/3d46d66f77670c0bd362bd37f4e593a67fe1e6 +./{{cookiecutter.module_name}}/frontend/.git/objects/a4/e47a6545bc15971f8f63fba70e4013df88a664 +./{{cookiecutter.module_name}}/frontend/.git/objects/fc/44b0a3796c0e0a64c3d858ca038bd4570465d9 +./{{cookiecutter.module_name}}/frontend/.git/objects/a2/73b0cfc0e965c35524e3cd0d3574cbe1ad2d0d +./{{cookiecutter.module_name}}/frontend/.git/objects/39/af63c4854e72b9d665ea4053f818a15abf01aa +./{{cookiecutter.module_name}}/frontend/.git/objects/aa/069f27cbd9d53394428171c3989fd03db73c76 +./{{cookiecutter.module_name}}/frontend/public/logo192.png +./{{cookiecutter.module_name}}/frontend/public/favicon.ico +./{{cookiecutter.module_name}}/frontend/public/logo512.png diff --git a/template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py similarity index 100% rename from template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py rename to template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py new file mode 100644 index 0000000..e69de29 diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py new file mode 100644 index 0000000..1672c21 --- /dev/null +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py @@ -0,0 +1,44 @@ +import logging + +from localstack.extensions.api import Extension, http, aws + +from localstack.services.internal import get_internal_apis +from localstack import config + +from react_test.backend.web import WebApp + +from .util import Routes, Subdomain, Submount + +LOG = logging.getLogger(__name__) + +class MyExtension(Extension): + name = "{{ cookiecutter.project_slug }}" + + def on_extension_load(self): + print("MyExtension: extension is loaded") + + def on_platform_start(self): + print("MyExtension: localstack is starting") + + def on_platform_ready(self): + print("MyExtension: localstack is running") + + def update_gateway_routes(self, router: http.Router[http.RouteHandler]): + LOG.info("Adding route for %s", self.name) + + get_internal_apis().add(WebApp()) + from localstack.aws.handlers.cors import ALLOWED_CORS_ORIGINS + + webapp = Routes(WebApp()) + + ALLOWED_CORS_ORIGINS.append(f"http://{self.name}.{config.LOCALSTACK_HOST}") + ALLOWED_CORS_ORIGINS.append(f"https://{self.name}.{config.LOCALSTACK_HOST}") + + router.add(Submount(f"/{self.name}", webapp)) + router.add(Subdomain(f"{self.name}", webapp)) + + def update_request_handlers(self, handlers: aws.CompositeHandler): + pass + + def update_response_handlers(self, handlers: aws.CompositeResponseHandler): + pass diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js new file mode 100644 index 0000000..3c42058 --- /dev/null +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js @@ -0,0 +1,102 @@ +/* eslint-disable global-require */ + +const esbuild = require('esbuild'); +const path = require('path'); + +const SvgrPlugin = require('esbuild-plugin-svgr'); +const CopyPlugin = require('esbuild-plugin-copy').default; +const CleanPlugin = require('esbuild-plugin-clean').default; +const { NodeModulesPolyfillPlugin } = require('@esbuild-plugins/node-modules-polyfill'); + +const packageJson = require('../package.json'); +const HtmlPlugin = require('./plugins/html'); + +const CURRENT_ENV = process.env.NODE_ENV || 'development.local'; +const BUILD_PATH = path.join(__dirname, '..', 'build'); +const WEB_LOCATION_PREFIX = process.env.WEB_LOCATION_PREFIX; + +// Load .env.* file depending on the active environment +require('dotenv').config({ path: `.env.${CURRENT_ENV}` }); + +const BUILD_CONFIG = { + entryPoints: [ + path.join(__dirname, '..', 'src', 'index.tsx'), + path.join(__dirname, '..', 'src', 'index.html'), + ], + assetNames: '[name]-[hash]', + entryNames: '[name]-[hash]', + outdir: BUILD_PATH, + bundle: true, + minify: !CURRENT_ENV.includes('development.local'), + sourcemap: true, + target: 'es2015', + metafile: true, + // splitting: true, + // set in case file loader is added below + plugins: [ + CleanPlugin({ + patterns: [`${BUILD_PATH}/*`, `!${BUILD_PATH}/index.html`], + sync: true, + verbose: false + }), + SvgrPlugin({ + prettier: false, + svgo: false, + svgoConfig: { + plugins: [{ removeViewBox: false }], + }, + titleProp: true, + ref: true, + }), + CopyPlugin({ + copyOnStart: true, + // https://github.com/LinbuduLab/nx-plugins/issues/57 + assets: [ + { + from: ['./public/*'], + to: ['./'], + }, + ], + }), + NodeModulesPolyfillPlugin(), + HtmlPlugin({ + prefix: WEB_LOCATION_PREFIX, + filename: path.join(BUILD_PATH, 'index.html'), + env: true, + }), + ], + inject: [path.join(__dirname, 'esbuild.shims.js')], + define: { + // Define replacements for env vars starting with `REACT_APP_` + ...Object.entries(process.env).reduce( + (memo, [name, value]) => name.startsWith('REACT_APP_') ? + { ...memo, [`process.env.${name}`]: JSON.stringify(value) } : + memo, + {}, + ), + 'process.cwd': 'dummyProcessCwd', + 'process.env.PUBLIC_URL': '""', // empty for now to point to the root + 'process.env.BASE_PATH': '"/"', + 'process.env.NODE_ENV': JSON.stringify(CURRENT_ENV), + global: 'window', + }, + external: [ + ...Object.keys(packageJson.devDependencies || {}), + ], + loader: { + '.md': 'text', + '.gif': 'dataurl', + } +}; + +const build = async (overrides = {}) => { + try { + await esbuild.build({ ...BUILD_CONFIG, ...overrides }); + console.log('done building'); + } catch (e) { + console.error(e); + process.exit(1); + } +}; + +module.exports = { build }; diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.shims.js b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.shims.js new file mode 100644 index 0000000..c44743a --- /dev/null +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.shims.js @@ -0,0 +1,7 @@ +import * as React from 'react'; + +export { React }; + +export function dummyProcessCwd() { + return ''; +}; diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/index.js b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/index.js new file mode 100644 index 0000000..66a0005 --- /dev/null +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/index.js @@ -0,0 +1,11 @@ +const { build, serve } = require('./esbuild.config'); + +(async () => { + if (process.argv.includes('--serve')) { + await serve(); + } else if (process.argv.includes('--watch')) { + await build({ watch: true }); + } else { + await build(); + } +})(); diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/plugins/html/index.js b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/plugins/html/index.js new file mode 100644 index 0000000..ec65ab6 --- /dev/null +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/plugins/html/index.js @@ -0,0 +1,93 @@ +const fs = require('fs'); +const path = require('path'); +const crypto = require('crypto'); + +/** + * @param {object} config + * @param {string} config.filename - HTML file to process and override + * @param {boolean} config.env - Whether to replace env vars or not (default - `false`) + * @param {string} config.envPrefix - Limit env vars to pick (default - `REACT_APP_`) + * @param {string} config.prefix - prefix to add to the links + */ +const HtmlPlugin = (config) => ({ + name: 'html', + setup(build) { + build.onResolve({ filter: /\.html$/ }, args => ({ + path: path.resolve(args.resolveDir, args.path), + namespace: 'html', + })); + build.onLoad({ filter: /.html/, namespace: 'html' }, (args) => { + let htmlContent = fs.readFileSync(args.path).toString('utf-8'); + + // replace env vars + if (config.env) { + const envPrefix = config.envPrefix || 'REACT_APP_'; + const envVars = Object.entries(process.env || {}).filter(([name]) => name.startsWith(envPrefix)); + htmlContent = envVars.reduce( + (memo, [name, value]) => memo.replace(new RegExp(`%${name}%`, 'igm'), value), + htmlContent, + ); + } + + return { + contents: htmlContent, + loader: 'file' + }; + }); + + build.onEnd((result) => { + const outFiles = Object.keys((result.metafile || {}).outputs); + const jsFiles = outFiles.filter((p) => p.endsWith('.js')); + const cssFiles = outFiles.filter((p) => p.endsWith('.css')); + const htmlFiles = outFiles.filter((p) => p.endsWith('.html')); + + const headerAppends = cssFiles.reduce( + (memo, p) => { + const filename = p.split(path.sep).slice(-1)[0]; + return [...memo, ``]; + }, + [], + ); + + const preHeadersAppend = [] + if (config.prefix) { + preHeadersAppend.push( + `` + ) + } + + const bodyAppends = jsFiles.reduce( + (memo, p) => { + const filename = p.split(path.sep).slice(-1)[0]; + return [...memo, ``]; + }, + [], + ); + + for (const htmlFile of htmlFiles) { + let htmlContent = fs.readFileSync(htmlFile).toString('utf-8'); + + // replace env vars + if (config.env) { + const envPrefix = config.envPrefix || 'REACT_APP_'; + const envVars = Object.entries(process.env).filter(([name]) => name.startsWith(envPrefix)); + + htmlContent = envVars.reduce( + (memo, [name, value]) => memo.replace(new RegExp(`%${name}%`, 'igm'), value), + htmlContent, + ); + } + + // inject references to js and css files + htmlContent = htmlContent + .replace('', ['', ...preHeadersAppend].join("\n")) + .replace('', [...headerAppends, ''].join("\n")) + .replace('', [...bodyAppends, ''].join("\n")); + + fs.writeFileSync(config.filename.replace('-[^.]+', ''), htmlContent); + } + }); + }, +}); + +module.exports = HtmlPlugin; diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/__init__.py b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json new file mode 100644 index 0000000..d409dfb --- /dev/null +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json @@ -0,0 +1,37 @@ +{ + "name": "frontend", + "version": "0.1.0", + "private": true, + "dependencies": { + "@emotion/react": "^11.11.4", + "@emotion/styled": "^11.11.5", + "@mui/material": "^5.15.20", + "@testing-library/react": "^13.4.0", + "@types/node": "^16.18.99", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-router-dom": "^6.24.0", + "react-scripts": "5.0.1", + "typescript": "^4.9.5" + }, + "devDependencies": { + "@esbuild-plugins/node-modules-polyfill": "^0.1.4", + "esbuild": "^0.16.6", + "esbuild-envfile-plugin": "^1.0.2", + "esbuild-plugin-clean": "^1.0.1", + "esbuild-plugin-copy": "^0.3.0", + "esbuild-plugin-svgr": "^1.0.0" + }, + "scripts": { + "start": "concurrently --restart-tries -1 --raw \"yarn serve\" \"yarn watch\"", + "watch": "node .esbuild --watch", + "build": "node .esbuild" + }, + "eslintConfig": { + "extends": [ + "react-app" + ] + } +} diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/index.html b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/index.html new file mode 100644 index 0000000..aa069f2 --- /dev/null +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/index.html @@ -0,0 +1,43 @@ + + + + + + + + + + + + + React App + + + +
+ + + diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/manifest.json b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/manifest.json new file mode 100644 index 0000000..080d6c7 --- /dev/null +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/manifest.json @@ -0,0 +1,25 @@ +{ + "short_name": "React App", + "name": "Create React App Sample", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "logo192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/robots.txt b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/robots.txt new file mode 100644 index 0000000..e9e57dc --- /dev/null +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/CustomRoutes.tsx b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/CustomRoutes.tsx new file mode 100644 index 0000000..280dbf7 --- /dev/null +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/CustomRoutes.tsx @@ -0,0 +1,12 @@ +import { ReactElement } from "react"; +import { Navigate, Route, Routes } from "react-router-dom"; +import { PageOne } from "./PageOne"; +import { Dashboard } from "./Dashboard"; + +export const CustomRoutes = (): ReactElement => ( + + } /> + } path="/dashboard" /> + } path="/one" /> + +) \ No newline at end of file diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/Dashboard.tsx b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/Dashboard.tsx new file mode 100644 index 0000000..a4fa84f --- /dev/null +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/Dashboard.tsx @@ -0,0 +1,17 @@ +import { Button } from '@mui/material'; +import React from 'react'; +import { useNavigate } from 'react-router-dom'; + +export const Dashboard = () => { + const navigate = useNavigate(); + + return ( + <> + Dashboard + + + ); +} + diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/PageOne.tsx b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/PageOne.tsx new file mode 100644 index 0000000..bf72481 --- /dev/null +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/PageOne.tsx @@ -0,0 +1,16 @@ +import { Button } from "@mui/material"; +import { ReactElement } from "react"; +import { useNavigate } from "react-router-dom"; + +export const PageOne = (): ReactElement => { + const navigate = useNavigate(); + + return ( + <> + Page One + + + ); +} \ No newline at end of file diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.css b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.css new file mode 100644 index 0000000..ec2585e --- /dev/null +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.css @@ -0,0 +1,13 @@ +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', + monospace; +} diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.html b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.html new file mode 100644 index 0000000..4914d10 --- /dev/null +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.html @@ -0,0 +1,21 @@ + + + + + + + + + LocalStack Extension + + + + + + + + +
+ + + \ No newline at end of file diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx new file mode 100644 index 0000000..092a6bc --- /dev/null +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import './index.css'; +import { CustomRoutes } from './CustomRoutes'; +import { BrowserRouter } from 'react-router-dom'; + +const root = ReactDOM.createRoot( + document.getElementById('root') as HTMLElement +); +const BASE_PATH = '/_localstack/{{cookiecutter.module_name}}'; + +root.render( + + + + + +); + diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/react-app-env.d.ts b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/react-app-env.d.ts new file mode 100644 index 0000000..6431bc5 --- /dev/null +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/react-app-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/util.py b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/util.py new file mode 100644 index 0000000..f6ffb36 --- /dev/null +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/util.py @@ -0,0 +1,51 @@ +from typing import Any, Iterable + +from localstack.http import Router + +from werkzeug.routing import ( + RuleFactory, + Map, + Rule, + Submount as WerkzeugSubmount, + Subdomain as WerkzeugSubdomain, +) + + +class Subdomain(WerkzeugSubdomain): + def __init__( + self, + subdomain: str, + rules: RuleFactory | Iterable[RuleFactory], + use_host_pattern: bool = True, + ): + super().__init__( + subdomain, [rules] if isinstance(rules, RuleFactory) else rules + ) + self.use_host_pattern = use_host_pattern + + def get_rules(self, map: Map) -> Iterable[Rule]: + if not self.use_host_pattern: + return super().get_rules(map) + + for rule in super().get_rules(map): + rule.host = f"{self.subdomain}.<__host__>" + yield rule + + +class Submount(WerkzeugSubmount): + def __init__(self, path: str, rules: RuleFactory | Iterable[RuleFactory]) -> None: + super().__init__(path, [rules] if isinstance(rules, RuleFactory) else rules) + + +class Routes(RuleFactory): + """ + Wraps an object that uses @route decorators ase a RuleFactory that can be added to a router. + """ + + def __init__(self, obj: Any): + self.obj = obj + + def get_rules(self, map: Map) -> Iterable[Rule]: + router = Router() # type: ignore + router.add(self.obj) + return router.url_map._rules \ No newline at end of file diff --git a/template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py b/template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py deleted file mode 100644 index b833617..0000000 --- a/template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py +++ /dev/null @@ -1,22 +0,0 @@ -from localstack.extensions.api import Extension, http, aws - -class MyExtension(Extension): - name = "{{ cookiecutter.project_slug }}" - - def on_extension_load(self): - print("MyExtension: extension is loaded") - - def on_platform_start(self): - print("MyExtension: localstack is starting") - - def on_platform_ready(self): - print("MyExtension: localstack is running") - - def update_gateway_routes(self, router: http.Router[http.RouteHandler]): - pass - - def update_request_handlers(self, handlers: aws.CompositeHandler): - pass - - def update_response_handlers(self, handlers: aws.CompositeResponseHandler): - pass From a835f75b1e56e4abc45cd7bb51d4d7f76f5ab465 Mon Sep 17 00:00:00 2001 From: Pive01 Date: Tue, 25 Jun 2024 14:54:01 +0200 Subject: [PATCH 02/35] re-added previous template --- template/default/README.md | 10 ++++++ template/default/cookiecutter.json | 10 ++++++ .../{{cookiecutter.project_slug}}/Makefile | 32 +++++++++++++++++ .../{{cookiecutter.project_slug}}/README.md | 34 +++++++++++++++++++ .../{{cookiecutter.project_slug}}/setup.cfg | 20 +++++++++++ .../{{cookiecutter.project_slug}}/setup.py | 4 +++ .../{{cookiecutter.module_name}}/__init__.py | 1 + .../{{cookiecutter.module_name}}/extension.py | 22 ++++++++++++ 8 files changed, 133 insertions(+) create mode 100644 template/default/README.md create mode 100644 template/default/cookiecutter.json create mode 100644 template/default/{{cookiecutter.project_slug}}/Makefile create mode 100644 template/default/{{cookiecutter.project_slug}}/README.md create mode 100644 template/default/{{cookiecutter.project_slug}}/setup.cfg create mode 100644 template/default/{{cookiecutter.project_slug}}/setup.py create mode 100644 template/default/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py create mode 100644 template/default/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py diff --git a/template/default/README.md b/template/default/README.md new file mode 100644 index 0000000..0213a57 --- /dev/null +++ b/template/default/README.md @@ -0,0 +1,10 @@ +Extension Template +================== + +This is a [cookiecutter](https://github.com/cookiecutter/cookiecutter) template that is used when you invoke. + +```console +localstack extensions dev new +``` + +It contains a simple python distribution config, and some boilerplate extension code. diff --git a/template/default/cookiecutter.json b/template/default/cookiecutter.json new file mode 100644 index 0000000..3d91d41 --- /dev/null +++ b/template/default/cookiecutter.json @@ -0,0 +1,10 @@ +{ + "project_name": "My LocalStack Extension", + "project_short_description": "All the boilerplate you need to create a LocalStack extension.", + "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '-') }}", + "module_name": "{{ cookiecutter.project_slug.replace('-', '_') }}", + "full_name": "Jane Doe", + "email": "jane@example.com", + "github_username": "janedoe", + "version": "0.1.0" +} \ No newline at end of file diff --git a/template/default/{{cookiecutter.project_slug}}/Makefile b/template/default/{{cookiecutter.project_slug}}/Makefile new file mode 100644 index 0000000..0f12f48 --- /dev/null +++ b/template/default/{{cookiecutter.project_slug}}/Makefile @@ -0,0 +1,32 @@ +VENV_BIN = python3 -m venv +VENV_DIR ?= .venv +VENV_ACTIVATE = $(VENV_DIR)/bin/activate +VENV_RUN = . $(VENV_ACTIVATE) + +venv: $(VENV_ACTIVATE) + +$(VENV_ACTIVATE): setup.py setup.cfg + test -d .venv || $(VENV_BIN) .venv + $(VENV_RUN); pip install --upgrade pip setuptools plux + $(VENV_RUN); pip install -e . + touch $(VENV_DIR)/bin/activate + +clean: + rm -rf .venv/ + rm -rf build/ + rm -rf .eggs/ + rm -rf *.egg-info/ + +install: venv + $(VENV_RUN); python setup.py develop + +dist: venv + $(VENV_RUN); python setup.py sdist bdist_wheel + +publish: clean-dist venv dist + $(VENV_RUN); pip install --upgrade twine; twine upload dist/* + +clean-dist: clean + rm -rf dist/ + +.PHONY: clean clean-dist dist install publish diff --git a/template/default/{{cookiecutter.project_slug}}/README.md b/template/default/{{cookiecutter.project_slug}}/README.md new file mode 100644 index 0000000..7240972 --- /dev/null +++ b/template/default/{{cookiecutter.project_slug}}/README.md @@ -0,0 +1,34 @@ +{{ cookiecutter.project_name }} +=============================== + +{{ cookiecutter.project_short_description }} + +## Install local development version + +To install the extension into localstack in developer mode, you will need Python 3.10, and create a virtual environment in the extensions project. + +In the newly generated project, simply run + +```bash +make install +``` + +Then, to enable the extension for LocalStack, run + +```bash +localstack extensions dev enable . +``` + +You can then start LocalStack with `EXTENSION_DEV_MODE=1` to load all enabled extensions: + +```bash +EXTENSION_DEV_MODE=1 localstack start +``` + +## Install from GitHub repository + +To distribute your extension, simply upload it to your github account. Your extension can then be installed via: + +```bash +localstack extensions install "git+https://github.com/{{cookiecutter.github_username }}/{{ cookiecutter.project_slug }}/#egg={{ cookiecutter.project_slug }}" +``` diff --git a/template/default/{{cookiecutter.project_slug}}/setup.cfg b/template/default/{{cookiecutter.project_slug}}/setup.cfg new file mode 100644 index 0000000..2bb3f02 --- /dev/null +++ b/template/default/{{cookiecutter.project_slug}}/setup.cfg @@ -0,0 +1,20 @@ +[metadata] +name = {{ cookiecutter.project_slug }} +version = {{ cookiecutter.version }} +summary = LocalStack Extension: {{ cookiecutter.project_name }} +url = https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.project_slug }} +author = {{ cookiecutter.full_name }} +author_email = {{ cookiecutter.email }} +description = {{ cookiecutter.project_short_description }} +long_description = file: README.md +long_description_content_type = text/markdown; charset=UTF-8 + +[options] +zip_safe = False +packages = find: +install_requires = + localstack>=1.0 + +[options.entry_points] +localstack.extensions = + {{ cookiecutter.project_slug }} = {{ cookiecutter.module_name }}.extension:MyExtension diff --git a/template/default/{{cookiecutter.project_slug}}/setup.py b/template/default/{{cookiecutter.project_slug}}/setup.py new file mode 100644 index 0000000..c823345 --- /dev/null +++ b/template/default/{{cookiecutter.project_slug}}/setup.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python +from setuptools import setup + +setup() diff --git a/template/default/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py b/template/default/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py new file mode 100644 index 0000000..4b62a2f --- /dev/null +++ b/template/default/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py @@ -0,0 +1 @@ +name = "{{ cookiecutter.module_name }}" diff --git a/template/default/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py b/template/default/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py new file mode 100644 index 0000000..b833617 --- /dev/null +++ b/template/default/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py @@ -0,0 +1,22 @@ +from localstack.extensions.api import Extension, http, aws + +class MyExtension(Extension): + name = "{{ cookiecutter.project_slug }}" + + def on_extension_load(self): + print("MyExtension: extension is loaded") + + def on_platform_start(self): + print("MyExtension: localstack is starting") + + def on_platform_ready(self): + print("MyExtension: localstack is running") + + def update_gateway_routes(self, router: http.Router[http.RouteHandler]): + pass + + def update_request_handlers(self, handlers: aws.CompositeHandler): + pass + + def update_response_handlers(self, handlers: aws.CompositeResponseHandler): + pass From 83b452dfa9882f7d8823001d6811fefb4a098b23 Mon Sep 17 00:00:00 2001 From: Pive01 Date: Tue, 25 Jun 2024 15:53:38 +0200 Subject: [PATCH 03/35] Simply added anything in the build folder --- template/react/{{cookiecutter.project_slug}}/setup.cfg | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/template/react/{{cookiecutter.project_slug}}/setup.cfg b/template/react/{{cookiecutter.project_slug}}/setup.cfg index 0477963..3ad57c0 100644 --- a/template/react/{{cookiecutter.project_slug}}/setup.cfg +++ b/template/react/{{cookiecutter.project_slug}}/setup.cfg @@ -26,10 +26,4 @@ localstack.extensions = [options.package_data] {{ cookiecutter.project_slug }} = - {{ cookiecutter.module_name }}/frontend/build/*.html - {{ cookiecutter.module_name }}/frontend/build/*.js - {{ cookiecutter.module_name }}/frontend/build/*.js.map - {{ cookiecutter.module_name }}/frontend/build/*.png - {{ cookiecutter.module_name }}/frontend/build/*.css - {{ cookiecutter.module_name }}/frontend/build/*.css.map - {{ cookiecutter.module_name }}/frontend/build/*.json + {{ cookiecutter.module_name }}/frontend/build/* From 73d1e94bb3eb7849d0fd5cd07d8ab2ccd280576d Mon Sep 17 00:00:00 2001 From: Pive01 Date: Tue, 25 Jun 2024 16:11:11 +0200 Subject: [PATCH 04/35] Fixed missing files --- .../backend/web.py | 46 +++++++++++++++++++ .../{{cookiecutter.module_name}}/extension.py | 2 +- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py index e69de29..e8487f2 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py @@ -0,0 +1,46 @@ +import mimetypes +import os +from pathlib import Path + +from flask import redirect +from localstack.constants import ( + APPLICATION_OCTET_STREAM, + INTERNAL_RESOURCE_PATH, + LOCALHOST_HOSTNAME, +) +from localstack.http import route, Request, Response + +from {{cookiecutter.module_name}} import frontend as web_ui + + +DOMAIN_NAME = f"{{cookiecutter.module_name}}.{LOCALHOST_HOSTNAME}" +ROUTE_HOST = f"{DOMAIN_NAME}" + + +class WebApp: + @route("/", methods=["GET"], host=ROUTE_HOST) + def forward_from_root(self, request: Request, **kwargs): + return redirect(f"{INTERNAL_RESOURCE_PATH}/{{cookiecutter.module_name}}/dashboard") + + @route(f"{INTERNAL_RESOURCE_PATH}/{{cookiecutter.module_name}}", methods=["GET"]) + def forward_from_extension_root(self, request: Request, **kwargs): + return redirect(f"{INTERNAL_RESOURCE_PATH}/{{cookiecutter.module_name}}/index.html") + + @route(f"{INTERNAL_RESOURCE_PATH}/{{cookiecutter.module_name}}/", methods=["GET"]) + def get_web_asset(self, request: Request, path: str, **kwargs): + return self.serve_static_file(path) + + @route(f"{INTERNAL_RESOURCE_PATH}/{{cookiecutter.module_name}}/index.html", methods=["GET"]) + def serve_index_html(self, request: Request, **kwargs): + return self.serve_static_file("index.html") + + def serve_static_file(self, path: str): + build_dir = os.path.join(os.path.dirname(web_ui.__file__), "build") + file_path = os.path.join(build_dir, path.lstrip("/")) + + if not os.path.exists(file_path): + file_path = os.path.join(build_dir, "index.html") + + mime_type = mimetypes.guess_type(file_path)[0] or APPLICATION_OCTET_STREAM + + return Response(Path(file_path).open(mode="rb"), mimetype=mime_type) diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py index 1672c21..d1e827d 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py @@ -5,7 +5,7 @@ from localstack.services.internal import get_internal_apis from localstack import config -from react_test.backend.web import WebApp +from {{ cookiecutter.module_name }}.backend.web import WebApp from .util import Routes, Subdomain, Submount From db2e6833918932014870638f98ca819c41c40852 Mon Sep 17 00:00:00 2001 From: Pive01 Date: Tue, 25 Jun 2024 16:40:03 +0200 Subject: [PATCH 05/35] Simplified routing patterns --- template/react/{{cookiecutter.project_slug}}/Makefile | 3 +-- .../{{cookiecutter.module_name}}/backend/web.py | 5 +++++ .../frontend/.esbuild/esbuild.config.js | 2 -- .../frontend/.esbuild/plugins/html/index.js | 9 --------- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/template/react/{{cookiecutter.project_slug}}/Makefile b/template/react/{{cookiecutter.project_slug}}/Makefile index ad16da1..26b39b9 100644 --- a/template/react/{{cookiecutter.project_slug}}/Makefile +++ b/template/react/{{cookiecutter.project_slug}}/Makefile @@ -2,7 +2,6 @@ VENV_BIN = python3 -m venv VENV_DIR ?= .venv VENV_ACTIVATE = $(VENV_DIR)/bin/activate VENV_RUN = . $(VENV_ACTIVATE) -WEB_LOCATION_PREFIX = /_localstack/{{cookiecutter.module_name}}/ venv: $(VENV_ACTIVATE) @@ -25,7 +24,7 @@ install-frontend: venv cd {{cookiecutter.module_name}}/frontend && yarn install build-frontend: - cd {{cookiecutter.module_name}}/frontend; rm -rf build && WEB_LOCATION_PREFIX=$(WEB_LOCATION_PREFIX) npm run build + cd {{cookiecutter.module_name}}/frontend; rm -rf build && npm run build install: venv install-backend install-frontend diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py index e8487f2..6f7820d 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py @@ -15,6 +15,7 @@ DOMAIN_NAME = f"{{cookiecutter.module_name}}.{LOCALHOST_HOSTNAME}" ROUTE_HOST = f"{DOMAIN_NAME}" +EXTENSION_SUB_ROUTE = f"{ROUTE_HOST}{INTERNAL_RESOURCE_PATH}/{{cookiecutter.module_name}}" class WebApp: @@ -22,6 +23,10 @@ class WebApp: def forward_from_root(self, request: Request, **kwargs): return redirect(f"{INTERNAL_RESOURCE_PATH}/{{cookiecutter.module_name}}/dashboard") + @route("/", methods=["GET"], host=ROUTE_HOST) + def forward_custom_from_root(self, request: Request, path: str, **kwargs): + return self.serve_static_file(path) + @route(f"{INTERNAL_RESOURCE_PATH}/{{cookiecutter.module_name}}", methods=["GET"]) def forward_from_extension_root(self, request: Request, **kwargs): return redirect(f"{INTERNAL_RESOURCE_PATH}/{{cookiecutter.module_name}}/index.html") diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js index 3c42058..9d641ff 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js @@ -13,7 +13,6 @@ const HtmlPlugin = require('./plugins/html'); const CURRENT_ENV = process.env.NODE_ENV || 'development.local'; const BUILD_PATH = path.join(__dirname, '..', 'build'); -const WEB_LOCATION_PREFIX = process.env.WEB_LOCATION_PREFIX; // Load .env.* file depending on the active environment require('dotenv').config({ path: `.env.${CURRENT_ENV}` }); @@ -60,7 +59,6 @@ const BUILD_CONFIG = { }), NodeModulesPolyfillPlugin(), HtmlPlugin({ - prefix: WEB_LOCATION_PREFIX, filename: path.join(BUILD_PATH, 'index.html'), env: true, }), diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/plugins/html/index.js b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/plugins/html/index.js index ec65ab6..2161d8e 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/plugins/html/index.js +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/plugins/html/index.js @@ -7,7 +7,6 @@ const crypto = require('crypto'); * @param {string} config.filename - HTML file to process and override * @param {boolean} config.env - Whether to replace env vars or not (default - `false`) * @param {string} config.envPrefix - Limit env vars to pick (default - `REACT_APP_`) - * @param {string} config.prefix - prefix to add to the links */ const HtmlPlugin = (config) => ({ name: 'html', @@ -49,13 +48,6 @@ const HtmlPlugin = (config) => ({ [], ); - const preHeadersAppend = [] - if (config.prefix) { - preHeadersAppend.push( - `` - ) - } - const bodyAppends = jsFiles.reduce( (memo, p) => { const filename = p.split(path.sep).slice(-1)[0]; @@ -80,7 +72,6 @@ const HtmlPlugin = (config) => ({ // inject references to js and css files htmlContent = htmlContent - .replace('', ['', ...preHeadersAppend].join("\n")) .replace('', [...headerAppends, ''].join("\n")) .replace('', [...bodyAppends, ''].join("\n")); From 4936f16385ea87e24c5cbc8bb78d268ad0e7ccc7 Mon Sep 17 00:00:00 2001 From: Pive01 Date: Thu, 27 Jun 2024 13:48:19 +0200 Subject: [PATCH 06/35] updated template --- .../{{cookiecutter.project_slug}}/utf8_fail | 28 ---- .../frontend/.yarnrc.yml | 1 + .../frontend/package.json | 23 +-- .../frontend/public/favicon.png | Bin 0 -> 1598 bytes .../frontend/public/index.html | 43 ------ .../frontend/public/manifest.json | 14 +- .../frontend/src/Dashboard.tsx | 29 ++-- .../frontend/src/PageOne.tsx | 32 ++-- .../frontend/src/index.css | 141 +++++++++++++++++- .../frontend/src/index.html | 2 +- .../frontend/src/index.tsx | 13 +- .../frontend/src/react-app-env.d.ts | 1 - .../frontend/tsconfig.json | 43 ++++++ 13 files changed, 242 insertions(+), 128 deletions(-) delete mode 100644 template/react/{{cookiecutter.project_slug}}/utf8_fail create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.yarnrc.yml create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/favicon.png delete mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/index.html delete mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/react-app-env.d.ts create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/tsconfig.json diff --git a/template/react/{{cookiecutter.project_slug}}/utf8_fail b/template/react/{{cookiecutter.project_slug}}/utf8_fail deleted file mode 100644 index 3930e7f..0000000 --- a/template/react/{{cookiecutter.project_slug}}/utf8_fail +++ /dev/null @@ -1,28 +0,0 @@ -./{{cookiecutter.module_name}}/frontend/.git/index -./{{cookiecutter.module_name}}/frontend/.git/objects/74/b5e053450a48a6bdb4d71aad648e7af821975c -./{{cookiecutter.module_name}}/frontend/.git/objects/9d/fc1c058cebbef8b891c5062be6f31033d7d186 -./{{cookiecutter.module_name}}/frontend/.git/objects/8f/2609b7b3e0e3897ab3bcaad13caf6876e48699 -./{{cookiecutter.module_name}}/frontend/.git/objects/a5/3698aab3c66049c61980112dd0109dd2cd0845 -./{{cookiecutter.module_name}}/frontend/.git/objects/49/a2a16e0fbc7636ee16bf907257a5282b856493 -./{{cookiecutter.module_name}}/frontend/.git/objects/e9/e57dc4d41b9b46e05112e9f45b7ea6ac0ba15e -./{{cookiecutter.module_name}}/frontend/.git/objects/2a/68616d9846ed7d3bfb9f28ca1eb4d51b2c2f84 -./{{cookiecutter.module_name}}/frontend/.git/objects/ec/2585e8c0bb8188184ed1e0703c4c8f2a8419b0 -./{{cookiecutter.module_name}}/frontend/.git/objects/4d/29575de80483b005c29bfcac5061cd2f45313e -./{{cookiecutter.module_name}}/frontend/.git/objects/08/0d6c77ac21bb2ef88a6992b2b73ad93daaca92 -./{{cookiecutter.module_name}}/frontend/.git/objects/a1/1777cc471a4344702741ab1c8a588998b1311a -./{{cookiecutter.module_name}}/frontend/.git/objects/03/2464fb6ec40a523899b8c8a593242f3108a420 -./{{cookiecutter.module_name}}/frontend/.git/objects/64/31bc5fc6b2c932dfe5d0418fc667b86c18b9fc -./{{cookiecutter.module_name}}/frontend/.git/objects/8e/29b36dea7f04ae8729d8b33ecc05c3c9b0fe46 -./{{cookiecutter.module_name}}/frontend/.git/objects/13/b31acae787d809ccb930cb109be523fd3d5d2b -./{{cookiecutter.module_name}}/frontend/.git/objects/19/50edfd6c40f283a255c45d6a9737cdbf7a4ac9 -./{{cookiecutter.module_name}}/frontend/.git/objects/b8/7cb00449efa5b6131f56b7e45cc63eddf37373 -./{{cookiecutter.module_name}}/frontend/.git/objects/7f/f18e5bf7ad6a79c120ab2c3759ca4f5826e7a5 -./{{cookiecutter.module_name}}/frontend/.git/objects/7f/3d46d66f77670c0bd362bd37f4e593a67fe1e6 -./{{cookiecutter.module_name}}/frontend/.git/objects/a4/e47a6545bc15971f8f63fba70e4013df88a664 -./{{cookiecutter.module_name}}/frontend/.git/objects/fc/44b0a3796c0e0a64c3d858ca038bd4570465d9 -./{{cookiecutter.module_name}}/frontend/.git/objects/a2/73b0cfc0e965c35524e3cd0d3574cbe1ad2d0d -./{{cookiecutter.module_name}}/frontend/.git/objects/39/af63c4854e72b9d665ea4053f818a15abf01aa -./{{cookiecutter.module_name}}/frontend/.git/objects/aa/069f27cbd9d53394428171c3989fd03db73c76 -./{{cookiecutter.module_name}}/frontend/public/logo192.png -./{{cookiecutter.module_name}}/frontend/public/favicon.ico -./{{cookiecutter.module_name}}/frontend/public/logo512.png diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.yarnrc.yml b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.yarnrc.yml new file mode 100644 index 0000000..8b757b2 --- /dev/null +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.yarnrc.yml @@ -0,0 +1 @@ +nodeLinker: node-modules \ No newline at end of file diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json index d409dfb..4d74fc4 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json @@ -1,17 +1,18 @@ { - "name": "frontend", + "name": "{{cookiecutter.module_name}}", "version": "0.1.0", "private": true, + "license": "UNLICENSED", "dependencies": { "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", + "@localstack/theme": "git+ssh://git@github.com/localstack/localstack-web.git#commit=741276a31896cb498dc6207830842e6cbcca9611&workspace=@localstack/theme", "@mui/material": "^5.15.20", "@testing-library/react": "^13.4.0", "@types/node": "^16.18.99", - "@types/react": "^18.3.3", - "@types/react-dom": "^18.3.0", - "react": "^18.3.1", - "react-dom": "^18.3.1", + "@types/react-dom": "^17.0.11", + "react": "^17.0.2", + "react-dom": "^17.0.2", "react-router-dom": "^6.24.0", "react-scripts": "5.0.1", "typescript": "^4.9.5" @@ -29,9 +30,11 @@ "watch": "node .esbuild --watch", "build": "node .esbuild" }, - "eslintConfig": { - "extends": [ - "react-app" - ] - } + "resolutions": { + "react": "^17.0.2", + "react-dom": "^17.0.2", + "@types/react-dom": "^17.0.11", + "@mui/material": "^5.15.20" + }, + "packageManager": "yarn@3.2.3" } diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/favicon.png b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..4eff7d32bc16d20b929c045aba24fda3b698342a GIT binary patch literal 1598 zcmV-E2EqA>P)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 zVoOIv0RI600RN!9r;`8x00(qQO+^Rj0SXQSI)kBI-~a#w-$_J4R9M5Um(Po&R~3ez z_uQ|l`j<{7*dqxcQ5ObxAsZJFM1l+L9>rxN!u$v6r5i<8ZW3tSxQPTe&R`J5nPgmu z3l|a;G(pr^1fmOFOev1aOm}sC_r5OftsmVzo%GQCL36(M)pza! zJTLJB1sjoUC5R4EXJPG zqkszmm_AT_5hy_^A^1xF*7j8yG-D8SWE-kiN|0^bFG&p+?I%rj3uj`Y|p-4H<8ROjw+ zUkEevKL%CYr3LTik_-}xx}E^oe)eb31)xnz*#mZfJ4ldAO*>`5Kp+>U`$9DTJ4l%( zz9>Ek)WmZV=vW56^s(0|>+4wBq|bZm*`X9#=|XW6ZxF4h!<;Cwph6WQ?+E)gJ*^K+G%%)z))9T|7EddMLdp$#h@XejC=;aA;EplRexb zpJ^DZj2);H%%TQn5OaWN-WzC@UQ-Uyi_$NN_oj5v>B%cNVv{Dmh zOn(58B)e64^E*;)$B-eZS3t8hM3? zk)I}j zJQ_fs%hDWpxWHK;kdGXFMgYU5b?Eaii3k-J&n_jkyLN6*Z92>KIxO?r5R`ur8XvLu zOaLtXK#8DB38zF!t=iQpANcuiK67I4*7iF!^)pbLH*P=wXaJ`@Tc7_Oh%5B@Ynn{g zIXpDejQYNI&mzzVzz>1(&A)6vq6P2w3=*KHLEoU1OLg$OUS6hI1Hg6Q)#KaG4=@_l z2ve2?T1u+PsK=CY19%CzcRc6k2Ur|C_%0P|_#@f7 zUR@ch8}P;}ANs)U7xK?3b;$gfl)mkawK1zB-uz}d)5iY;1g49a=47nH0000bbVXQn zWMOn=I%9HWVRU5xGB7eUEif@HF)&myG&(RdIyE>eFfckWFwOVQ2><{9C3HntbYx+4 zWjbwdWNBu305UK#G%YYOEio`uF*G_bGdeXmD=;uRFfhETcC`Qi09SfcSaechcOY6Cgx@ wG{a;ABePT>%h=S&#LUDT#0SfONT5nC0O}VJbn-$ql>h($07*qoM6N<$g1m*wS^xk5 literal 0 HcmV?d00001 diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/index.html b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/index.html deleted file mode 100644 index aa069f2..0000000 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/index.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - React App - - - -
- - - diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/manifest.json b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/manifest.json index 080d6c7..711e77a 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/manifest.json +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/manifest.json @@ -1,21 +1,11 @@ { - "short_name": "React App", - "name": "Create React App Sample", + "short_name": "{{cookiecutter.project_name}}", + "name": "{{cookiecutter.project_name}}", "icons": [ { "src": "favicon.ico", "sizes": "64x64 32x32 24x24 16x16", "type": "image/x-icon" - }, - { - "src": "logo192.png", - "type": "image/png", - "sizes": "192x192" - }, - { - "src": "logo512.png", - "type": "image/png", - "sizes": "512x512" } ], "start_url": ".", diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/Dashboard.tsx b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/Dashboard.tsx index a4fa84f..c1c8073 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/Dashboard.tsx +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/Dashboard.tsx @@ -1,17 +1,28 @@ -import { Button } from '@mui/material'; -import React from 'react'; +import { Button, Card, CardContent, CardHeader, Typography } from '@mui/material'; +import { ReactElement } from 'react'; import { useNavigate } from 'react-router-dom'; -export const Dashboard = () => { +export const Dashboard = (): ReactElement => { const navigate = useNavigate(); return ( - <> - Dashboard - - + + navigate("/one")} + color="primary" + variant="contained" + > + Page One + + } + /> + + Lorem Ipsum + + ); } diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/PageOne.tsx b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/PageOne.tsx index bf72481..52dd474 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/PageOne.tsx +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/PageOne.tsx @@ -1,16 +1,28 @@ -import { Button } from "@mui/material"; -import { ReactElement } from "react"; -import { useNavigate } from "react-router-dom"; +import { Button, Card, CardContent, CardHeader, Typography } from '@mui/material'; +import { ReactElement } from 'react'; +import { useNavigate } from 'react-router-dom'; export const PageOne = (): ReactElement => { const navigate = useNavigate(); return ( - <> - Page One - - + + navigate("/dashboard")} + color="primary" + variant="contained" + > + Dashboard + + } + /> + + Lorem Ipsum + + ); -} \ No newline at end of file +} + diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.css b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.css index ec2585e..3f462eb 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.css +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.css @@ -1,13 +1,140 @@ -body { +* { + box-sizing: border-box; margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', - sans-serif; + padding: 0; +} + +html { + font-size: 1rem; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } -code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; +body { + background-color: #f9fafb; +} + +a { + text-decoration: none; +} + +a, +a:hover { + cursor: pointer; +} + +div.centeredPanel { + text-align: center; + padding: 20px; +} + +table.compactTable td, +table.compactTable th { + padding: 10px; +} + +table.compactTable tr { + height: auto; +} + +div.compactInput input { + padding: 7px; +} + +table tr.disabled td { + color: grey; +} + +a.tocAnchor { + position: relative; + top: -80px; + display: block; + height: 0; + width: 0; +} + +#root { + overflow-x: hidden; +} + +.plumb * { + word-wrap: break-word; +} +.layoutnode { + position: absolute; + border: 2px solid #bbbbbf; + border-radius: 5px; + padding: 6px; + max-width: 120px; + background: #fafbfe; +} +.layoutnode.selected, +.shard.selected { + border: 2px solid #888888; + background: #dddddd; + z-index: 100; +} +.shard, +.kinesis_shard { + position: static; + display: block; + border: 1px solid #aaaaaa; + border-radius: 5px; + padding: 3px; + white-space: nowrap; +} +.plumb .title { + font-weight: bold; + white-space: nowrap; +} + +div.MuiCollapse-wrapperInner a.MuiListItem-root { + margin-top: 0px; +} +div.MuiCollapse-wrapperInner a.MuiListItem-root span { + margin-left: 8px; +} +th.MuiTableCell-head { + white-space: nowrap; +} + +.dialogue { + line-height: 1.5; + +} +.dialogue .closeButton { + position: absolute !important; + right: 0; + top: 0; +} + +.MuiDropzoneArea-root { + padding: 20px; +} + +.MuiSelect-icon { + color: inherit !important; +} + +textarea { + width: 100%; +} + +.statusDot { + height: 8px; + min-width: 8px; + border-radius: 50%; + padding: 0; + display: inline-block; + margin-left: 0.5rem; +} + +.grecaptcha-badge { + width: 70px !important; + overflow: hidden !important; + transition: all 0.2s ease !important; + left: 0 !important; +} +.grecaptcha-badge:hover { + width: 256px !important; } diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.html b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.html index 4914d10..dae9f8d 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.html +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.html @@ -6,7 +6,7 @@ - LocalStack Extension + {{cookiecutter.project_name}} diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx index 092a6bc..5c13ef6 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx @@ -1,19 +1,18 @@ import React from 'react'; -import ReactDOM from 'react-dom/client'; +import ReactDOM from 'react-dom'; import './index.css'; import { CustomRoutes } from './CustomRoutes'; import { BrowserRouter } from 'react-router-dom'; +import { LocalStackThemeProvider } from '@localstack/theme' -const root = ReactDOM.createRoot( - document.getElementById('root') as HTMLElement -); const BASE_PATH = '/_localstack/{{cookiecutter.module_name}}'; -root.render( - +ReactDOM.render( + - + , + document.getElementById('root'), ); diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/react-app-env.d.ts b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/react-app-env.d.ts deleted file mode 100644 index 6431bc5..0000000 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/react-app-env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/tsconfig.json b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/tsconfig.json new file mode 100644 index 0000000..7c0ee58 --- /dev/null +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/tsconfig.json @@ -0,0 +1,43 @@ +{ + "compilerOptions": { + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "jsx": "react-jsx", + "target": "es5", + + "baseUrl": "./", + "esModuleInterop": true, + "moduleResolution": "node", + + "noEmit": true, + "allowJs": true, + "alwaysStrict": true, + "allowUnreachableCode": false, + "allowSyntheticDefaultImports": true, + "noImplicitAny": true, + "strictNullChecks": true, + "resolveJsonModule": true, + "preserveConstEnums": true, + "preserveSymlinks": true, + + "skipLibCheck": true, + "noImplicitReturns": true, + "noUncheckedIndexedAccess": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "typeRoots": [ + "./node_modules/@types", + "./src/types", + ], + + "paths": { + "@localstack/*": ["./node_modules/@localstack/*/src"], + }, + }, + "include": [ + "src/**/*", + ] +} From aad8fe50600428095ef08772aa3e863d399c4c50 Mon Sep 17 00:00:00 2001 From: Pive01 Date: Fri, 28 Jun 2024 17:47:38 +0200 Subject: [PATCH 07/35] Updated base endpoint --- .../{{cookiecutter.module_name}}/frontend/src/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx index 5c13ef6..21dbc71 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx @@ -5,7 +5,7 @@ import { CustomRoutes } from './CustomRoutes'; import { BrowserRouter } from 'react-router-dom'; import { LocalStackThemeProvider } from '@localstack/theme' -const BASE_PATH = '/_localstack/{{cookiecutter.module_name}}'; +const BASE_PATH = '/_extension/{{cookiecutter.project_slug}}'; ReactDOM.render( From 1fbf3a6e762897eba57b5aba4e8951d405b7aab7 Mon Sep 17 00:00:00 2001 From: Pive01 Date: Tue, 2 Jul 2024 16:33:59 +0200 Subject: [PATCH 08/35] Modified cookiecutter to choose base route based on location --- .../frontend/src/index.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx index 21dbc71..bf3ac54 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx @@ -5,11 +5,19 @@ import { CustomRoutes } from './CustomRoutes'; import { BrowserRouter } from 'react-router-dom'; import { LocalStackThemeProvider } from '@localstack/theme' -const BASE_PATH = '/_extension/{{cookiecutter.project_slug}}'; +const EXTENSION_NAME = '{{cookiecutter.project_slug}}'; + +const getBaseName = () => { + if (!window.location.origin.includes(EXTENSION_NAME)) { + return `/_extension/${EXTENSION_NAME}`; + } + return ''; +}; + ReactDOM.render( - + , From 4c58937c808826ea24e87e7320b13fd6835a608b Mon Sep 17 00:00:00 2001 From: Pive01 Date: Wed, 3 Jul 2024 10:30:30 +0200 Subject: [PATCH 09/35] Added hot reloading to extension UI --- .../{{cookiecutter.project_slug}}/Makefile | 30 ++++++++++++------- .../frontend/.esbuild/esbuild.config.js | 6 ---- .../frontend/package.json | 7 +++-- .../frontend/src/constants.ts | 1 + .../frontend/src/index.tsx | 13 ++++---- 5 files changed, 32 insertions(+), 25 deletions(-) create mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/constants.ts diff --git a/template/react/{{cookiecutter.project_slug}}/Makefile b/template/react/{{cookiecutter.project_slug}}/Makefile index 26b39b9..9e5be4c 100644 --- a/template/react/{{cookiecutter.project_slug}}/Makefile +++ b/template/react/{{cookiecutter.project_slug}}/Makefile @@ -3,6 +3,9 @@ VENV_DIR ?= .venv VENV_ACTIVATE = $(VENV_DIR)/bin/activate VENV_RUN = . $(VENV_ACTIVATE) +INFO_COLOR = \033[0;36m +NO_COLOR = \033[m + venv: $(VENV_ACTIVATE) $(VENV_ACTIVATE): setup.py setup.cfg @@ -11,30 +14,37 @@ $(VENV_ACTIVATE): setup.py setup.cfg $(VENV_RUN); pip install -e . touch $(VENV_DIR)/bin/activate -clean: +clean: ## Clean the project rm -rf .venv/ rm -rf build/ rm -rf .eggs/ rm -rf *.egg-info/ -install-backend: venv +install-backend: venv ## Install dependencies of the extension $(VENV_RUN); python setup.py develop -install-frontend: venv - cd {{cookiecutter.module_name}}/frontend && yarn install +install-frontend: venv ## Install dependencies of the frontend + cd my_localstack_extension/frontend && yarn install -build-frontend: - cd {{cookiecutter.module_name}}/frontend; rm -rf build && npm run build +build-frontend: # Build the react app + cd my_localstack_extension/frontend; rm -rf build && NODE_ENV=prod npm run build + +start-frontend: ## Start the frontend in dev mode (hot reload) + cd my_localstack_extension/frontend; REACT_APP_DEVELOPMENT_ENVIRONMENT=true yarn start -install: venv install-backend install-frontend +install: venv install-backend install-frontend ## Install dependencies -dist: venv build-frontend +dist: venv build-frontend ## Create distribution files $(VENV_RUN); python setup.py sdist bdist_wheel -publish: clean-dist venv dist +publish: clean-dist venv dist ## Build and upload package to pypi $(VENV_RUN); pip install --upgrade twine; twine upload dist/* -clean-dist: clean +clean-dist: clean ## Remove dist folder rm -rf dist/ +help: ## Show this help + @echo Please specify a build target. The choices are: + @grep -E '^[0-9a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "$(INFO_COLOR)%-30s$(NO_COLOR) %s\n", $$1, $$2}' + .PHONY: clean clean-dist dist install publish diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js index 9d641ff..3548bb6 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js @@ -14,9 +14,6 @@ const HtmlPlugin = require('./plugins/html'); const CURRENT_ENV = process.env.NODE_ENV || 'development.local'; const BUILD_PATH = path.join(__dirname, '..', 'build'); -// Load .env.* file depending on the active environment -require('dotenv').config({ path: `.env.${CURRENT_ENV}` }); - const BUILD_CONFIG = { entryPoints: [ path.join(__dirname, '..', 'src', 'index.tsx'), @@ -73,9 +70,6 @@ const BUILD_CONFIG = { {}, ), 'process.cwd': 'dummyProcessCwd', - 'process.env.PUBLIC_URL': '""', // empty for now to point to the root - 'process.env.BASE_PATH': '"/"', - 'process.env.NODE_ENV': JSON.stringify(CURRENT_ENV), global: 'window', }, external: [ diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json index 4d74fc4..be7ac31 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json @@ -1,5 +1,5 @@ { - "name": "{{cookiecutter.module_name}}", + "name": "my_localstack_extension", "version": "0.1.0", "private": true, "license": "UNLICENSED", @@ -19,14 +19,17 @@ }, "devDependencies": { "@esbuild-plugins/node-modules-polyfill": "^0.1.4", + "concurrently": "^8.2.2", "esbuild": "^0.16.6", "esbuild-envfile-plugin": "^1.0.2", "esbuild-plugin-clean": "^1.0.1", "esbuild-plugin-copy": "^0.3.0", - "esbuild-plugin-svgr": "^1.0.0" + "esbuild-plugin-svgr": "^1.0.0", + "live-server": "^1.2.2" }, "scripts": { "start": "concurrently --restart-tries -1 --raw \"yarn serve\" \"yarn watch\"", + "serve": "live-server --port=3000 --host=0.0.0.0 --no-browser --watch=build/index.html --entry-file=index.html build", "watch": "node .esbuild --watch", "build": "node .esbuild" }, diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/constants.ts b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/constants.ts new file mode 100644 index 0000000..2e059ec --- /dev/null +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/constants.ts @@ -0,0 +1 @@ +export const DEVELOPMENT_ENVIRONMENT = !!process.env.REACT_APP_DEVELOPMENT_ENVIRONMENT; diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx index bf3ac54..df67d7c 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx @@ -1,19 +1,19 @@ -import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import { CustomRoutes } from './CustomRoutes'; import { BrowserRouter } from 'react-router-dom'; import { LocalStackThemeProvider } from '@localstack/theme' +import { DEVELOPMENT_ENVIRONMENT } from './constants'; -const EXTENSION_NAME = '{{cookiecutter.project_slug}}'; +const EXTENSION_NAME = 'my-localstack-extension' const getBaseName = () => { - if (!window.location.origin.includes(EXTENSION_NAME)) { - return `/_extension/${EXTENSION_NAME}`; + if (window.location.origin.includes(EXTENSION_NAME) || DEVELOPMENT_ENVIRONMENT) { + return ''; } - return ''; -}; + return `/_extension/${EXTENSION_NAME}`; +}; ReactDOM.render( @@ -23,4 +23,3 @@ ReactDOM.render( , document.getElementById('root'), ); - From 5c5f9f00267d6508879760c3c6c13994813ccbbf Mon Sep 17 00:00:00 2001 From: Pive01 Date: Wed, 3 Jul 2024 11:48:19 +0200 Subject: [PATCH 10/35] Fixed issue with wrong boolean value --- .../{{cookiecutter.module_name}}/frontend/src/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/constants.ts b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/constants.ts index 2e059ec..2a85b5c 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/constants.ts +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/constants.ts @@ -1 +1 @@ -export const DEVELOPMENT_ENVIRONMENT = !!process.env.REACT_APP_DEVELOPMENT_ENVIRONMENT; +export const DEVELOPMENT_ENVIRONMENT = process.env.REACT_APP_DEVELOPMENT_ENVIRONMENT === "true"; From 7a09a16752b139676dad6e0b071f0425f56e3ea0 Mon Sep 17 00:00:00 2001 From: Pive01 Date: Wed, 3 Jul 2024 12:06:37 +0200 Subject: [PATCH 11/35] Updated README for react extension --- template/react/{{cookiecutter.project_slug}}/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/template/react/{{cookiecutter.project_slug}}/README.md b/template/react/{{cookiecutter.project_slug}}/README.md index 7240972..0eb2f2e 100644 --- a/template/react/{{cookiecutter.project_slug}}/README.md +++ b/template/react/{{cookiecutter.project_slug}}/README.md @@ -25,6 +25,14 @@ You can then start LocalStack with `EXTENSION_DEV_MODE=1` to load all enabled ex EXTENSION_DEV_MODE=1 localstack start ``` +## Developing UI +With this template is generated also a UI made in react that is available at either {{ cookiecutter.project_name }}.localhost.localstack.cloud:4566/ or http://localhost.localstack.cloud:4566/_extension/{{ cookiecutter.project_name }}/. + +There are a few make commands available that will help your journey with the UI: +- **build-frontend**: will build the react app into the frontend/build folder which will then be passed into the extension itself allowing the UI to be seen. Remember to always execute this command when you wish to see new changes when using the extension. +- **start-frontend**: will start a live server on port 3000 (by default) that will allow you to have hot reloading when developing locally outside the extension (it will also build the frontend) + + ## Install from GitHub repository To distribute your extension, simply upload it to your github account. Your extension can then be installed via: From 92e2c76b9d9a4829fe031f32d4651a9fda3e9102 Mon Sep 17 00:00:00 2001 From: Pive01 Date: Wed, 3 Jul 2024 14:36:47 +0200 Subject: [PATCH 12/35] Updated template to use WebAppExtension class --- .../{{cookiecutter.project_slug}}/Makefile | 2 +- .../backend/web.py | 53 +++---------------- .../{{cookiecutter.module_name}}/extension.py | 45 ++++------------ .../frontend/.esbuild/esbuild.config.js | 2 + .../{{cookiecutter.module_name}}/util.py | 51 ------------------ 5 files changed, 20 insertions(+), 133 deletions(-) delete mode 100644 template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/util.py diff --git a/template/react/{{cookiecutter.project_slug}}/Makefile b/template/react/{{cookiecutter.project_slug}}/Makefile index 9e5be4c..85d9063 100644 --- a/template/react/{{cookiecutter.project_slug}}/Makefile +++ b/template/react/{{cookiecutter.project_slug}}/Makefile @@ -27,7 +27,7 @@ install-frontend: venv ## Install dependencies of the frontend cd my_localstack_extension/frontend && yarn install build-frontend: # Build the react app - cd my_localstack_extension/frontend; rm -rf build && NODE_ENV=prod npm run build + cd my_localstack_extension/frontend; rm -rf build && REACT_APP_DEVELOPMENT_ENVIRONMENT=false NODE_ENV=prod npm run build start-frontend: ## Start the frontend in dev mode (hot reload) cd my_localstack_extension/frontend; REACT_APP_DEVELOPMENT_ENVIRONMENT=true yarn start diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py index 6f7820d..041d3bf 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py @@ -1,51 +1,12 @@ -import mimetypes -import os -from pathlib import Path - -from flask import redirect -from localstack.constants import ( - APPLICATION_OCTET_STREAM, - INTERNAL_RESOURCE_PATH, - LOCALHOST_HOSTNAME, -) from localstack.http import route, Request, Response -from {{cookiecutter.module_name}} import frontend as web_ui - - -DOMAIN_NAME = f"{{cookiecutter.module_name}}.{LOCALHOST_HOSTNAME}" -ROUTE_HOST = f"{DOMAIN_NAME}" -EXTENSION_SUB_ROUTE = f"{ROUTE_HOST}{INTERNAL_RESOURCE_PATH}/{{cookiecutter.module_name}}" - +from ..frontend import build class WebApp: - @route("/", methods=["GET"], host=ROUTE_HOST) - def forward_from_root(self, request: Request, **kwargs): - return redirect(f"{INTERNAL_RESOURCE_PATH}/{{cookiecutter.module_name}}/dashboard") - - @route("/", methods=["GET"], host=ROUTE_HOST) - def forward_custom_from_root(self, request: Request, path: str, **kwargs): - return self.serve_static_file(path) + @route("/") + def index(self, request: Request, *args, **kwargs): + return Response.for_resource(build, "index.html") - @route(f"{INTERNAL_RESOURCE_PATH}/{{cookiecutter.module_name}}", methods=["GET"]) - def forward_from_extension_root(self, request: Request, **kwargs): - return redirect(f"{INTERNAL_RESOURCE_PATH}/{{cookiecutter.module_name}}/index.html") - - @route(f"{INTERNAL_RESOURCE_PATH}/{{cookiecutter.module_name}}/", methods=["GET"]) - def get_web_asset(self, request: Request, path: str, **kwargs): - return self.serve_static_file(path) - - @route(f"{INTERNAL_RESOURCE_PATH}/{{cookiecutter.module_name}}/index.html", methods=["GET"]) - def serve_index_html(self, request: Request, **kwargs): - return self.serve_static_file("index.html") - - def serve_static_file(self, path: str): - build_dir = os.path.join(os.path.dirname(web_ui.__file__), "build") - file_path = os.path.join(build_dir, path.lstrip("/")) - - if not os.path.exists(file_path): - file_path = os.path.join(build_dir, "index.html") - - mime_type = mimetypes.guess_type(file_path)[0] or APPLICATION_OCTET_STREAM - - return Response(Path(file_path).open(mode="rb"), mimetype=mime_type) + @route("/") + def index2(self, request: Request, path: str, **kwargs): + return Response.for_resource(build, path) diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py index d1e827d..75d6522 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py @@ -1,44 +1,19 @@ import logging +import typing as t -from localstack.extensions.api import Extension, http, aws +from localstack.extensions.patterns.webapp import WebAppExtension -from localstack.services.internal import get_internal_apis -from localstack import config - -from {{ cookiecutter.module_name }}.backend.web import WebApp - -from .util import Routes, Subdomain, Submount +from .backend.web import WebApp LOG = logging.getLogger(__name__) -class MyExtension(Extension): - name = "{{ cookiecutter.project_slug }}" - - def on_extension_load(self): - print("MyExtension: extension is loaded") - - def on_platform_start(self): - print("MyExtension: localstack is starting") - - def on_platform_ready(self): - print("MyExtension: localstack is running") - def update_gateway_routes(self, router: http.Router[http.RouteHandler]): - LOG.info("Adding route for %s", self.name) +class MyExtension(WebAppExtension): + name = "{{ cookiecutter.project_slug }}" + + def __init__(self): + super().__init__(template_package_path=None) - get_internal_apis().add(WebApp()) - from localstack.aws.handlers.cors import ALLOWED_CORS_ORIGINS - - webapp = Routes(WebApp()) - - ALLOWED_CORS_ORIGINS.append(f"http://{self.name}.{config.LOCALSTACK_HOST}") - ALLOWED_CORS_ORIGINS.append(f"https://{self.name}.{config.LOCALSTACK_HOST}") - - router.add(Submount(f"/{self.name}", webapp)) - router.add(Subdomain(f"{self.name}", webapp)) - - def update_request_handlers(self, handlers: aws.CompositeHandler): - pass + def collect_routes(self, routes: list[t.Any]): + routes.append(WebApp()) - def update_response_handlers(self, handlers: aws.CompositeResponseHandler): - pass diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js index 3548bb6..6f241cb 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js @@ -10,6 +10,7 @@ const { NodeModulesPolyfillPlugin } = require('@esbuild-plugins/node-modules-pol const packageJson = require('../package.json'); const HtmlPlugin = require('./plugins/html'); +const { writeFileSync } = require('fs'); const CURRENT_ENV = process.env.NODE_ENV || 'development.local'; const BUILD_PATH = path.join(__dirname, '..', 'build'); @@ -84,6 +85,7 @@ const BUILD_CONFIG = { const build = async (overrides = {}) => { try { await esbuild.build({ ...BUILD_CONFIG, ...overrides }); + writeFileSync(path.join(BUILD_PATH, '__init__.py'),'') console.log('done building'); } catch (e) { console.error(e); diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/util.py b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/util.py deleted file mode 100644 index f6ffb36..0000000 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/util.py +++ /dev/null @@ -1,51 +0,0 @@ -from typing import Any, Iterable - -from localstack.http import Router - -from werkzeug.routing import ( - RuleFactory, - Map, - Rule, - Submount as WerkzeugSubmount, - Subdomain as WerkzeugSubdomain, -) - - -class Subdomain(WerkzeugSubdomain): - def __init__( - self, - subdomain: str, - rules: RuleFactory | Iterable[RuleFactory], - use_host_pattern: bool = True, - ): - super().__init__( - subdomain, [rules] if isinstance(rules, RuleFactory) else rules - ) - self.use_host_pattern = use_host_pattern - - def get_rules(self, map: Map) -> Iterable[Rule]: - if not self.use_host_pattern: - return super().get_rules(map) - - for rule in super().get_rules(map): - rule.host = f"{self.subdomain}.<__host__>" - yield rule - - -class Submount(WerkzeugSubmount): - def __init__(self, path: str, rules: RuleFactory | Iterable[RuleFactory]) -> None: - super().__init__(path, [rules] if isinstance(rules, RuleFactory) else rules) - - -class Routes(RuleFactory): - """ - Wraps an object that uses @route decorators ase a RuleFactory that can be added to a router. - """ - - def __init__(self, obj: Any): - self.obj = obj - - def get_rules(self, map: Map) -> Iterable[Rule]: - router = Router() # type: ignore - router.add(self.obj) - return router.url_map._rules \ No newline at end of file From 88be70726328126ec9ba1512b912e4969fa65631 Mon Sep 17 00:00:00 2001 From: Pive01 Date: Wed, 3 Jul 2024 14:44:23 +0200 Subject: [PATCH 13/35] Removed unnecessary dependencies --- template/react/{{cookiecutter.project_slug}}/setup.cfg | 5 ----- 1 file changed, 5 deletions(-) diff --git a/template/react/{{cookiecutter.project_slug}}/setup.cfg b/template/react/{{cookiecutter.project_slug}}/setup.cfg index 3ad57c0..0b11e43 100644 --- a/template/react/{{cookiecutter.project_slug}}/setup.cfg +++ b/template/react/{{cookiecutter.project_slug}}/setup.cfg @@ -14,11 +14,6 @@ zip_safe = False packages = find: install_requires = localstack>=2.2 - localstack-core - localstack-ext - werkzeug - flask - rolo [options.entry_points] localstack.extensions = From e6d348ce145b723c79d1b581aea948a771b9766f Mon Sep 17 00:00:00 2001 From: Pive01 Date: Wed, 3 Jul 2024 14:52:33 +0200 Subject: [PATCH 14/35] Added comment --- .../{{cookiecutter.module_name}}/frontend/src/CustomRoutes.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/CustomRoutes.tsx b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/CustomRoutes.tsx index 280dbf7..4158a2e 100644 --- a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/CustomRoutes.tsx +++ b/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/CustomRoutes.tsx @@ -5,7 +5,8 @@ import { Dashboard } from "./Dashboard"; export const CustomRoutes = (): ReactElement => ( - } /> + {/* Make sure to always have a route fallback to "/" as it is the default page that gets opened from the web app*/} + } /> } path="/dashboard" /> } path="/one" /> From b026d1b7ce5c3a405af72776bf3d295cbaf02412 Mon Sep 17 00:00:00 2001 From: Pive01 Date: Wed, 3 Jul 2024 15:18:37 +0200 Subject: [PATCH 15/35] Moved templates to allow retro-compatibility --- {template/react => react-template}/README.md | 0 .../default => react-template}/cookiecutter.json | 0 .../{{cookiecutter.project_slug}}/Makefile | 0 .../{{cookiecutter.project_slug}}/README.md | 0 .../{{cookiecutter.project_slug}}/setup.cfg | 0 .../{{cookiecutter.project_slug}}/setup.py | 0 .../{{cookiecutter.module_name}}/__init__.py | 0 .../{{cookiecutter.module_name}}/backend/web.py | 0 .../{{cookiecutter.module_name}}/extension.py | 0 .../frontend/.esbuild/esbuild.config.js | 0 .../frontend/.esbuild/esbuild.shims.js | 0 .../frontend/.esbuild/index.js | 0 .../frontend/.esbuild/plugins/html/index.js | 0 .../frontend/.yarnrc.yml | 0 .../frontend/__init__.py | 0 .../frontend/package.json | 0 .../frontend/public/favicon.png | Bin .../frontend/public/manifest.json | 0 .../frontend/public/robots.txt | 0 .../frontend/src/CustomRoutes.tsx | 0 .../frontend/src/Dashboard.tsx | 0 .../frontend/src/PageOne.tsx | 0 .../frontend/src/constants.ts | 0 .../frontend/src/index.css | 0 .../frontend/src/index.html | 0 .../frontend/src/index.tsx | 0 .../frontend/tsconfig.json | 0 template/{default => }/README.md | 0 template/{react => }/cookiecutter.json | 0 .../{{cookiecutter.project_slug}}/Makefile | 0 .../{{cookiecutter.project_slug}}/README.md | 0 .../{{cookiecutter.project_slug}}/setup.cfg | 0 .../{{cookiecutter.project_slug}}/setup.py | 0 .../{{cookiecutter.module_name}}/__init__.py | 0 .../{{cookiecutter.module_name}}/extension.py | 0 35 files changed, 0 insertions(+), 0 deletions(-) rename {template/react => react-template}/README.md (100%) rename {template/default => react-template}/cookiecutter.json (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/Makefile (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/README.md (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/setup.cfg (100%) rename {template/default => react-template}/{{cookiecutter.project_slug}}/setup.py (100%) rename {template/default => react-template}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.shims.js (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/index.js (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/plugins/html/index.js (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.yarnrc.yml (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/__init__.py (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/favicon.png (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/manifest.json (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/robots.txt (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/CustomRoutes.tsx (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/Dashboard.tsx (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/PageOne.tsx (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/constants.ts (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.css (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.html (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx (100%) rename {template/react => react-template}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/tsconfig.json (100%) rename template/{default => }/README.md (100%) rename template/{react => }/cookiecutter.json (100%) rename template/{default => }/{{cookiecutter.project_slug}}/Makefile (100%) rename template/{default => }/{{cookiecutter.project_slug}}/README.md (100%) rename template/{default => }/{{cookiecutter.project_slug}}/setup.cfg (100%) rename template/{react => }/{{cookiecutter.project_slug}}/setup.py (100%) rename template/{react => }/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py (100%) rename template/{default => }/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py (100%) diff --git a/template/react/README.md b/react-template/README.md similarity index 100% rename from template/react/README.md rename to react-template/README.md diff --git a/template/default/cookiecutter.json b/react-template/cookiecutter.json similarity index 100% rename from template/default/cookiecutter.json rename to react-template/cookiecutter.json diff --git a/template/react/{{cookiecutter.project_slug}}/Makefile b/react-template/{{cookiecutter.project_slug}}/Makefile similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/Makefile rename to react-template/{{cookiecutter.project_slug}}/Makefile diff --git a/template/react/{{cookiecutter.project_slug}}/README.md b/react-template/{{cookiecutter.project_slug}}/README.md similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/README.md rename to react-template/{{cookiecutter.project_slug}}/README.md diff --git a/template/react/{{cookiecutter.project_slug}}/setup.cfg b/react-template/{{cookiecutter.project_slug}}/setup.cfg similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/setup.cfg rename to react-template/{{cookiecutter.project_slug}}/setup.cfg diff --git a/template/default/{{cookiecutter.project_slug}}/setup.py b/react-template/{{cookiecutter.project_slug}}/setup.py similarity index 100% rename from template/default/{{cookiecutter.project_slug}}/setup.py rename to react-template/{{cookiecutter.project_slug}}/setup.py diff --git a/template/default/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py b/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py similarity index 100% rename from template/default/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py rename to react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py b/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py rename to react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py b/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py rename to react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js b/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js rename to react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.shims.js b/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.shims.js similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.shims.js rename to react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.shims.js diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/index.js b/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/index.js similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/index.js rename to react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/index.js diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/plugins/html/index.js b/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/plugins/html/index.js similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/plugins/html/index.js rename to react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/plugins/html/index.js diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.yarnrc.yml b/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.yarnrc.yml similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.yarnrc.yml rename to react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.yarnrc.yml diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/__init__.py b/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/__init__.py similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/__init__.py rename to react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/__init__.py diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json b/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json rename to react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/favicon.png b/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/favicon.png similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/favicon.png rename to react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/favicon.png diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/manifest.json b/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/manifest.json similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/manifest.json rename to react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/manifest.json diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/robots.txt b/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/robots.txt similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/robots.txt rename to react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/robots.txt diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/CustomRoutes.tsx b/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/CustomRoutes.tsx similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/CustomRoutes.tsx rename to react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/CustomRoutes.tsx diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/Dashboard.tsx b/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/Dashboard.tsx similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/Dashboard.tsx rename to react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/Dashboard.tsx diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/PageOne.tsx b/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/PageOne.tsx similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/PageOne.tsx rename to react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/PageOne.tsx diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/constants.ts b/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/constants.ts similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/constants.ts rename to react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/constants.ts diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.css b/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.css similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.css rename to react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.css diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.html b/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.html similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.html rename to react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.html diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx b/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx rename to react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/tsconfig.json b/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/tsconfig.json similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/tsconfig.json rename to react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/tsconfig.json diff --git a/template/default/README.md b/template/README.md similarity index 100% rename from template/default/README.md rename to template/README.md diff --git a/template/react/cookiecutter.json b/template/cookiecutter.json similarity index 100% rename from template/react/cookiecutter.json rename to template/cookiecutter.json diff --git a/template/default/{{cookiecutter.project_slug}}/Makefile b/template/{{cookiecutter.project_slug}}/Makefile similarity index 100% rename from template/default/{{cookiecutter.project_slug}}/Makefile rename to template/{{cookiecutter.project_slug}}/Makefile diff --git a/template/default/{{cookiecutter.project_slug}}/README.md b/template/{{cookiecutter.project_slug}}/README.md similarity index 100% rename from template/default/{{cookiecutter.project_slug}}/README.md rename to template/{{cookiecutter.project_slug}}/README.md diff --git a/template/default/{{cookiecutter.project_slug}}/setup.cfg b/template/{{cookiecutter.project_slug}}/setup.cfg similarity index 100% rename from template/default/{{cookiecutter.project_slug}}/setup.cfg rename to template/{{cookiecutter.project_slug}}/setup.cfg diff --git a/template/react/{{cookiecutter.project_slug}}/setup.py b/template/{{cookiecutter.project_slug}}/setup.py similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/setup.py rename to template/{{cookiecutter.project_slug}}/setup.py diff --git a/template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py b/template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py similarity index 100% rename from template/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py rename to template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py diff --git a/template/default/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py b/template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py similarity index 100% rename from template/default/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py rename to template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py From a018dec043a0bb1abdb262a4fa7ad9c79da551cc Mon Sep 17 00:00:00 2001 From: Pive01 Date: Fri, 5 Jul 2024 09:58:19 +0200 Subject: [PATCH 16/35] re-ordered template folders --- templates/basic/README.md | 10 ++++++ .../basic}/cookiecutter.json | 0 .../{{cookiecutter.project_slug}}/Makefile | 32 +++++++++++++++++ .../{{cookiecutter.project_slug}}/README.md | 34 ++++++++++++++++++ .../{{cookiecutter.project_slug}}/setup.cfg | 20 +++++++++++ .../{{cookiecutter.project_slug}}/setup.py | 0 .../{{cookiecutter.module_name}}/__init__.py | 0 .../{{cookiecutter.module_name}}/extension.py | 22 ++++++++++++ {react-template => templates/react}/README.md | 0 templates/react/cookiecutter.json | 10 ++++++ .../{{cookiecutter.project_slug}}/Makefile | 0 .../{{cookiecutter.project_slug}}/README.md | 0 .../{{cookiecutter.project_slug}}/setup.cfg | 0 .../{{cookiecutter.project_slug}}/setup.py | 4 +++ .../{{cookiecutter.module_name}}/__init__.py | 1 + .../backend/web.py | 0 .../{{cookiecutter.module_name}}/extension.py | 0 .../frontend/.esbuild/esbuild.config.js | 0 .../frontend/.esbuild/esbuild.shims.js | 0 .../frontend/.esbuild/index.js | 0 .../frontend/.esbuild/plugins/html/index.js | 0 .../frontend/.yarnrc.yml | 0 .../frontend/__init__.py | 0 .../frontend/package.json | 0 .../frontend/public/favicon.png | Bin .../frontend/public/manifest.json | 0 .../frontend/public/robots.txt | 0 .../frontend/src/CustomRoutes.tsx | 0 .../frontend/src/Dashboard.tsx | 0 .../frontend/src/PageOne.tsx | 0 .../frontend/src/constants.ts | 0 .../frontend/src/index.css | 0 .../frontend/src/index.html | 0 .../frontend/src/index.tsx | 0 .../frontend/tsconfig.json | 0 35 files changed, 133 insertions(+) create mode 100644 templates/basic/README.md rename {react-template => templates/basic}/cookiecutter.json (100%) create mode 100644 templates/basic/{{cookiecutter.project_slug}}/Makefile create mode 100644 templates/basic/{{cookiecutter.project_slug}}/README.md create mode 100644 templates/basic/{{cookiecutter.project_slug}}/setup.cfg rename {react-template => templates/basic}/{{cookiecutter.project_slug}}/setup.py (100%) rename {react-template => templates/basic}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py (100%) create mode 100644 templates/basic/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py rename {react-template => templates/react}/README.md (100%) create mode 100644 templates/react/cookiecutter.json rename {react-template => templates/react}/{{cookiecutter.project_slug}}/Makefile (100%) rename {react-template => templates/react}/{{cookiecutter.project_slug}}/README.md (100%) rename {react-template => templates/react}/{{cookiecutter.project_slug}}/setup.cfg (100%) create mode 100644 templates/react/{{cookiecutter.project_slug}}/setup.py create mode 100644 templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py rename {react-template => templates/react}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py (100%) rename {react-template => templates/react}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py (100%) rename {react-template => templates/react}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js (100%) rename {react-template => templates/react}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.shims.js (100%) rename {react-template => templates/react}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/index.js (100%) rename {react-template => templates/react}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/plugins/html/index.js (100%) rename {react-template => templates/react}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.yarnrc.yml (100%) rename {react-template => templates/react}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/__init__.py (100%) rename {react-template => templates/react}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json (100%) rename {react-template => templates/react}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/favicon.png (100%) rename {react-template => templates/react}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/manifest.json (100%) rename {react-template => templates/react}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/robots.txt (100%) rename {react-template => templates/react}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/CustomRoutes.tsx (100%) rename {react-template => templates/react}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/Dashboard.tsx (100%) rename {react-template => templates/react}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/PageOne.tsx (100%) rename {react-template => templates/react}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/constants.ts (100%) rename {react-template => templates/react}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.css (100%) rename {react-template => templates/react}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.html (100%) rename {react-template => templates/react}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx (100%) rename {react-template => templates/react}/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/tsconfig.json (100%) diff --git a/templates/basic/README.md b/templates/basic/README.md new file mode 100644 index 0000000..0213a57 --- /dev/null +++ b/templates/basic/README.md @@ -0,0 +1,10 @@ +Extension Template +================== + +This is a [cookiecutter](https://github.com/cookiecutter/cookiecutter) template that is used when you invoke. + +```console +localstack extensions dev new +``` + +It contains a simple python distribution config, and some boilerplate extension code. diff --git a/react-template/cookiecutter.json b/templates/basic/cookiecutter.json similarity index 100% rename from react-template/cookiecutter.json rename to templates/basic/cookiecutter.json diff --git a/templates/basic/{{cookiecutter.project_slug}}/Makefile b/templates/basic/{{cookiecutter.project_slug}}/Makefile new file mode 100644 index 0000000..0f12f48 --- /dev/null +++ b/templates/basic/{{cookiecutter.project_slug}}/Makefile @@ -0,0 +1,32 @@ +VENV_BIN = python3 -m venv +VENV_DIR ?= .venv +VENV_ACTIVATE = $(VENV_DIR)/bin/activate +VENV_RUN = . $(VENV_ACTIVATE) + +venv: $(VENV_ACTIVATE) + +$(VENV_ACTIVATE): setup.py setup.cfg + test -d .venv || $(VENV_BIN) .venv + $(VENV_RUN); pip install --upgrade pip setuptools plux + $(VENV_RUN); pip install -e . + touch $(VENV_DIR)/bin/activate + +clean: + rm -rf .venv/ + rm -rf build/ + rm -rf .eggs/ + rm -rf *.egg-info/ + +install: venv + $(VENV_RUN); python setup.py develop + +dist: venv + $(VENV_RUN); python setup.py sdist bdist_wheel + +publish: clean-dist venv dist + $(VENV_RUN); pip install --upgrade twine; twine upload dist/* + +clean-dist: clean + rm -rf dist/ + +.PHONY: clean clean-dist dist install publish diff --git a/templates/basic/{{cookiecutter.project_slug}}/README.md b/templates/basic/{{cookiecutter.project_slug}}/README.md new file mode 100644 index 0000000..7240972 --- /dev/null +++ b/templates/basic/{{cookiecutter.project_slug}}/README.md @@ -0,0 +1,34 @@ +{{ cookiecutter.project_name }} +=============================== + +{{ cookiecutter.project_short_description }} + +## Install local development version + +To install the extension into localstack in developer mode, you will need Python 3.10, and create a virtual environment in the extensions project. + +In the newly generated project, simply run + +```bash +make install +``` + +Then, to enable the extension for LocalStack, run + +```bash +localstack extensions dev enable . +``` + +You can then start LocalStack with `EXTENSION_DEV_MODE=1` to load all enabled extensions: + +```bash +EXTENSION_DEV_MODE=1 localstack start +``` + +## Install from GitHub repository + +To distribute your extension, simply upload it to your github account. Your extension can then be installed via: + +```bash +localstack extensions install "git+https://github.com/{{cookiecutter.github_username }}/{{ cookiecutter.project_slug }}/#egg={{ cookiecutter.project_slug }}" +``` diff --git a/templates/basic/{{cookiecutter.project_slug}}/setup.cfg b/templates/basic/{{cookiecutter.project_slug}}/setup.cfg new file mode 100644 index 0000000..2bb3f02 --- /dev/null +++ b/templates/basic/{{cookiecutter.project_slug}}/setup.cfg @@ -0,0 +1,20 @@ +[metadata] +name = {{ cookiecutter.project_slug }} +version = {{ cookiecutter.version }} +summary = LocalStack Extension: {{ cookiecutter.project_name }} +url = https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.project_slug }} +author = {{ cookiecutter.full_name }} +author_email = {{ cookiecutter.email }} +description = {{ cookiecutter.project_short_description }} +long_description = file: README.md +long_description_content_type = text/markdown; charset=UTF-8 + +[options] +zip_safe = False +packages = find: +install_requires = + localstack>=1.0 + +[options.entry_points] +localstack.extensions = + {{ cookiecutter.project_slug }} = {{ cookiecutter.module_name }}.extension:MyExtension diff --git a/react-template/{{cookiecutter.project_slug}}/setup.py b/templates/basic/{{cookiecutter.project_slug}}/setup.py similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/setup.py rename to templates/basic/{{cookiecutter.project_slug}}/setup.py diff --git a/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py b/templates/basic/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py rename to templates/basic/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py diff --git a/templates/basic/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py b/templates/basic/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py new file mode 100644 index 0000000..b833617 --- /dev/null +++ b/templates/basic/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py @@ -0,0 +1,22 @@ +from localstack.extensions.api import Extension, http, aws + +class MyExtension(Extension): + name = "{{ cookiecutter.project_slug }}" + + def on_extension_load(self): + print("MyExtension: extension is loaded") + + def on_platform_start(self): + print("MyExtension: localstack is starting") + + def on_platform_ready(self): + print("MyExtension: localstack is running") + + def update_gateway_routes(self, router: http.Router[http.RouteHandler]): + pass + + def update_request_handlers(self, handlers: aws.CompositeHandler): + pass + + def update_response_handlers(self, handlers: aws.CompositeResponseHandler): + pass diff --git a/react-template/README.md b/templates/react/README.md similarity index 100% rename from react-template/README.md rename to templates/react/README.md diff --git a/templates/react/cookiecutter.json b/templates/react/cookiecutter.json new file mode 100644 index 0000000..3d91d41 --- /dev/null +++ b/templates/react/cookiecutter.json @@ -0,0 +1,10 @@ +{ + "project_name": "My LocalStack Extension", + "project_short_description": "All the boilerplate you need to create a LocalStack extension.", + "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '-') }}", + "module_name": "{{ cookiecutter.project_slug.replace('-', '_') }}", + "full_name": "Jane Doe", + "email": "jane@example.com", + "github_username": "janedoe", + "version": "0.1.0" +} \ No newline at end of file diff --git a/react-template/{{cookiecutter.project_slug}}/Makefile b/templates/react/{{cookiecutter.project_slug}}/Makefile similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/Makefile rename to templates/react/{{cookiecutter.project_slug}}/Makefile diff --git a/react-template/{{cookiecutter.project_slug}}/README.md b/templates/react/{{cookiecutter.project_slug}}/README.md similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/README.md rename to templates/react/{{cookiecutter.project_slug}}/README.md diff --git a/react-template/{{cookiecutter.project_slug}}/setup.cfg b/templates/react/{{cookiecutter.project_slug}}/setup.cfg similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/setup.cfg rename to templates/react/{{cookiecutter.project_slug}}/setup.cfg diff --git a/templates/react/{{cookiecutter.project_slug}}/setup.py b/templates/react/{{cookiecutter.project_slug}}/setup.py new file mode 100644 index 0000000..c823345 --- /dev/null +++ b/templates/react/{{cookiecutter.project_slug}}/setup.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python +from setuptools import setup + +setup() diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py new file mode 100644 index 0000000..4b62a2f --- /dev/null +++ b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py @@ -0,0 +1 @@ +name = "{{ cookiecutter.module_name }}" diff --git a/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py rename to templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py diff --git a/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py rename to templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py diff --git a/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js rename to templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js diff --git a/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.shims.js b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.shims.js similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.shims.js rename to templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.shims.js diff --git a/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/index.js b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/index.js similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/index.js rename to templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/index.js diff --git a/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/plugins/html/index.js b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/plugins/html/index.js similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/plugins/html/index.js rename to templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/plugins/html/index.js diff --git a/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.yarnrc.yml b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.yarnrc.yml similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.yarnrc.yml rename to templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.yarnrc.yml diff --git a/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/__init__.py b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/__init__.py similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/__init__.py rename to templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/__init__.py diff --git a/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json rename to templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json diff --git a/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/favicon.png b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/favicon.png similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/favicon.png rename to templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/favicon.png diff --git a/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/manifest.json b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/manifest.json similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/manifest.json rename to templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/manifest.json diff --git a/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/robots.txt b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/robots.txt similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/robots.txt rename to templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/robots.txt diff --git a/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/CustomRoutes.tsx b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/CustomRoutes.tsx similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/CustomRoutes.tsx rename to templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/CustomRoutes.tsx diff --git a/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/Dashboard.tsx b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/Dashboard.tsx similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/Dashboard.tsx rename to templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/Dashboard.tsx diff --git a/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/PageOne.tsx b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/PageOne.tsx similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/PageOne.tsx rename to templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/PageOne.tsx diff --git a/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/constants.ts b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/constants.ts similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/constants.ts rename to templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/constants.ts diff --git a/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.css b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.css similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.css rename to templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.css diff --git a/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.html b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.html similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.html rename to templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.html diff --git a/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx rename to templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx diff --git a/react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/tsconfig.json b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/tsconfig.json similarity index 100% rename from react-template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/tsconfig.json rename to templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/tsconfig.json From 817a16ed2c5437be17c9b54e4f0699d6d5694664 Mon Sep 17 00:00:00 2001 From: Pive01 Date: Tue, 9 Jul 2024 09:53:05 +0200 Subject: [PATCH 17/35] Bit of adjustment to packaging and naming --- templates/react/{{cookiecutter.project_slug}}/Makefile | 6 +++--- templates/react/{{cookiecutter.project_slug}}/setup.cfg | 2 +- .../{{cookiecutter.module_name}}/frontend/package.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/templates/react/{{cookiecutter.project_slug}}/Makefile b/templates/react/{{cookiecutter.project_slug}}/Makefile index 85d9063..9890b2b 100644 --- a/templates/react/{{cookiecutter.project_slug}}/Makefile +++ b/templates/react/{{cookiecutter.project_slug}}/Makefile @@ -24,13 +24,13 @@ install-backend: venv ## Install dependencies of the extension $(VENV_RUN); python setup.py develop install-frontend: venv ## Install dependencies of the frontend - cd my_localstack_extension/frontend && yarn install + cd {{cookiecutter.module_name}}/frontend && yarn install build-frontend: # Build the react app - cd my_localstack_extension/frontend; rm -rf build && REACT_APP_DEVELOPMENT_ENVIRONMENT=false NODE_ENV=prod npm run build + cd {{cookiecutter.module_name}}/frontend; rm -rf build && REACT_APP_DEVELOPMENT_ENVIRONMENT=false NODE_ENV=prod npm run build start-frontend: ## Start the frontend in dev mode (hot reload) - cd my_localstack_extension/frontend; REACT_APP_DEVELOPMENT_ENVIRONMENT=true yarn start + cd {{cookiecutter.module_name}}/frontend; REACT_APP_DEVELOPMENT_ENVIRONMENT=true yarn start install: venv install-backend install-frontend ## Install dependencies diff --git a/templates/react/{{cookiecutter.project_slug}}/setup.cfg b/templates/react/{{cookiecutter.project_slug}}/setup.cfg index 0b11e43..29a7850 100644 --- a/templates/react/{{cookiecutter.project_slug}}/setup.cfg +++ b/templates/react/{{cookiecutter.project_slug}}/setup.cfg @@ -21,4 +21,4 @@ localstack.extensions = [options.package_data] {{ cookiecutter.project_slug }} = - {{ cookiecutter.module_name }}/frontend/build/* + frontend/build/* diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json index be7ac31..d3ce08b 100644 --- a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json +++ b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json @@ -1,5 +1,5 @@ { - "name": "my_localstack_extension", + "name": "{{ cookiecutter.project_name }}", "version": "0.1.0", "private": true, "license": "UNLICENSED", From 182cf2f711c8ef64d62b0236bb64903577303bd4 Mon Sep 17 00:00:00 2001 From: Pive01 Date: Tue, 9 Jul 2024 09:56:58 +0200 Subject: [PATCH 18/35] Added yarn install warning --- templates/react/{{cookiecutter.project_slug}}/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/react/{{cookiecutter.project_slug}}/README.md b/templates/react/{{cookiecutter.project_slug}}/README.md index 0eb2f2e..5fb79a0 100644 --- a/templates/react/{{cookiecutter.project_slug}}/README.md +++ b/templates/react/{{cookiecutter.project_slug}}/README.md @@ -6,7 +6,7 @@ ## Install local development version To install the extension into localstack in developer mode, you will need Python 3.10, and create a virtual environment in the extensions project. - +You will also need to install [yarn](https://yarnpkg.com/getting-started/install) as package manager if you haven't already In the newly generated project, simply run ```bash From ec8914e6bdee24c1f8614b04771a6fb96ca03ab8 Mon Sep 17 00:00:00 2001 From: Pive01 Date: Mon, 15 Jul 2024 10:19:30 +0200 Subject: [PATCH 19/35] Updated package.json with new published package --- .../{{cookiecutter.module_name}}/frontend/package.json | 2 +- .../{{cookiecutter.module_name}}/frontend/src/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json index d3ce08b..cdd428f 100644 --- a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json +++ b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json @@ -6,7 +6,7 @@ "dependencies": { "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", - "@localstack/theme": "git+ssh://git@github.com/localstack/localstack-web.git#commit=741276a31896cb498dc6207830842e6cbcca9611&workspace=@localstack/theme", + "@localstack/integrations": "^1.0.0", "@mui/material": "^5.15.20", "@testing-library/react": "^13.4.0", "@types/node": "^16.18.99", diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx index df67d7c..e365557 100644 --- a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx +++ b/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx @@ -2,7 +2,7 @@ import ReactDOM from 'react-dom'; import './index.css'; import { CustomRoutes } from './CustomRoutes'; import { BrowserRouter } from 'react-router-dom'; -import { LocalStackThemeProvider } from '@localstack/theme' +import { LocalStackThemeProvider } from '@localstack/integrations' import { DEVELOPMENT_ENVIRONMENT } from './constants'; const EXTENSION_NAME = 'my-localstack-extension' From 28306e39219255260a6e80b640a28e53df7f3e6e Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 15 Jul 2024 16:07:32 +0200 Subject: [PATCH 20/35] Update README.md --- templates/react/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/react/README.md b/templates/react/README.md index ae0ce10..02505dc 100644 --- a/templates/react/README.md +++ b/templates/react/README.md @@ -4,7 +4,7 @@ Extension Template This is a [cookiecutter](https://github.com/cookiecutter/cookiecutter) template that is used when you invoke. ```console -localstack extensions dev new --ui +localstack extensions dev new --template=react ``` It contains a simple python distribution config, and some boilerplate extension code. From b148dcc82c93fb42d32aae1c2214949b3a15fe45 Mon Sep 17 00:00:00 2001 From: Pive01 Date: Tue, 23 Jul 2024 16:05:20 +0200 Subject: [PATCH 21/35] changed directory layout for react extension --- .../react/{{cookiecutter.project_slug}}/Makefile | 7 ++++--- .../{{cookiecutter.module_name}}/__init__.py | 0 .../{{cookiecutter.module_name}}/api}/web.py | 6 +++--- .../{{cookiecutter.module_name}}/extension.py | 2 +- .../static}/__init__.py | 0 .../frontend/.esbuild/esbuild.config.js | 7 +++++-- .../frontend/.esbuild/esbuild.shims.js | 0 .../frontend/.esbuild/index.js | 0 .../frontend/.esbuild/plugins/html/index.js | 0 .../frontend/.yarnrc.yml | 0 .../frontend/__init__.py | 0 .../frontend/package.json | 2 +- .../frontend/public/favicon.png | Bin .../frontend/public/manifest.json | 0 .../frontend/public/robots.txt | 0 .../frontend/src/CustomRoutes.tsx | 0 .../frontend/src/Dashboard.tsx | 0 .../frontend/src/PageOne.tsx | 0 .../frontend/src/constants.ts | 0 .../frontend/src/index.css | 0 .../frontend/src/index.html | 0 .../frontend/src/index.tsx | 2 +- .../frontend/tsconfig.json | 0 .../react/{{cookiecutter.project_slug}}/setup.cfg | 11 ++++++++--- 24 files changed, 23 insertions(+), 14 deletions(-) rename templates/react/{{cookiecutter.project_slug}}/{ => backend}/{{cookiecutter.module_name}}/__init__.py (100%) rename templates/react/{{cookiecutter.project_slug}}/{{{cookiecutter.module_name}}/backend => backend/{{cookiecutter.module_name}}/api}/web.py (63%) rename templates/react/{{cookiecutter.project_slug}}/{ => backend}/{{cookiecutter.module_name}}/extension.py (92%) rename templates/react/{{cookiecutter.project_slug}}/{{{cookiecutter.module_name}}/frontend => backend/{{cookiecutter.module_name}}/static}/__init__.py (100%) rename templates/react/{{cookiecutter.project_slug}}/{{{cookiecutter.module_name}} => }/frontend/.esbuild/esbuild.config.js (93%) rename templates/react/{{cookiecutter.project_slug}}/{{{cookiecutter.module_name}} => }/frontend/.esbuild/esbuild.shims.js (100%) rename templates/react/{{cookiecutter.project_slug}}/{{{cookiecutter.module_name}} => }/frontend/.esbuild/index.js (100%) rename templates/react/{{cookiecutter.project_slug}}/{{{cookiecutter.module_name}} => }/frontend/.esbuild/plugins/html/index.js (100%) rename templates/react/{{cookiecutter.project_slug}}/{{{cookiecutter.module_name}} => }/frontend/.yarnrc.yml (100%) create mode 100644 templates/react/{{cookiecutter.project_slug}}/frontend/__init__.py rename templates/react/{{cookiecutter.project_slug}}/{{{cookiecutter.module_name}} => }/frontend/package.json (90%) rename templates/react/{{cookiecutter.project_slug}}/{{{cookiecutter.module_name}} => }/frontend/public/favicon.png (100%) rename templates/react/{{cookiecutter.project_slug}}/{{{cookiecutter.module_name}} => }/frontend/public/manifest.json (100%) rename templates/react/{{cookiecutter.project_slug}}/{{{cookiecutter.module_name}} => }/frontend/public/robots.txt (100%) rename templates/react/{{cookiecutter.project_slug}}/{{{cookiecutter.module_name}} => }/frontend/src/CustomRoutes.tsx (100%) rename templates/react/{{cookiecutter.project_slug}}/{{{cookiecutter.module_name}} => }/frontend/src/Dashboard.tsx (100%) rename templates/react/{{cookiecutter.project_slug}}/{{{cookiecutter.module_name}} => }/frontend/src/PageOne.tsx (100%) rename templates/react/{{cookiecutter.project_slug}}/{{{cookiecutter.module_name}} => }/frontend/src/constants.ts (100%) rename templates/react/{{cookiecutter.project_slug}}/{{{cookiecutter.module_name}} => }/frontend/src/index.css (100%) rename templates/react/{{cookiecutter.project_slug}}/{{{cookiecutter.module_name}} => }/frontend/src/index.html (100%) rename templates/react/{{cookiecutter.project_slug}}/{{{cookiecutter.module_name}} => }/frontend/src/index.tsx (92%) rename templates/react/{{cookiecutter.project_slug}}/{{{cookiecutter.module_name}} => }/frontend/tsconfig.json (100%) diff --git a/templates/react/{{cookiecutter.project_slug}}/Makefile b/templates/react/{{cookiecutter.project_slug}}/Makefile index 9890b2b..ab1e79b 100644 --- a/templates/react/{{cookiecutter.project_slug}}/Makefile +++ b/templates/react/{{cookiecutter.project_slug}}/Makefile @@ -2,6 +2,7 @@ VENV_BIN = python3 -m venv VENV_DIR ?= .venv VENV_ACTIVATE = $(VENV_DIR)/bin/activate VENV_RUN = . $(VENV_ACTIVATE) +FRONTEND_FOLDER = frontend INFO_COLOR = \033[0;36m NO_COLOR = \033[m @@ -24,13 +25,13 @@ install-backend: venv ## Install dependencies of the extension $(VENV_RUN); python setup.py develop install-frontend: venv ## Install dependencies of the frontend - cd {{cookiecutter.module_name}}/frontend && yarn install + cd $(FRONTEND_FOLDER) && yarn install build-frontend: # Build the react app - cd {{cookiecutter.module_name}}/frontend; rm -rf build && REACT_APP_DEVELOPMENT_ENVIRONMENT=false NODE_ENV=prod npm run build + cd $(FRONTEND_FOLDER); rm -rf build && REACT_APP_DEVELOPMENT_ENVIRONMENT=false NODE_ENV=prod npm run build start-frontend: ## Start the frontend in dev mode (hot reload) - cd {{cookiecutter.module_name}}/frontend; REACT_APP_DEVELOPMENT_ENVIRONMENT=true yarn start + cd $(FRONTEND_FOLDER); REACT_APP_DEVELOPMENT_ENVIRONMENT=true yarn start install: venv install-backend install-frontend ## Install dependencies diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py b/templates/react/{{cookiecutter.project_slug}}/backend/{{cookiecutter.module_name}}/__init__.py similarity index 100% rename from templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/__init__.py rename to templates/react/{{cookiecutter.project_slug}}/backend/{{cookiecutter.module_name}}/__init__.py diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py b/templates/react/{{cookiecutter.project_slug}}/backend/{{cookiecutter.module_name}}/api/web.py similarity index 63% rename from templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py rename to templates/react/{{cookiecutter.project_slug}}/backend/{{cookiecutter.module_name}}/api/web.py index 041d3bf..78faf4d 100644 --- a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/backend/web.py +++ b/templates/react/{{cookiecutter.project_slug}}/backend/{{cookiecutter.module_name}}/api/web.py @@ -1,12 +1,12 @@ from localstack.http import route, Request, Response -from ..frontend import build +from .. import static class WebApp: @route("/") def index(self, request: Request, *args, **kwargs): - return Response.for_resource(build, "index.html") + return Response.for_resource(static, "index.html") @route("/") def index2(self, request: Request, path: str, **kwargs): - return Response.for_resource(build, path) + return Response.for_resource(static, path) diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py b/templates/react/{{cookiecutter.project_slug}}/backend/{{cookiecutter.module_name}}/extension.py similarity index 92% rename from templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py rename to templates/react/{{cookiecutter.project_slug}}/backend/{{cookiecutter.module_name}}/extension.py index 75d6522..789ef79 100644 --- a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py +++ b/templates/react/{{cookiecutter.project_slug}}/backend/{{cookiecutter.module_name}}/extension.py @@ -3,7 +3,7 @@ from localstack.extensions.patterns.webapp import WebAppExtension -from .backend.web import WebApp +from .api.web import WebApp LOG = logging.getLogger(__name__) diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/__init__.py b/templates/react/{{cookiecutter.project_slug}}/backend/{{cookiecutter.module_name}}/static/__init__.py similarity index 100% rename from templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/__init__.py rename to templates/react/{{cookiecutter.project_slug}}/backend/{{cookiecutter.module_name}}/static/__init__.py diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js b/templates/react/{{cookiecutter.project_slug}}/frontend/.esbuild/esbuild.config.js similarity index 93% rename from templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js rename to templates/react/{{cookiecutter.project_slug}}/frontend/.esbuild/esbuild.config.js index 6f241cb..8ada308 100644 --- a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.config.js +++ b/templates/react/{{cookiecutter.project_slug}}/frontend/.esbuild/esbuild.config.js @@ -13,7 +13,7 @@ const HtmlPlugin = require('./plugins/html'); const { writeFileSync } = require('fs'); const CURRENT_ENV = process.env.NODE_ENV || 'development.local'; -const BUILD_PATH = path.join(__dirname, '..', 'build'); +const BUILD_PATH = path.join(__dirname, '..', '..', 'backend', '{{cookiecutter.module_name}}', 'static'); const BUILD_CONFIG = { entryPoints: [ @@ -34,7 +34,10 @@ const BUILD_CONFIG = { CleanPlugin({ patterns: [`${BUILD_PATH}/*`, `!${BUILD_PATH}/index.html`], sync: true, - verbose: false + verbose: false, + options: { + force: true + } }), SvgrPlugin({ prettier: false, diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.shims.js b/templates/react/{{cookiecutter.project_slug}}/frontend/.esbuild/esbuild.shims.js similarity index 100% rename from templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/esbuild.shims.js rename to templates/react/{{cookiecutter.project_slug}}/frontend/.esbuild/esbuild.shims.js diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/index.js b/templates/react/{{cookiecutter.project_slug}}/frontend/.esbuild/index.js similarity index 100% rename from templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/index.js rename to templates/react/{{cookiecutter.project_slug}}/frontend/.esbuild/index.js diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/plugins/html/index.js b/templates/react/{{cookiecutter.project_slug}}/frontend/.esbuild/plugins/html/index.js similarity index 100% rename from templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.esbuild/plugins/html/index.js rename to templates/react/{{cookiecutter.project_slug}}/frontend/.esbuild/plugins/html/index.js diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.yarnrc.yml b/templates/react/{{cookiecutter.project_slug}}/frontend/.yarnrc.yml similarity index 100% rename from templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/.yarnrc.yml rename to templates/react/{{cookiecutter.project_slug}}/frontend/.yarnrc.yml diff --git a/templates/react/{{cookiecutter.project_slug}}/frontend/__init__.py b/templates/react/{{cookiecutter.project_slug}}/frontend/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json b/templates/react/{{cookiecutter.project_slug}}/frontend/package.json similarity index 90% rename from templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json rename to templates/react/{{cookiecutter.project_slug}}/frontend/package.json index cdd428f..53661c8 100644 --- a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/package.json +++ b/templates/react/{{cookiecutter.project_slug}}/frontend/package.json @@ -29,7 +29,7 @@ }, "scripts": { "start": "concurrently --restart-tries -1 --raw \"yarn serve\" \"yarn watch\"", - "serve": "live-server --port=3000 --host=0.0.0.0 --no-browser --watch=build/index.html --entry-file=index.html build", + "serve": "live-server --port=3000 --host=0.0.0.0 --no-browser --watch=backend/{{cookiecutter.module_name}}/static/index.html --entry-file=index.html ../backend/{{cookiecutter.module_name}}/static", "watch": "node .esbuild --watch", "build": "node .esbuild" }, diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/favicon.png b/templates/react/{{cookiecutter.project_slug}}/frontend/public/favicon.png similarity index 100% rename from templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/favicon.png rename to templates/react/{{cookiecutter.project_slug}}/frontend/public/favicon.png diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/manifest.json b/templates/react/{{cookiecutter.project_slug}}/frontend/public/manifest.json similarity index 100% rename from templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/manifest.json rename to templates/react/{{cookiecutter.project_slug}}/frontend/public/manifest.json diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/robots.txt b/templates/react/{{cookiecutter.project_slug}}/frontend/public/robots.txt similarity index 100% rename from templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/public/robots.txt rename to templates/react/{{cookiecutter.project_slug}}/frontend/public/robots.txt diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/CustomRoutes.tsx b/templates/react/{{cookiecutter.project_slug}}/frontend/src/CustomRoutes.tsx similarity index 100% rename from templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/CustomRoutes.tsx rename to templates/react/{{cookiecutter.project_slug}}/frontend/src/CustomRoutes.tsx diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/Dashboard.tsx b/templates/react/{{cookiecutter.project_slug}}/frontend/src/Dashboard.tsx similarity index 100% rename from templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/Dashboard.tsx rename to templates/react/{{cookiecutter.project_slug}}/frontend/src/Dashboard.tsx diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/PageOne.tsx b/templates/react/{{cookiecutter.project_slug}}/frontend/src/PageOne.tsx similarity index 100% rename from templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/PageOne.tsx rename to templates/react/{{cookiecutter.project_slug}}/frontend/src/PageOne.tsx diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/constants.ts b/templates/react/{{cookiecutter.project_slug}}/frontend/src/constants.ts similarity index 100% rename from templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/constants.ts rename to templates/react/{{cookiecutter.project_slug}}/frontend/src/constants.ts diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.css b/templates/react/{{cookiecutter.project_slug}}/frontend/src/index.css similarity index 100% rename from templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.css rename to templates/react/{{cookiecutter.project_slug}}/frontend/src/index.css diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.html b/templates/react/{{cookiecutter.project_slug}}/frontend/src/index.html similarity index 100% rename from templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.html rename to templates/react/{{cookiecutter.project_slug}}/frontend/src/index.html diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx b/templates/react/{{cookiecutter.project_slug}}/frontend/src/index.tsx similarity index 92% rename from templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx rename to templates/react/{{cookiecutter.project_slug}}/frontend/src/index.tsx index e365557..cddd6a1 100644 --- a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/src/index.tsx +++ b/templates/react/{{cookiecutter.project_slug}}/frontend/src/index.tsx @@ -5,7 +5,7 @@ import { BrowserRouter } from 'react-router-dom'; import { LocalStackThemeProvider } from '@localstack/integrations' import { DEVELOPMENT_ENVIRONMENT } from './constants'; -const EXTENSION_NAME = 'my-localstack-extension' +const EXTENSION_NAME = '{{cookiecutter.project_slug}}' const getBaseName = () => { if (window.location.origin.includes(EXTENSION_NAME) || DEVELOPMENT_ENVIRONMENT) { diff --git a/templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/tsconfig.json b/templates/react/{{cookiecutter.project_slug}}/frontend/tsconfig.json similarity index 100% rename from templates/react/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/frontend/tsconfig.json rename to templates/react/{{cookiecutter.project_slug}}/frontend/tsconfig.json diff --git a/templates/react/{{cookiecutter.project_slug}}/setup.cfg b/templates/react/{{cookiecutter.project_slug}}/setup.cfg index 29a7850..3fb6fad 100644 --- a/templates/react/{{cookiecutter.project_slug}}/setup.cfg +++ b/templates/react/{{cookiecutter.project_slug}}/setup.cfg @@ -11,14 +11,19 @@ long_description_content_type = text/markdown; charset=UTF-8 [options] zip_safe = False +package_dir= + =backend packages = find: install_requires = localstack>=2.2 - + +[options.packages.find] +where=backend + [options.entry_points] localstack.extensions = - {{ cookiecutter.project_slug }} = {{ cookiecutter.module_name }}.extension:MyExtension + {{ cookiecutter.project_slug }} = backend.{{ cookiecutter.module_name }}.extension:MyExtension [options.package_data] {{ cookiecutter.project_slug }} = - frontend/build/* + backend/{{ cookiecutter.module_name }}/* From 458931f3d45bc69fd50234088232584205b964e6 Mon Sep 17 00:00:00 2001 From: Luca Pivetta <36865043+Pive01@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:44:42 +0200 Subject: [PATCH 22/35] Apply suggestions from code review Co-authored-by: Dominik Schubert --- templates/react/{{cookiecutter.project_slug}}/README.md | 2 +- templates/react/{{cookiecutter.project_slug}}/setup.cfg | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/react/{{cookiecutter.project_slug}}/README.md b/templates/react/{{cookiecutter.project_slug}}/README.md index 5fb79a0..8e083cd 100644 --- a/templates/react/{{cookiecutter.project_slug}}/README.md +++ b/templates/react/{{cookiecutter.project_slug}}/README.md @@ -5,7 +5,7 @@ ## Install local development version -To install the extension into localstack in developer mode, you will need Python 3.10, and create a virtual environment in the extensions project. +To install the extension into localstack in developer mode, you will need Python 3.10+, and create a virtual environment in the extensions project. You will also need to install [yarn](https://yarnpkg.com/getting-started/install) as package manager if you haven't already In the newly generated project, simply run diff --git a/templates/react/{{cookiecutter.project_slug}}/setup.cfg b/templates/react/{{cookiecutter.project_slug}}/setup.cfg index 3fb6fad..71a9289 100644 --- a/templates/react/{{cookiecutter.project_slug}}/setup.cfg +++ b/templates/react/{{cookiecutter.project_slug}}/setup.cfg @@ -22,8 +22,8 @@ where=backend [options.entry_points] localstack.extensions = - {{ cookiecutter.project_slug }} = backend.{{ cookiecutter.module_name }}.extension:MyExtension + {{ cookiecutter.module_name }} = {{ cookiecutter.module_name }}.extension:MyExtension [options.package_data] -{{ cookiecutter.project_slug }} = - backend/{{ cookiecutter.module_name }}/* +{{ cookiecutter.module_name }} = + static/* From 9560d22da4ac7e3d731cdcf97448e446de10228c Mon Sep 17 00:00:00 2001 From: Pive01 Date: Wed, 24 Jul 2024 16:25:06 +0200 Subject: [PATCH 23/35] Address some comments --- .../react/{{cookiecutter.project_slug}}/Makefile | 11 ++++++++--- .../react/{{cookiecutter.project_slug}}/setup.cfg | 6 ++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/templates/react/{{cookiecutter.project_slug}}/Makefile b/templates/react/{{cookiecutter.project_slug}}/Makefile index ab1e79b..2990875 100644 --- a/templates/react/{{cookiecutter.project_slug}}/Makefile +++ b/templates/react/{{cookiecutter.project_slug}}/Makefile @@ -3,6 +3,8 @@ VENV_DIR ?= .venv VENV_ACTIVATE = $(VENV_DIR)/bin/activate VENV_RUN = . $(VENV_ACTIVATE) FRONTEND_FOLDER = frontend +BACKEND_FOLDER = backend + INFO_COLOR = \033[0;36m NO_COLOR = \033[m @@ -19,7 +21,7 @@ clean: ## Clean the project rm -rf .venv/ rm -rf build/ rm -rf .eggs/ - rm -rf *.egg-info/ + rm -rf $(BACKEND_FOLDER)/*.egg-info/ install-backend: venv ## Install dependencies of the extension $(VENV_RUN); python setup.py develop @@ -28,7 +30,10 @@ install-frontend: venv ## Install dependencies of the frontend cd $(FRONTEND_FOLDER) && yarn install build-frontend: # Build the react app - cd $(FRONTEND_FOLDER); rm -rf build && REACT_APP_DEVELOPMENT_ENVIRONMENT=false NODE_ENV=prod npm run build + ifeq ($(wildcard $(FRONTEND_FOLDER)/node_modules),) + $(MAKE) install-frontend + endif + cd $(FRONTEND_FOLDER); rm -rf build && REACT_APP_DEVELOPMENT_ENVIRONMENT=false NODE_ENV=prod npm run build start-frontend: ## Start the frontend in dev mode (hot reload) cd $(FRONTEND_FOLDER); REACT_APP_DEVELOPMENT_ENVIRONMENT=true yarn start @@ -48,4 +53,4 @@ help: ## Show this help @echo Please specify a build target. The choices are: @grep -E '^[0-9a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "$(INFO_COLOR)%-30s$(NO_COLOR) %s\n", $$1, $$2}' -.PHONY: clean clean-dist dist install publish +.PHONY: clean clean-dist dist install install-backend install-frontend build-frontend start-frontend publish diff --git a/templates/react/{{cookiecutter.project_slug}}/setup.cfg b/templates/react/{{cookiecutter.project_slug}}/setup.cfg index 71a9289..433cbf6 100644 --- a/templates/react/{{cookiecutter.project_slug}}/setup.cfg +++ b/templates/react/{{cookiecutter.project_slug}}/setup.cfg @@ -14,12 +14,14 @@ zip_safe = False package_dir= =backend packages = find: -install_requires = - localstack>=2.2 [options.packages.find] where=backend +[options.extras_require] +test= + localstack-core>=2.2 + [options.entry_points] localstack.extensions = {{ cookiecutter.module_name }} = {{ cookiecutter.module_name }}.extension:MyExtension From 94c96372a3e5e5d105c46489593e3fc5ccda8f1f Mon Sep 17 00:00:00 2001 From: Pive01 Date: Wed, 24 Jul 2024 16:29:31 +0200 Subject: [PATCH 24/35] Added .gitignore --- templates/basic/{{cookiecutter.project_slug}}/.gitignore | 5 +++++ templates/react/{{cookiecutter.project_slug}}/.gitignore | 7 +++++++ 2 files changed, 12 insertions(+) create mode 100644 templates/basic/{{cookiecutter.project_slug}}/.gitignore create mode 100644 templates/react/{{cookiecutter.project_slug}}/.gitignore diff --git a/templates/basic/{{cookiecutter.project_slug}}/.gitignore b/templates/basic/{{cookiecutter.project_slug}}/.gitignore new file mode 100644 index 0000000..77be714 --- /dev/null +++ b/templates/basic/{{cookiecutter.project_slug}}/.gitignore @@ -0,0 +1,5 @@ +.venv +dist +build +**/*.egg-info +.eggs \ No newline at end of file diff --git a/templates/react/{{cookiecutter.project_slug}}/.gitignore b/templates/react/{{cookiecutter.project_slug}}/.gitignore new file mode 100644 index 0000000..04336b6 --- /dev/null +++ b/templates/react/{{cookiecutter.project_slug}}/.gitignore @@ -0,0 +1,7 @@ +.venv +frontend/node_modules +frontend/.yarn +dist +build +**/*.egg-info +.eggs \ No newline at end of file From 051055087027fb7869f519f9bed3ba3e987d9490 Mon Sep 17 00:00:00 2001 From: Pive01 Date: Wed, 24 Jul 2024 16:55:37 +0200 Subject: [PATCH 25/35] Addressed more comments --- templates/basic/cookiecutter.json | 1 + .../basic/{{cookiecutter.project_slug}}/setup.cfg | 2 +- .../{{cookiecutter.module_name}}/extension.py | 2 +- templates/react/cookiecutter.json | 1 + templates/react/{{cookiecutter.project_slug}}/Makefile | 10 +++++----- .../backend/{{cookiecutter.module_name}}/extension.py | 2 +- .../react/{{cookiecutter.project_slug}}/setup.cfg | 2 +- 7 files changed, 11 insertions(+), 9 deletions(-) diff --git a/templates/basic/cookiecutter.json b/templates/basic/cookiecutter.json index 3d91d41..8b4ead9 100644 --- a/templates/basic/cookiecutter.json +++ b/templates/basic/cookiecutter.json @@ -3,6 +3,7 @@ "project_short_description": "All the boilerplate you need to create a LocalStack extension.", "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '-') }}", "module_name": "{{ cookiecutter.project_slug.replace('-', '_') }}", + "class_name": "{{ cookiecutter.project_name.replace('-', ' ').replace('_', ' ').title().replace(' ', '') }}", "full_name": "Jane Doe", "email": "jane@example.com", "github_username": "janedoe", diff --git a/templates/basic/{{cookiecutter.project_slug}}/setup.cfg b/templates/basic/{{cookiecutter.project_slug}}/setup.cfg index 2bb3f02..3bbcb46 100644 --- a/templates/basic/{{cookiecutter.project_slug}}/setup.cfg +++ b/templates/basic/{{cookiecutter.project_slug}}/setup.cfg @@ -17,4 +17,4 @@ install_requires = [options.entry_points] localstack.extensions = - {{ cookiecutter.project_slug }} = {{ cookiecutter.module_name }}.extension:MyExtension + {{ cookiecutter.project_slug }} = {{ cookiecutter.module_name }}.extension:{{ cookiecutter.class_name }} diff --git a/templates/basic/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py b/templates/basic/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py index b833617..3c3671a 100644 --- a/templates/basic/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py +++ b/templates/basic/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py @@ -1,6 +1,6 @@ from localstack.extensions.api import Extension, http, aws -class MyExtension(Extension): +class {{ cookiecutter.class_name }}(Extension): name = "{{ cookiecutter.project_slug }}" def on_extension_load(self): diff --git a/templates/react/cookiecutter.json b/templates/react/cookiecutter.json index 3d91d41..8b4ead9 100644 --- a/templates/react/cookiecutter.json +++ b/templates/react/cookiecutter.json @@ -3,6 +3,7 @@ "project_short_description": "All the boilerplate you need to create a LocalStack extension.", "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '-') }}", "module_name": "{{ cookiecutter.project_slug.replace('-', '_') }}", + "class_name": "{{ cookiecutter.project_name.replace('-', ' ').replace('_', ' ').title().replace(' ', '') }}", "full_name": "Jane Doe", "email": "jane@example.com", "github_username": "janedoe", diff --git a/templates/react/{{cookiecutter.project_slug}}/Makefile b/templates/react/{{cookiecutter.project_slug}}/Makefile index 2990875..d704b9a 100644 --- a/templates/react/{{cookiecutter.project_slug}}/Makefile +++ b/templates/react/{{cookiecutter.project_slug}}/Makefile @@ -29,11 +29,11 @@ install-backend: venv ## Install dependencies of the extension install-frontend: venv ## Install dependencies of the frontend cd $(FRONTEND_FOLDER) && yarn install -build-frontend: # Build the react app - ifeq ($(wildcard $(FRONTEND_FOLDER)/node_modules),) - $(MAKE) install-frontend - endif - cd $(FRONTEND_FOLDER); rm -rf build && REACT_APP_DEVELOPMENT_ENVIRONMENT=false NODE_ENV=prod npm run build +build-frontend: # Build the React app + @if [ ! -d "$(FRONTEND_FOLDER)/node_modules" ]; then \ + $(MAKE) install-frontend; \ + fi + cd $(FRONTEND_FOLDER); rm -rf build && REACT_APP_DEVELOPMENT_ENVIRONMENT=false NODE_ENV=prod npm run build start-frontend: ## Start the frontend in dev mode (hot reload) cd $(FRONTEND_FOLDER); REACT_APP_DEVELOPMENT_ENVIRONMENT=true yarn start diff --git a/templates/react/{{cookiecutter.project_slug}}/backend/{{cookiecutter.module_name}}/extension.py b/templates/react/{{cookiecutter.project_slug}}/backend/{{cookiecutter.module_name}}/extension.py index 789ef79..be97f23 100644 --- a/templates/react/{{cookiecutter.project_slug}}/backend/{{cookiecutter.module_name}}/extension.py +++ b/templates/react/{{cookiecutter.project_slug}}/backend/{{cookiecutter.module_name}}/extension.py @@ -8,7 +8,7 @@ LOG = logging.getLogger(__name__) -class MyExtension(WebAppExtension): +class {{ cookiecutter.class_name }}(WebAppExtension): name = "{{ cookiecutter.project_slug }}" def __init__(self): diff --git a/templates/react/{{cookiecutter.project_slug}}/setup.cfg b/templates/react/{{cookiecutter.project_slug}}/setup.cfg index 433cbf6..f51c8e3 100644 --- a/templates/react/{{cookiecutter.project_slug}}/setup.cfg +++ b/templates/react/{{cookiecutter.project_slug}}/setup.cfg @@ -24,7 +24,7 @@ test= [options.entry_points] localstack.extensions = - {{ cookiecutter.module_name }} = {{ cookiecutter.module_name }}.extension:MyExtension + {{ cookiecutter.module_name }} = {{ cookiecutter.module_name }}.extension:{{ cookiecutter.class_name }} [options.package_data] {{ cookiecutter.module_name }} = From 5b8aa917e846fa63b3cd0ee88d60c503bf83bc77 Mon Sep 17 00:00:00 2001 From: Pive01 Date: Wed, 24 Jul 2024 17:00:23 +0200 Subject: [PATCH 26/35] update requirements in base template --- templates/basic/{{cookiecutter.project_slug}}/setup.cfg | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/templates/basic/{{cookiecutter.project_slug}}/setup.cfg b/templates/basic/{{cookiecutter.project_slug}}/setup.cfg index 3bbcb46..32c9e6c 100644 --- a/templates/basic/{{cookiecutter.project_slug}}/setup.cfg +++ b/templates/basic/{{cookiecutter.project_slug}}/setup.cfg @@ -12,8 +12,10 @@ long_description_content_type = text/markdown; charset=UTF-8 [options] zip_safe = False packages = find: -install_requires = - localstack>=1.0 + +[options.extras_require] +test= + localstack-core>=2.2 [options.entry_points] localstack.extensions = From 8911b91e0ed6f9e6b849ba6c7c2315291cc76dc4 Mon Sep 17 00:00:00 2001 From: Dominik Schubert Date: Thu, 25 Jul 2024 14:06:24 +0200 Subject: [PATCH 27/35] use pyproject.toml for react template --- .../{{cookiecutter.project_slug}}/Makefile | 9 +++-- .../pyproject.toml | 34 +++++++++++++++++++ .../{{cookiecutter.project_slug}}/setup.cfg | 31 ----------------- .../{{cookiecutter.project_slug}}/setup.py | 4 --- 4 files changed, 38 insertions(+), 40 deletions(-) create mode 100644 templates/react/{{cookiecutter.project_slug}}/pyproject.toml delete mode 100644 templates/react/{{cookiecutter.project_slug}}/setup.cfg delete mode 100644 templates/react/{{cookiecutter.project_slug}}/setup.py diff --git a/templates/react/{{cookiecutter.project_slug}}/Makefile b/templates/react/{{cookiecutter.project_slug}}/Makefile index d704b9a..2b3ca47 100644 --- a/templates/react/{{cookiecutter.project_slug}}/Makefile +++ b/templates/react/{{cookiecutter.project_slug}}/Makefile @@ -11,9 +11,9 @@ NO_COLOR = \033[m venv: $(VENV_ACTIVATE) -$(VENV_ACTIVATE): setup.py setup.cfg +$(VENV_ACTIVATE): pyproject.toml test -d .venv || $(VENV_BIN) .venv - $(VENV_RUN); pip install --upgrade pip setuptools plux + $(VENV_RUN); pip install --upgrade pip setuptools plux build $(VENV_RUN); pip install -e . touch $(VENV_DIR)/bin/activate @@ -24,7 +24,6 @@ clean: ## Clean the project rm -rf $(BACKEND_FOLDER)/*.egg-info/ install-backend: venv ## Install dependencies of the extension - $(VENV_RUN); python setup.py develop install-frontend: venv ## Install dependencies of the frontend cd $(FRONTEND_FOLDER) && yarn install @@ -41,7 +40,7 @@ start-frontend: ## Start the frontend in dev mode (hot reload) install: venv install-backend install-frontend ## Install dependencies dist: venv build-frontend ## Create distribution files - $(VENV_RUN); python setup.py sdist bdist_wheel + $(VENV_RUN); python -m build publish: clean-dist venv dist ## Build and upload package to pypi $(VENV_RUN); pip install --upgrade twine; twine upload dist/* @@ -53,4 +52,4 @@ help: ## Show this help @echo Please specify a build target. The choices are: @grep -E '^[0-9a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "$(INFO_COLOR)%-30s$(NO_COLOR) %s\n", $$1, $$2}' -.PHONY: clean clean-dist dist install install-backend install-frontend build-frontend start-frontend publish +.PHONY: clean clean-dist dist install install-backend install-frontend build-frontend start-frontend publish venv diff --git a/templates/react/{{cookiecutter.project_slug}}/pyproject.toml b/templates/react/{{cookiecutter.project_slug}}/pyproject.toml new file mode 100644 index 0000000..a3f0ded --- /dev/null +++ b/templates/react/{{cookiecutter.project_slug}}/pyproject.toml @@ -0,0 +1,34 @@ +[build-system] +requires = ["setuptools", 'wheel', 'plux>=1.3.1'] +build-backend = "setuptools.build_meta" + +[project] +name = "{{ cookiecutter.project_slug }}" +version = "{{ cookiecutter.version }}" +description = "LocalStack Extension: {{ cookiecutter.project_name }}" +readme = {file = "README.md", content-type = "text/markdown; charset=UTF-8"} +requires-python = ">=3.8" +license = {text = "UNLICENSED"} +authors = [ + { name = "{{ cookiecutter.full_name }}", email = "{{ cookiecutter.email }}" } +] +keywords = ["localstack", "localstack-extension", "extension"] +classifiers = [] + +[project.urls] +Homepage = "https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.project_slug }}" + +[project.optional-dependencies] +test = ["localstack-core>=2.2"] + +[project.scripts] +{{ cookiecutter.module_name }} = "{{ cookiecutter.module_name }}.extension:{{ cookiecutter.class_name }}" + +[tool.setuptools] +package-dir = {"" = "backend"} + +[tool.setuptools.packages.find] +where = ["backend"] + +[tool.setuptools.package-data] +"{{ cookiecutter.module_name }}" = ["static/*"] \ No newline at end of file diff --git a/templates/react/{{cookiecutter.project_slug}}/setup.cfg b/templates/react/{{cookiecutter.project_slug}}/setup.cfg deleted file mode 100644 index f51c8e3..0000000 --- a/templates/react/{{cookiecutter.project_slug}}/setup.cfg +++ /dev/null @@ -1,31 +0,0 @@ -[metadata] -name = {{ cookiecutter.project_slug }} -version = {{ cookiecutter.version }} -summary = LocalStack Extension: {{ cookiecutter.project_name }} -url = https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.project_slug }} -author = {{ cookiecutter.full_name }} -author_email = {{ cookiecutter.email }} -description = {{ cookiecutter.project_short_description }} -long_description = file: README.md -long_description_content_type = text/markdown; charset=UTF-8 - -[options] -zip_safe = False -package_dir= - =backend -packages = find: - -[options.packages.find] -where=backend - -[options.extras_require] -test= - localstack-core>=2.2 - -[options.entry_points] -localstack.extensions = - {{ cookiecutter.module_name }} = {{ cookiecutter.module_name }}.extension:{{ cookiecutter.class_name }} - -[options.package_data] -{{ cookiecutter.module_name }} = - static/* diff --git a/templates/react/{{cookiecutter.project_slug}}/setup.py b/templates/react/{{cookiecutter.project_slug}}/setup.py deleted file mode 100644 index c823345..0000000 --- a/templates/react/{{cookiecutter.project_slug}}/setup.py +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env python -from setuptools import setup - -setup() From 851741702d098d914cb9d9075f59ca5f7b575053 Mon Sep 17 00:00:00 2001 From: Dominik Schubert Date: Thu, 25 Jul 2024 14:07:43 +0200 Subject: [PATCH 28/35] extend gitignore for react template --- templates/react/{{cookiecutter.project_slug}}/.gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/templates/react/{{cookiecutter.project_slug}}/.gitignore b/templates/react/{{cookiecutter.project_slug}}/.gitignore index 04336b6..efb099f 100644 --- a/templates/react/{{cookiecutter.project_slug}}/.gitignore +++ b/templates/react/{{cookiecutter.project_slug}}/.gitignore @@ -4,4 +4,6 @@ frontend/.yarn dist build **/*.egg-info -.eggs \ No newline at end of file +.eggs +__pycache__ +*.pyc \ No newline at end of file From 1067819860062eef1dee548fa03745b4cc0b6049 Mon Sep 17 00:00:00 2001 From: Dominik Schubert Date: Thu, 25 Jul 2024 14:17:04 +0200 Subject: [PATCH 29/35] install dev version of localstack-core --- templates/react/{{cookiecutter.project_slug}}/Makefile | 7 ++++--- .../react/{{cookiecutter.project_slug}}/pyproject.toml | 4 +++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/templates/react/{{cookiecutter.project_slug}}/Makefile b/templates/react/{{cookiecutter.project_slug}}/Makefile index 2b3ca47..71afff6 100644 --- a/templates/react/{{cookiecutter.project_slug}}/Makefile +++ b/templates/react/{{cookiecutter.project_slug}}/Makefile @@ -11,10 +11,10 @@ NO_COLOR = \033[m venv: $(VENV_ACTIVATE) -$(VENV_ACTIVATE): pyproject.toml +$(VENV_ACTIVATE): test -d .venv || $(VENV_BIN) .venv - $(VENV_RUN); pip install --upgrade pip setuptools plux build - $(VENV_RUN); pip install -e . + $(VENV_RUN); pip install --upgrade pip setuptools plux build wheel + $(VENV_RUN); pip install -e .[dev] touch $(VENV_DIR)/bin/activate clean: ## Clean the project @@ -24,6 +24,7 @@ clean: ## Clean the project rm -rf $(BACKEND_FOLDER)/*.egg-info/ install-backend: venv ## Install dependencies of the extension + $(VENV_RUN); python -m plux entrypoints install-frontend: venv ## Install dependencies of the frontend cd $(FRONTEND_FOLDER) && yarn install diff --git a/templates/react/{{cookiecutter.project_slug}}/pyproject.toml b/templates/react/{{cookiecutter.project_slug}}/pyproject.toml index a3f0ded..e6d41ae 100644 --- a/templates/react/{{cookiecutter.project_slug}}/pyproject.toml +++ b/templates/react/{{cookiecutter.project_slug}}/pyproject.toml @@ -19,7 +19,9 @@ classifiers = [] Homepage = "https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.project_slug }}" [project.optional-dependencies] -test = ["localstack-core>=2.2"] +dev = [ + "localstack>=0.0.0.dev" +] [project.scripts] {{ cookiecutter.module_name }} = "{{ cookiecutter.module_name }}.extension:{{ cookiecutter.class_name }}" From 0f3229f9744cf81d6996fbcf99583db4a1b16399 Mon Sep 17 00:00:00 2001 From: Pive01 Date: Fri, 26 Jul 2024 10:01:37 +0200 Subject: [PATCH 30/35] Changed other templates from setup to pyproject --- template/cookiecutter.json | 1 + .../{{cookiecutter.project_slug}}/Makefile | 2 +- .../pyproject.toml | 27 +++++++++++++++++++ .../{{cookiecutter.project_slug}}/setup.cfg | 20 -------------- .../{{cookiecutter.project_slug}}/setup.py | 4 --- .../{{cookiecutter.module_name}}/extension.py | 2 +- .../{{cookiecutter.project_slug}}/Makefile | 2 +- .../pyproject.toml | 27 +++++++++++++++++++ 8 files changed, 58 insertions(+), 27 deletions(-) create mode 100644 template/{{cookiecutter.project_slug}}/pyproject.toml delete mode 100644 template/{{cookiecutter.project_slug}}/setup.cfg delete mode 100644 template/{{cookiecutter.project_slug}}/setup.py create mode 100644 templates/basic/{{cookiecutter.project_slug}}/pyproject.toml diff --git a/template/cookiecutter.json b/template/cookiecutter.json index 3d91d41..8b4ead9 100644 --- a/template/cookiecutter.json +++ b/template/cookiecutter.json @@ -3,6 +3,7 @@ "project_short_description": "All the boilerplate you need to create a LocalStack extension.", "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '-') }}", "module_name": "{{ cookiecutter.project_slug.replace('-', '_') }}", + "class_name": "{{ cookiecutter.project_name.replace('-', ' ').replace('_', ' ').title().replace(' ', '') }}", "full_name": "Jane Doe", "email": "jane@example.com", "github_username": "janedoe", diff --git a/template/{{cookiecutter.project_slug}}/Makefile b/template/{{cookiecutter.project_slug}}/Makefile index 0f12f48..ecc8d87 100644 --- a/template/{{cookiecutter.project_slug}}/Makefile +++ b/template/{{cookiecutter.project_slug}}/Makefile @@ -21,7 +21,7 @@ install: venv $(VENV_RUN); python setup.py develop dist: venv - $(VENV_RUN); python setup.py sdist bdist_wheel + $(VENV_RUN); python -m build publish: clean-dist venv dist $(VENV_RUN); pip install --upgrade twine; twine upload dist/* diff --git a/template/{{cookiecutter.project_slug}}/pyproject.toml b/template/{{cookiecutter.project_slug}}/pyproject.toml new file mode 100644 index 0000000..7af2c0b --- /dev/null +++ b/template/{{cookiecutter.project_slug}}/pyproject.toml @@ -0,0 +1,27 @@ +[build-system] +requires = ["setuptools", 'wheel', 'plux>=1.3.1'] +build-backend = "setuptools.build_meta" + +[project] +name = "{{ cookiecutter.project_slug }}" +version = "{{ cookiecutter.version }}" +description = "LocalStack Extension: {{ cookiecutter.project_name }}" +readme = {file = "README.md", content-type = "text/markdown; charset=UTF-8"} +requires-python = ">=3.8" +license = {text = "UNLICENSED"} +authors = [ + { name = "{{ cookiecutter.full_name }}", email = "{{ cookiecutter.email }}" } +] +keywords = ["localstack", "localstack-extension", "extension"] +classifiers = [] + +[project.urls] +Homepage = "https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.project_slug }}" + +[project.optional-dependencies] +dev = [ + "localstack>=0.0.0.dev" +] + +[project.scripts] +{{ cookiecutter.module_name }} = "{{ cookiecutter.module_name }}.extension:{{ cookiecutter.class_name }}" diff --git a/template/{{cookiecutter.project_slug}}/setup.cfg b/template/{{cookiecutter.project_slug}}/setup.cfg deleted file mode 100644 index 2bb3f02..0000000 --- a/template/{{cookiecutter.project_slug}}/setup.cfg +++ /dev/null @@ -1,20 +0,0 @@ -[metadata] -name = {{ cookiecutter.project_slug }} -version = {{ cookiecutter.version }} -summary = LocalStack Extension: {{ cookiecutter.project_name }} -url = https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.project_slug }} -author = {{ cookiecutter.full_name }} -author_email = {{ cookiecutter.email }} -description = {{ cookiecutter.project_short_description }} -long_description = file: README.md -long_description_content_type = text/markdown; charset=UTF-8 - -[options] -zip_safe = False -packages = find: -install_requires = - localstack>=1.0 - -[options.entry_points] -localstack.extensions = - {{ cookiecutter.project_slug }} = {{ cookiecutter.module_name }}.extension:MyExtension diff --git a/template/{{cookiecutter.project_slug}}/setup.py b/template/{{cookiecutter.project_slug}}/setup.py deleted file mode 100644 index c823345..0000000 --- a/template/{{cookiecutter.project_slug}}/setup.py +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env python -from setuptools import setup - -setup() diff --git a/template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py b/template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py index b833617..3c3671a 100644 --- a/template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py +++ b/template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py @@ -1,6 +1,6 @@ from localstack.extensions.api import Extension, http, aws -class MyExtension(Extension): +class {{ cookiecutter.class_name }}(Extension): name = "{{ cookiecutter.project_slug }}" def on_extension_load(self): diff --git a/templates/basic/{{cookiecutter.project_slug}}/Makefile b/templates/basic/{{cookiecutter.project_slug}}/Makefile index 0f12f48..ecc8d87 100644 --- a/templates/basic/{{cookiecutter.project_slug}}/Makefile +++ b/templates/basic/{{cookiecutter.project_slug}}/Makefile @@ -21,7 +21,7 @@ install: venv $(VENV_RUN); python setup.py develop dist: venv - $(VENV_RUN); python setup.py sdist bdist_wheel + $(VENV_RUN); python -m build publish: clean-dist venv dist $(VENV_RUN); pip install --upgrade twine; twine upload dist/* diff --git a/templates/basic/{{cookiecutter.project_slug}}/pyproject.toml b/templates/basic/{{cookiecutter.project_slug}}/pyproject.toml new file mode 100644 index 0000000..7af2c0b --- /dev/null +++ b/templates/basic/{{cookiecutter.project_slug}}/pyproject.toml @@ -0,0 +1,27 @@ +[build-system] +requires = ["setuptools", 'wheel', 'plux>=1.3.1'] +build-backend = "setuptools.build_meta" + +[project] +name = "{{ cookiecutter.project_slug }}" +version = "{{ cookiecutter.version }}" +description = "LocalStack Extension: {{ cookiecutter.project_name }}" +readme = {file = "README.md", content-type = "text/markdown; charset=UTF-8"} +requires-python = ">=3.8" +license = {text = "UNLICENSED"} +authors = [ + { name = "{{ cookiecutter.full_name }}", email = "{{ cookiecutter.email }}" } +] +keywords = ["localstack", "localstack-extension", "extension"] +classifiers = [] + +[project.urls] +Homepage = "https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.project_slug }}" + +[project.optional-dependencies] +dev = [ + "localstack>=0.0.0.dev" +] + +[project.scripts] +{{ cookiecutter.module_name }} = "{{ cookiecutter.module_name }}.extension:{{ cookiecutter.class_name }}" From 900077eb5a03d6a98fa29387f0c230e0f4f95cc7 Mon Sep 17 00:00:00 2001 From: Luca Pivetta <36865043+Pive01@users.noreply.github.com> Date: Fri, 26 Jul 2024 10:37:55 +0200 Subject: [PATCH 31/35] Update templates/react/{{cookiecutter.project_slug}}/pyproject.toml Co-authored-by: Dominik Schubert --- templates/react/{{cookiecutter.project_slug}}/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/react/{{cookiecutter.project_slug}}/pyproject.toml b/templates/react/{{cookiecutter.project_slug}}/pyproject.toml index e6d41ae..48e1d83 100644 --- a/templates/react/{{cookiecutter.project_slug}}/pyproject.toml +++ b/templates/react/{{cookiecutter.project_slug}}/pyproject.toml @@ -23,7 +23,7 @@ dev = [ "localstack>=0.0.0.dev" ] -[project.scripts] +[project.entry-points."localstack.extensions"] {{ cookiecutter.module_name }} = "{{ cookiecutter.module_name }}.extension:{{ cookiecutter.class_name }}" [tool.setuptools] From b80cc5f4ee1dc71283fb693b9a673e38d35f15e6 Mon Sep 17 00:00:00 2001 From: Pive01 Date: Fri, 26 Jul 2024 10:39:03 +0200 Subject: [PATCH 32/35] updated pyproject.toml --- template/{{cookiecutter.project_slug}}/pyproject.toml | 2 +- templates/basic/{{cookiecutter.project_slug}}/pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/template/{{cookiecutter.project_slug}}/pyproject.toml b/template/{{cookiecutter.project_slug}}/pyproject.toml index 7af2c0b..dacb4fd 100644 --- a/template/{{cookiecutter.project_slug}}/pyproject.toml +++ b/template/{{cookiecutter.project_slug}}/pyproject.toml @@ -23,5 +23,5 @@ dev = [ "localstack>=0.0.0.dev" ] -[project.scripts] +[project.entry-points."localstack.extensions"] {{ cookiecutter.module_name }} = "{{ cookiecutter.module_name }}.extension:{{ cookiecutter.class_name }}" diff --git a/templates/basic/{{cookiecutter.project_slug}}/pyproject.toml b/templates/basic/{{cookiecutter.project_slug}}/pyproject.toml index 7af2c0b..dacb4fd 100644 --- a/templates/basic/{{cookiecutter.project_slug}}/pyproject.toml +++ b/templates/basic/{{cookiecutter.project_slug}}/pyproject.toml @@ -23,5 +23,5 @@ dev = [ "localstack>=0.0.0.dev" ] -[project.scripts] +[project.entry-points."localstack.extensions"] {{ cookiecutter.module_name }} = "{{ cookiecutter.module_name }}.extension:{{ cookiecutter.class_name }}" From e659844286c404a7520ff27787f092cc4c6268bc Mon Sep 17 00:00:00 2001 From: Pive01 Date: Mon, 29 Jul 2024 10:30:42 +0200 Subject: [PATCH 33/35] Added checks for corepack / yarn stuff --- .../react/{{cookiecutter.project_slug}}/Makefile | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/templates/react/{{cookiecutter.project_slug}}/Makefile b/templates/react/{{cookiecutter.project_slug}}/Makefile index 71afff6..d683965 100644 --- a/templates/react/{{cookiecutter.project_slug}}/Makefile +++ b/templates/react/{{cookiecutter.project_slug}}/Makefile @@ -4,6 +4,8 @@ VENV_ACTIVATE = $(VENV_DIR)/bin/activate VENV_RUN = . $(VENV_ACTIVATE) FRONTEND_FOLDER = frontend BACKEND_FOLDER = backend +COREPACK_EXISTS := $(shell command -v corepack) +YARN_EXISTS := $(shell command -v yarn) INFO_COLOR = \033[0;36m @@ -17,6 +19,14 @@ $(VENV_ACTIVATE): $(VENV_RUN); pip install -e .[dev] touch $(VENV_DIR)/bin/activate +check-frontend-deps: + @if [ -z "$(YARN_EXISTS)" ]; then \ + npm install --global yarn; \ + fi + @if [ -z "$(COREPACK_EXISTS)" ]; then \ + npm install -g corepack; \ + fi + clean: ## Clean the project rm -rf .venv/ rm -rf build/ @@ -26,7 +36,7 @@ clean: ## Clean the project install-backend: venv ## Install dependencies of the extension $(VENV_RUN); python -m plux entrypoints -install-frontend: venv ## Install dependencies of the frontend +install-frontend: venv check-frontend-deps ## Install dependencies of the frontend cd $(FRONTEND_FOLDER) && yarn install build-frontend: # Build the React app From 9f93c0cbaf17d7aafd2decda2606b8e9b5fab488 Mon Sep 17 00:00:00 2001 From: Pive01 Date: Mon, 29 Jul 2024 10:51:04 +0200 Subject: [PATCH 34/35] added .pth for package discovery --- templates/react/{{cookiecutter.project_slug}}/backend.pth | 1 + 1 file changed, 1 insertion(+) create mode 100644 templates/react/{{cookiecutter.project_slug}}/backend.pth diff --git a/templates/react/{{cookiecutter.project_slug}}/backend.pth b/templates/react/{{cookiecutter.project_slug}}/backend.pth new file mode 100644 index 0000000..98cd9e7 --- /dev/null +++ b/templates/react/{{cookiecutter.project_slug}}/backend.pth @@ -0,0 +1 @@ +backend \ No newline at end of file From 859faaf39dd459e403b465deca15c6244159c3cc Mon Sep 17 00:00:00 2001 From: Thomas Rausch Date: Fri, 16 Aug 2024 19:42:43 +0200 Subject: [PATCH 35/35] reset changes to original template --- template/cookiecutter.json | 1 - .../{{cookiecutter.project_slug}}/Makefile | 2 +- .../pyproject.toml | 27 ------------------- .../{{cookiecutter.project_slug}}/setup.cfg | 22 +++++++++++++++ .../{{cookiecutter.project_slug}}/setup.py | 0 .../{{cookiecutter.module_name}}/extension.py | 2 +- 6 files changed, 24 insertions(+), 30 deletions(-) delete mode 100644 template/{{cookiecutter.project_slug}}/pyproject.toml create mode 100644 template/{{cookiecutter.project_slug}}/setup.cfg rename {templates/basic => template}/{{cookiecutter.project_slug}}/setup.py (100%) diff --git a/template/cookiecutter.json b/template/cookiecutter.json index 8b4ead9..3d91d41 100644 --- a/template/cookiecutter.json +++ b/template/cookiecutter.json @@ -3,7 +3,6 @@ "project_short_description": "All the boilerplate you need to create a LocalStack extension.", "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '-') }}", "module_name": "{{ cookiecutter.project_slug.replace('-', '_') }}", - "class_name": "{{ cookiecutter.project_name.replace('-', ' ').replace('_', ' ').title().replace(' ', '') }}", "full_name": "Jane Doe", "email": "jane@example.com", "github_username": "janedoe", diff --git a/template/{{cookiecutter.project_slug}}/Makefile b/template/{{cookiecutter.project_slug}}/Makefile index efd455a..c3d6a3e 100644 --- a/template/{{cookiecutter.project_slug}}/Makefile +++ b/template/{{cookiecutter.project_slug}}/Makefile @@ -20,7 +20,7 @@ install: venv $(VENV_RUN); python -m pip install -e .[dev] dist: venv - $(VENV_RUN); python -m build + $(VENV_RUN); python setup.py sdist bdist_wheel publish: clean-dist venv dist $(VENV_RUN); pip install --upgrade twine; twine upload dist/* diff --git a/template/{{cookiecutter.project_slug}}/pyproject.toml b/template/{{cookiecutter.project_slug}}/pyproject.toml deleted file mode 100644 index dacb4fd..0000000 --- a/template/{{cookiecutter.project_slug}}/pyproject.toml +++ /dev/null @@ -1,27 +0,0 @@ -[build-system] -requires = ["setuptools", 'wheel', 'plux>=1.3.1'] -build-backend = "setuptools.build_meta" - -[project] -name = "{{ cookiecutter.project_slug }}" -version = "{{ cookiecutter.version }}" -description = "LocalStack Extension: {{ cookiecutter.project_name }}" -readme = {file = "README.md", content-type = "text/markdown; charset=UTF-8"} -requires-python = ">=3.8" -license = {text = "UNLICENSED"} -authors = [ - { name = "{{ cookiecutter.full_name }}", email = "{{ cookiecutter.email }}" } -] -keywords = ["localstack", "localstack-extension", "extension"] -classifiers = [] - -[project.urls] -Homepage = "https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.project_slug }}" - -[project.optional-dependencies] -dev = [ - "localstack>=0.0.0.dev" -] - -[project.entry-points."localstack.extensions"] -{{ cookiecutter.module_name }} = "{{ cookiecutter.module_name }}.extension:{{ cookiecutter.class_name }}" diff --git a/template/{{cookiecutter.project_slug}}/setup.cfg b/template/{{cookiecutter.project_slug}}/setup.cfg new file mode 100644 index 0000000..17145a0 --- /dev/null +++ b/template/{{cookiecutter.project_slug}}/setup.cfg @@ -0,0 +1,22 @@ +[metadata] +name = {{ cookiecutter.project_slug }} +version = {{ cookiecutter.version }} +summary = LocalStack Extension: {{ cookiecutter.project_name }} +url = https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.project_slug }} +author = {{ cookiecutter.full_name }} +author_email = {{ cookiecutter.email }} +description = {{ cookiecutter.project_short_description }} +long_description = file: README.md +long_description_content_type = text/markdown; charset=UTF-8 + +[options] +zip_safe = False +packages = find: + +[options.extras_require] +dev = + localstack-core>=1.0 + +[options.entry_points] +localstack.extensions = + {{ cookiecutter.project_slug }} = {{ cookiecutter.module_name }}.extension:MyExtension diff --git a/templates/basic/{{cookiecutter.project_slug}}/setup.py b/template/{{cookiecutter.project_slug}}/setup.py similarity index 100% rename from templates/basic/{{cookiecutter.project_slug}}/setup.py rename to template/{{cookiecutter.project_slug}}/setup.py diff --git a/template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py b/template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py index 3c3671a..b833617 100644 --- a/template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py +++ b/template/{{cookiecutter.project_slug}}/{{cookiecutter.module_name}}/extension.py @@ -1,6 +1,6 @@ from localstack.extensions.api import Extension, http, aws -class {{ cookiecutter.class_name }}(Extension): +class MyExtension(Extension): name = "{{ cookiecutter.project_slug }}" def on_extension_load(self):