@aurostack/stacks 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +209 -0
- package/cli/src/extract.mjs +165 -0
- package/cli/src/fsx.mjs +197 -0
- package/cli/src/generate.mjs +235 -0
- package/cli/src/hooks.mjs +55 -0
- package/cli/src/manifest.mjs +163 -0
- package/cli/src/strip.mjs +208 -0
- package/cli/src/tokens.mjs +102 -0
- package/cli/stack.mjs +672 -0
- package/package.json +37 -0
- package/templates/nest-api/files/.bin/db.ts +123 -0
- package/templates/nest-api/files/.bin/dc.ts +74 -0
- package/templates/nest-api/files/.bin/helpers.ts +49 -0
- package/templates/nest-api/files/.bin/secrets.ts +68 -0
- package/templates/nest-api/files/.bin/start.ts +47 -0
- package/templates/nest-api/files/.dockerignore +7 -0
- package/templates/nest-api/files/.env.example +91 -0
- package/templates/nest-api/files/.env.test.example +75 -0
- package/templates/nest-api/files/.forgejo/workflows/build-and-push.yml +41 -0
- package/templates/nest-api/files/.forgejo/workflows/test-e2e.yml +83 -0
- package/templates/nest-api/files/.forgejo/workflows/test.yml +53 -0
- package/templates/nest-api/files/.npmrc.example +1 -0
- package/templates/nest-api/files/.nvmrc +1 -0
- package/templates/nest-api/files/.prettierrc +8 -0
- package/templates/nest-api/files/.swcrc +15 -0
- package/templates/nest-api/files/.watchmanconfig +3 -0
- package/templates/nest-api/files/.yarnrc.yml +1 -0
- package/templates/nest-api/files/Dockerfile +40 -0
- package/templates/nest-api/files/__mocks__/activation-twofa.js +7 -0
- package/templates/nest-api/files/__mocks__/activation.js +7 -0
- package/templates/nest-api/files/__mocks__/forgot-password.js +7 -0
- package/templates/nest-api/files/__mocks__/main-layout.js +7 -0
- package/templates/nest-api/files/__mocks__/password-changed.js +7 -0
- package/templates/nest-api/files/__mocks__/reset-password.js +7 -0
- package/templates/nest-api/files/__mocks__/set-password.js +7 -0
- package/templates/nest-api/files/__mocks__/welcome.js +7 -0
- package/templates/nest-api/files/_gitignore +62 -0
- package/templates/nest-api/files/compose.test.yml +33 -0
- package/templates/nest-api/files/compose.yml +39 -0
- package/templates/nest-api/files/emails/activation-twofa.tsx +58 -0
- package/templates/nest-api/files/emails/activation.tsx +36 -0
- package/templates/nest-api/files/emails/forgot-password.tsx +29 -0
- package/templates/nest-api/files/emails/main-layout.tsx +134 -0
- package/templates/nest-api/files/emails/password-changed.tsx +24 -0
- package/templates/nest-api/files/emails/reset-password.tsx +24 -0
- package/templates/nest-api/files/emails/set-password.tsx +25 -0
- package/templates/nest-api/files/emails/welcome.tsx +39 -0
- package/templates/nest-api/files/eslint.config.mjs +28 -0
- package/templates/nest-api/files/global.d.ts +5 -0
- package/templates/nest-api/files/nest-cli.json +8 -0
- package/templates/nest-api/files/package.json +150 -0
- package/templates/nest-api/files/prisma/schema/auth.prisma +75 -0
- package/templates/nest-api/files/prisma/schema/base.prisma +17 -0
- package/templates/nest-api/files/prisma/schema/enum.prisma +17 -0
- package/templates/nest-api/files/prisma/schema/notification.prisma +14 -0
- package/templates/nest-api/files/prisma.config.ts +13 -0
- package/templates/nest-api/files/public/.gitkeep +0 -0
- package/templates/nest-api/files/seeders/index.ts +27 -0
- package/templates/nest-api/files/seeders/util.ts +88 -0
- package/templates/nest-api/files/src/__tests__/app.controller.spec.ts +29 -0
- package/templates/nest-api/files/src/app.controller.ts +40 -0
- package/templates/nest-api/files/src/app.module.ts +268 -0
- package/templates/nest-api/files/src/app.resolver.ts +32 -0
- package/templates/nest-api/files/src/app.setup.ts +178 -0
- package/templates/nest-api/files/src/common/__tests__/auth.service.spec.ts +31 -0
- package/templates/nest-api/files/src/common/__tests__/cache.service.spec.ts +214 -0
- package/templates/nest-api/files/src/common/__tests__/config.service.spec.ts +56 -0
- package/templates/nest-api/files/src/common/__tests__/generator.service.spec.ts +114 -0
- package/templates/nest-api/files/src/common/__tests__/health.controller.spec.ts +72 -0
- package/templates/nest-api/files/src/common/__tests__/helpers.spec.ts +124 -0
- package/templates/nest-api/files/src/common/__tests__/mail.service.spec.ts +75 -0
- package/templates/nest-api/files/src/common/__tests__/prisma.indicator.spec.ts +39 -0
- package/templates/nest-api/files/src/common/__tests__/prisma.service.spec.ts +15 -0
- package/templates/nest-api/files/src/common/__tests__/records.spec.ts +87 -0
- package/templates/nest-api/files/src/common/__tests__/schemas.spec.ts +142 -0
- package/templates/nest-api/files/src/common/__tests__/throttler-storage.service.spec.ts +80 -0
- package/templates/nest-api/files/src/common/common.module.ts +72 -0
- package/templates/nest-api/files/src/common/constants/index.ts +2 -0
- package/templates/nest-api/files/src/common/constants/options.ts +52 -0
- package/templates/nest-api/files/src/common/constants/pino.ts +24 -0
- package/templates/nest-api/files/src/common/controllers/health.controller.ts +54 -0
- package/templates/nest-api/files/src/common/controllers/index.ts +2 -0
- package/templates/nest-api/files/src/common/controllers/metrics.controller.ts +21 -0
- package/templates/nest-api/files/src/common/decorators/index.ts +2 -0
- package/templates/nest-api/files/src/common/decorators/misc.decorator.ts +49 -0
- package/templates/nest-api/files/src/common/decorators/multi-part.decorator.ts +6 -0
- package/templates/nest-api/files/src/common/dto/filters.dto.ts +25 -0
- package/templates/nest-api/files/src/common/dto/index.ts +1 -0
- package/templates/nest-api/files/src/common/entity/index.ts +2 -0
- package/templates/nest-api/files/src/common/entity/ok.entity.ts +11 -0
- package/templates/nest-api/files/src/common/entity/pagination.entity.ts +24 -0
- package/templates/nest-api/files/src/common/exceptions/index.ts +1 -0
- package/templates/nest-api/files/src/common/exceptions/prisma.exception.ts +57 -0
- package/templates/nest-api/files/src/common/guards/feature-flag.guard.ts +51 -0
- package/templates/nest-api/files/src/common/guards/index.ts +1 -0
- package/templates/nest-api/files/src/common/interceptors/index.ts +1 -0
- package/templates/nest-api/files/src/common/interceptors/metrics.interceptor.ts +37 -0
- package/templates/nest-api/files/src/common/misc/helpers.ts +26 -0
- package/templates/nest-api/files/src/common/misc/index.ts +3 -0
- package/templates/nest-api/files/src/common/misc/origin-builder.ts +56 -0
- package/templates/nest-api/files/src/common/misc/prisma.indicator.ts +24 -0
- package/templates/nest-api/files/src/common/modules/index.ts +3 -0
- package/templates/nest-api/files/src/common/modules/logger.module.ts +104 -0
- package/templates/nest-api/files/src/common/modules/metrics.module.ts +28 -0
- package/templates/nest-api/files/src/common/modules/queue.module.ts +23 -0
- package/templates/nest-api/files/src/common/processors/index.ts +1 -0
- package/templates/nest-api/files/src/common/processors/mail/index.ts +47 -0
- package/templates/nest-api/files/src/common/processors/mail/process.ts +225 -0
- package/templates/nest-api/files/src/common/schemas/fields.ts +76 -0
- package/templates/nest-api/files/src/common/schemas/index.ts +1 -0
- package/templates/nest-api/files/src/common/services/auth-rate-limit.storage.ts +79 -0
- package/templates/nest-api/files/src/common/services/auth.service.ts +16 -0
- package/templates/nest-api/files/src/common/services/cache.service.ts +118 -0
- package/templates/nest-api/files/src/common/services/config.service.ts +388 -0
- package/templates/nest-api/files/src/common/services/feature-flag.service.ts +117 -0
- package/templates/nest-api/files/src/common/services/generator.service.ts +54 -0
- package/templates/nest-api/files/src/common/services/index.ts +10 -0
- package/templates/nest-api/files/src/common/services/logger.service.ts +14 -0
- package/templates/nest-api/files/src/common/services/mail.service.ts +44 -0
- package/templates/nest-api/files/src/common/services/prisma.service.ts +106 -0
- package/templates/nest-api/files/src/common/services/throttler-storage.service.ts +112 -0
- package/templates/nest-api/files/src/common/types/email.ts +55 -0
- package/templates/nest-api/files/src/common/types/index.ts +3 -0
- package/templates/nest-api/files/src/common/types/misc.ts +20 -0
- package/templates/nest-api/files/src/common/types/prisma.ts +18 -0
- package/templates/nest-api/files/src/common/utils/enum.ts +39 -0
- package/templates/nest-api/files/src/common/utils/helpers.ts +139 -0
- package/templates/nest-api/files/src/common/utils/index.ts +5 -0
- package/templates/nest-api/files/src/common/utils/ip.ts +22 -0
- package/templates/nest-api/files/src/common/utils/records.ts +66 -0
- package/templates/nest-api/files/src/common/utils/redis.keys.ts +31 -0
- package/templates/nest-api/files/src/lib/__tests__/access.spec.ts +33 -0
- package/templates/nest-api/files/src/lib/access.ts +114 -0
- package/templates/nest-api/files/src/lib/auth.ts +76 -0
- package/templates/nest-api/files/src/lib/rate-limit.ts +20 -0
- package/templates/nest-api/files/src/main.ts +28 -0
- package/templates/nest-api/files/src/media/__tests__/media.service.spec.ts +60 -0
- package/templates/nest-api/files/src/media/__tests__/s3.service.spec.ts +159 -0
- package/templates/nest-api/files/src/media/entity/file.entity.ts +7 -0
- package/templates/nest-api/files/src/media/entity/index.ts +1 -0
- package/templates/nest-api/files/src/media/media.module.ts +20 -0
- package/templates/nest-api/files/src/media/processors/index.ts +44 -0
- package/templates/nest-api/files/src/media/services/index.ts +2 -0
- package/templates/nest-api/files/src/media/services/media.service.ts +29 -0
- package/templates/nest-api/files/src/media/services/s3.service.ts +168 -0
- package/templates/nest-api/files/src/notifications/controllers/index.ts +1 -0
- package/templates/nest-api/files/src/notifications/controllers/notifications.controller.ts +72 -0
- package/templates/nest-api/files/src/notifications/dto/index.ts +1 -0
- package/templates/nest-api/files/src/notifications/dto/notification.dto.ts +11 -0
- package/templates/nest-api/files/src/notifications/entity/index.ts +1 -0
- package/templates/nest-api/files/src/notifications/entity/notification.entity.ts +37 -0
- package/templates/nest-api/files/src/notifications/notifications.module.ts +11 -0
- package/templates/nest-api/files/src/notifications/services/index.ts +1 -0
- package/templates/nest-api/files/src/notifications/services/notifications.service.ts +98 -0
- package/templates/nest-api/files/src/realtime/__tests__/events.gateway.spec.ts +88 -0
- package/templates/nest-api/files/src/realtime/__tests__/rooms.spec.ts +29 -0
- package/templates/nest-api/files/src/realtime/__tests__/ws-permissions.guard.spec.ts +54 -0
- package/templates/nest-api/files/src/realtime/adapters/redis-io.adapter.ts +57 -0
- package/templates/nest-api/files/src/realtime/constants/index.ts +68 -0
- package/templates/nest-api/files/src/realtime/decorators/index.ts +1 -0
- package/templates/nest-api/files/src/realtime/decorators/ws-permissions.decorator.ts +14 -0
- package/templates/nest-api/files/src/realtime/gateways/events.gateway.ts +187 -0
- package/templates/nest-api/files/src/realtime/guards/index.ts +2 -0
- package/templates/nest-api/files/src/realtime/guards/ws-auth.guard.ts +20 -0
- package/templates/nest-api/files/src/realtime/guards/ws-permissions.guard.ts +35 -0
- package/templates/nest-api/files/src/realtime/misc/session-from-socket.ts +54 -0
- package/templates/nest-api/files/src/realtime/realtime.module.ts +26 -0
- package/templates/nest-api/files/src/realtime/services/presence.service.ts +56 -0
- package/templates/nest-api/files/src/realtime/services/realtime.service.ts +72 -0
- package/templates/nest-api/files/src/users/__tests__/current-user.controller.spec.ts +77 -0
- package/templates/nest-api/files/src/users/__tests__/current-user.service.spec.ts +159 -0
- package/templates/nest-api/files/src/users/__tests__/user.entity.spec.ts +175 -0
- package/templates/nest-api/files/src/users/__tests__/users.controller.spec.ts +89 -0
- package/templates/nest-api/files/src/users/__tests__/users.service.spec.ts +398 -0
- package/templates/nest-api/files/src/users/controllers/current-user.controller.ts +82 -0
- package/templates/nest-api/files/src/users/controllers/index.ts +2 -0
- package/templates/nest-api/files/src/users/controllers/users.controller.ts +40 -0
- package/templates/nest-api/files/src/users/decorators/index.ts +1 -0
- package/templates/nest-api/files/src/users/decorators/permissions.decorator.ts +24 -0
- package/templates/nest-api/files/src/users/dto/avatar.dto.ts +13 -0
- package/templates/nest-api/files/src/users/dto/filters.dto.ts +8 -0
- package/templates/nest-api/files/src/users/dto/index.ts +2 -0
- package/templates/nest-api/files/src/users/entity/index.ts +1 -0
- package/templates/nest-api/files/src/users/entity/user.entity.ts +53 -0
- package/templates/nest-api/files/src/users/services/current-user.service.ts +46 -0
- package/templates/nest-api/files/src/users/services/index.ts +2 -0
- package/templates/nest-api/files/src/users/services/users.service.ts +88 -0
- package/templates/nest-api/files/src/users/users.module.ts +10 -0
- package/templates/nest-api/files/test/app.spec.ts +102 -0
- package/templates/nest-api/files/test/auth.spec.ts +108 -0
- package/templates/nest-api/files/test/current-user.spec.ts +154 -0
- package/templates/nest-api/files/test/factory/app.ts +172 -0
- package/templates/nest-api/files/test/factory/constants.ts +22 -0
- package/templates/nest-api/files/test/factory/dto.ts +27 -0
- package/templates/nest-api/files/test/factory/entity.ts +70 -0
- package/templates/nest-api/files/test/factory/gen.ts +75 -0
- package/templates/nest-api/files/test/factory/util.ts +21 -0
- package/templates/nest-api/files/test/notifications.spec.ts +176 -0
- package/templates/nest-api/files/test/rate-limit.spec.ts +180 -0
- package/templates/nest-api/files/test/setup.ts +1 -0
- package/templates/nest-api/files/test/users.spec.ts +437 -0
- package/templates/nest-api/files/tsconfig.build.json +13 -0
- package/templates/nest-api/files/tsconfig.json +35 -0
- package/templates/nest-api/files/vitest.config.ts +53 -0
- package/templates/nest-api/template.json +452 -0
- package/templates/node-worker/files/.bin/db.ts +123 -0
- package/templates/node-worker/files/.bin/helpers.ts +49 -0
- package/templates/node-worker/files/.bin/secrets.ts +68 -0
- package/templates/node-worker/files/.dockerignore +5 -0
- package/templates/node-worker/files/.env.example +21 -0
- package/templates/node-worker/files/.forgejo/workflows/build-and-push.yml +41 -0
- package/templates/node-worker/files/.nvmrc +1 -0
- package/templates/node-worker/files/.prettierignore +4 -0
- package/templates/node-worker/files/.prettierrc +8 -0
- package/templates/node-worker/files/.yarnrc.yml +5 -0
- package/templates/node-worker/files/Dockerfile +63 -0
- package/templates/node-worker/files/Dockerfile.dev +59 -0
- package/templates/node-worker/files/_gitignore +48 -0
- package/templates/node-worker/files/ecosystem.config.cjs +10 -0
- package/templates/node-worker/files/eslint.config.js +37 -0
- package/templates/node-worker/files/package.json +67 -0
- package/templates/node-worker/files/prisma/_gitignore +1 -0
- package/templates/node-worker/files/prisma/schema/base.prisma +36 -0
- package/templates/node-worker/files/prisma.config.ts +13 -0
- package/templates/node-worker/files/src/config.ts +55 -0
- package/templates/node-worker/files/src/db.ts +118 -0
- package/templates/node-worker/files/src/index.ts +7 -0
- package/templates/node-worker/files/src/logger.ts +45 -0
- package/templates/node-worker/files/src/types.ts +23 -0
- package/templates/node-worker/files/src/utils/browser.ts +16 -0
- package/templates/node-worker/files/src/utils/date.ts +68 -0
- package/templates/node-worker/files/src/utils/helpers.ts +17 -0
- package/templates/node-worker/files/src/utils/number.ts +47 -0
- package/templates/node-worker/files/src/utils/worker.ts +29 -0
- package/templates/node-worker/files/src/workers/constants.ts +6 -0
- package/templates/node-worker/files/src/workers/example/index.ts +27 -0
- package/templates/node-worker/files/src/workers/index.ts +1 -0
- package/templates/node-worker/files/tsconfig.json +30 -0
- package/templates/node-worker/template.json +135 -0
- package/templates/py-worker/files/.dockerignore +176 -0
- package/templates/py-worker/files/.env.example +20 -0
- package/templates/py-worker/files/.forgejo/workflows/build-amd-push.yml +39 -0
- package/templates/py-worker/files/Dockerfile +10 -0
- package/templates/py-worker/files/README.md +3 -0
- package/templates/py-worker/files/_gitignore +176 -0
- package/templates/py-worker/files/config.py +89 -0
- package/templates/py-worker/files/models/decorators.py +42 -0
- package/templates/py-worker/files/models/enums.py +32 -0
- package/templates/py-worker/files/models/mixins.py +61 -0
- package/templates/py-worker/files/requirements.txt +18 -0
- package/templates/py-worker/files/utils/db.py +67 -0
- package/templates/py-worker/files/utils/logger.py +97 -0
- package/templates/py-worker/files/utils/misc.py +45 -0
- package/templates/py-worker/files/utils/worker.py +80 -0
- package/templates/py-worker/files/worker.py +41 -0
- package/templates/py-worker/files/workers/hello/process.py +22 -0
- package/templates/py-worker/template.json +87 -0
- package/templates/react-app/README.md +78 -0
- package/templates/react-app/derive.sh +128 -0
- package/templates/react-app/files/.bin/openapi.js +32 -0
- package/templates/react-app/files/.bin/secrets.js +47 -0
- package/templates/react-app/files/.dockerignore +16 -0
- package/templates/react-app/files/.editorconfig +12 -0
- package/templates/react-app/files/.env.example +34 -0
- package/templates/react-app/files/.forgejo/workflows/build-and-push.yml +55 -0
- package/templates/react-app/files/.forgejo/workflows/ci.yml +39 -0
- package/templates/react-app/files/.husky/pre-commit +1 -0
- package/templates/react-app/files/.nvmrc +1 -0
- package/templates/react-app/files/.prettierignore +6 -0
- package/templates/react-app/files/.prettierrc +9 -0
- package/templates/react-app/files/.yarnrc.yml +2 -0
- package/templates/react-app/files/Dockerfile +52 -0
- package/templates/react-app/files/_gitignore +33 -0
- package/templates/react-app/files/build.sh +53 -0
- package/templates/react-app/files/docker/nginx.conf +134 -0
- package/templates/react-app/files/eslint.config.mjs +75 -0
- package/templates/react-app/files/index.html +62 -0
- package/templates/react-app/files/openapi-ts.config.ts +22 -0
- package/templates/react-app/files/package.json +80 -0
- package/templates/react-app/files/src/app/nav.tsx +32 -0
- package/templates/react-app/files/src/app/providers.tsx +39 -0
- package/templates/react-app/files/src/app/router.tsx +142 -0
- package/templates/react-app/files/src/app/store.ts +20 -0
- package/templates/react-app/files/src/features/auth/components/auth-card.tsx +23 -0
- package/templates/react-app/files/src/features/auth/components/checkbox-field.tsx +32 -0
- package/templates/react-app/files/src/features/auth/components/google-button.tsx +41 -0
- package/templates/react-app/files/src/features/auth/components/or-divider.tsx +9 -0
- package/templates/react-app/files/src/features/auth/components/password-field.tsx +70 -0
- package/templates/react-app/files/src/features/auth/components/submit-button.tsx +16 -0
- package/templates/react-app/files/src/features/auth/lib/auth-actions.ts +68 -0
- package/templates/react-app/files/src/features/auth/lib/password-strength.ts +20 -0
- package/templates/react-app/files/src/features/auth/lib/redirect.ts +6 -0
- package/templates/react-app/files/src/features/auth/lib/schemas.ts +37 -0
- package/templates/react-app/files/src/features/seo/routes.ts +65 -0
- package/templates/react-app/files/src/lib/env.ts +28 -0
- package/templates/react-app/files/src/lib/paths.ts +58 -0
- package/templates/react-app/files/src/main.tsx +19 -0
- package/templates/react-app/files/src/routes/admin/home.tsx +24 -0
- package/templates/react-app/files/src/routes/auth/forgot-password.tsx +93 -0
- package/templates/react-app/files/src/routes/auth/login.tsx +87 -0
- package/templates/react-app/files/src/routes/auth/reset-password.tsx +83 -0
- package/templates/react-app/files/src/routes/auth/signup.tsx +117 -0
- package/templates/react-app/files/src/routes/auth/verified.tsx +31 -0
- package/templates/react-app/files/src/routes/auth/verify-email.tsx +97 -0
- package/templates/react-app/files/src/routes/home.tsx +17 -0
- package/templates/react-app/files/src/routes/legal/privacy.tsx +26 -0
- package/templates/react-app/files/src/routes/legal/terms.tsx +28 -0
- package/templates/react-app/files/src/routes/marketing/home.tsx +18 -0
- package/templates/react-app/files/src/routes/settings.tsx +10 -0
- package/templates/react-app/files/src/shared/api/base-api.ts +24 -0
- package/templates/react-app/files/src/shared/api/base-query.ts +29 -0
- package/templates/react-app/files/src/shared/api/config.ts +21 -0
- package/templates/react-app/files/src/shared/api/index.ts +15 -0
- package/templates/react-app/files/src/shared/api/realtime-events.ts +34 -0
- package/templates/react-app/files/src/shared/api/socket.ts +41 -0
- package/templates/react-app/files/src/shared/api/store.ts +39 -0
- package/templates/react-app/files/src/shared/api/upload-query.ts +115 -0
- package/templates/react-app/files/src/shared/auth/client.ts +27 -0
- package/templates/react-app/files/src/shared/auth/config.ts +28 -0
- package/templates/react-app/files/src/shared/auth/guards.tsx +75 -0
- package/templates/react-app/files/src/shared/auth/hooks.ts +13 -0
- package/templates/react-app/files/src/shared/auth/index.ts +20 -0
- package/templates/react-app/files/src/shared/auth/logout.ts +23 -0
- package/templates/react-app/files/src/shared/auth/provider.tsx +52 -0
- package/templates/react-app/files/src/shared/auth/redirect.ts +65 -0
- package/templates/react-app/files/src/shared/auth/slice.ts +54 -0
- package/templates/react-app/files/src/shared/hooks/index.ts +6 -0
- package/templates/react-app/files/src/shared/layouts/app-shell/app-shell.tsx +225 -0
- package/templates/react-app/files/src/shared/layouts/app-shell/user-menu.tsx +74 -0
- package/templates/react-app/files/src/shared/layouts/auth-layout.tsx +137 -0
- package/templates/react-app/files/src/shared/layouts/error-boundary.tsx +38 -0
- package/templates/react-app/files/src/shared/layouts/index.ts +23 -0
- package/templates/react-app/files/src/shared/layouts/marketing/marketing-layout.tsx +29 -0
- package/templates/react-app/files/src/shared/layouts/marketing/section-heading.tsx +38 -0
- package/templates/react-app/files/src/shared/layouts/marketing/section.tsx +30 -0
- package/templates/react-app/files/src/shared/layouts/states/app-shell-skeleton.tsx +47 -0
- package/templates/react-app/files/src/shared/layouts/states/empty.tsx +22 -0
- package/templates/react-app/files/src/shared/layouts/states/forbidden.tsx +14 -0
- package/templates/react-app/files/src/shared/layouts/states/loading.tsx +11 -0
- package/templates/react-app/files/src/shared/layouts/states/not-found.tsx +21 -0
- package/templates/react-app/files/src/shared/layouts/states/page-skeleton.tsx +39 -0
- package/templates/react-app/files/src/shared/layouts/states/route-fallback.tsx +26 -0
- package/templates/react-app/files/src/shared/layouts/states/state-screen.tsx +22 -0
- package/templates/react-app/files/src/shared/types/README.md +28 -0
- package/templates/react-app/files/src/shared/types/api/index.ts +9 -0
- package/templates/react-app/files/src/shared/types/api/zod.gen.ts +5 -0
- package/templates/react-app/files/src/shared/types/index.ts +4 -0
- package/templates/react-app/files/src/shared/ui/components/brand/logo.tsx +51 -0
- package/templates/react-app/files/src/shared/ui/components/brand/social-icons.tsx +37 -0
- package/templates/react-app/files/src/shared/ui/components/form/form.tsx +120 -0
- package/templates/react-app/files/src/shared/ui/components/ui/alert.tsx +25 -0
- package/templates/react-app/files/src/shared/ui/components/ui/button.tsx +43 -0
- package/templates/react-app/files/src/shared/ui/components/ui/calendar.tsx +78 -0
- package/templates/react-app/files/src/shared/ui/components/ui/card.tsx +44 -0
- package/templates/react-app/files/src/shared/ui/components/ui/checkbox.tsx +16 -0
- package/templates/react-app/files/src/shared/ui/components/ui/date-picker.tsx +76 -0
- package/templates/react-app/files/src/shared/ui/components/ui/input.tsx +22 -0
- package/templates/react-app/files/src/shared/ui/components/ui/label.tsx +19 -0
- package/templates/react-app/files/src/shared/ui/components/ui/modal.tsx +94 -0
- package/templates/react-app/files/src/shared/ui/components/ui/popover.tsx +31 -0
- package/templates/react-app/files/src/shared/ui/components/ui/progress.tsx +33 -0
- package/templates/react-app/files/src/shared/ui/components/ui/search-input.tsx +69 -0
- package/templates/react-app/files/src/shared/ui/components/ui/select.tsx +80 -0
- package/templates/react-app/files/src/shared/ui/components/ui/skeleton.tsx +12 -0
- package/templates/react-app/files/src/shared/ui/components/ui/sonner.tsx +23 -0
- package/templates/react-app/files/src/shared/ui/components/ui/spinner.tsx +8 -0
- package/templates/react-app/files/src/shared/ui/components/ui/textarea.tsx +22 -0
- package/templates/react-app/files/src/shared/ui/index.ts +45 -0
- package/templates/react-app/files/src/shared/ui/lib/utils.ts +7 -0
- package/templates/react-app/files/src/shared/ui/lib/zod-setup.ts +28 -0
- package/templates/react-app/files/src/shared/ui/meta/brand.ts +18 -0
- package/templates/react-app/files/src/shared/ui/meta/meta-context.ts +30 -0
- package/templates/react-app/files/src/shared/ui/meta/meta-provider.tsx +24 -0
- package/templates/react-app/files/src/shared/ui/meta/page-meta.tsx +69 -0
- package/templates/react-app/files/src/shared/ui/meta/use-meta-config.ts +11 -0
- package/templates/react-app/files/src/shared/ui/styles/globals.css +285 -0
- package/templates/react-app/files/src/shared/ui/styles/theme.css +48 -0
- package/templates/react-app/files/src/shared/ui/theme/init-script.ts +23 -0
- package/templates/react-app/files/src/shared/ui/theme/theme-colors.ts +14 -0
- package/templates/react-app/files/src/shared/ui/theme/theme-context.ts +60 -0
- package/templates/react-app/files/src/shared/ui/theme/theme-provider.tsx +101 -0
- package/templates/react-app/files/src/shared/ui/theme/theme-toggle.tsx +40 -0
- package/templates/react-app/files/src/shared/ui/theme/use-theme.ts +11 -0
- package/templates/react-app/files/src/vite-env.d.ts +13 -0
- package/templates/react-app/files/tsconfig.json +26 -0
- package/templates/react-app/files/tsconfig.node.json +25 -0
- package/templates/react-app/files/vite.config.ts +344 -0
- package/templates/react-app/overrides/src/routes/auth/forgot-password.tsx +93 -0
- package/templates/react-app/overrides/src/routes/auth/login.tsx +87 -0
- package/templates/react-app/overrides/src/routes/auth/signup.tsx +117 -0
- package/templates/react-app/overrides/src/routes/auth/verified.tsx +31 -0
- package/templates/react-app/overrides/src/routes/auth/verify-email.tsx +97 -0
- package/templates/react-app/overrides/src/shared/auth/config.ts +28 -0
- package/templates/react-app/overrides/src/shared/auth/guards.tsx +75 -0
- package/templates/react-app/overrides/src/shared/auth/index.ts +20 -0
- package/templates/react-app/overrides/src/shared/auth/redirect.ts +65 -0
- package/templates/react-app/overrides/src/shared/hooks/index.ts +6 -0
- package/templates/react-app/overrides/src/shared/types/README.md +28 -0
- package/templates/react-app/template.json +222 -0
- package/templates/react-monorepo/files/.dockerignore +19 -0
- package/templates/react-monorepo/files/.editorconfig +12 -0
- package/templates/react-monorepo/files/.forgejo/workflows/build-and-push.yml +98 -0
- package/templates/react-monorepo/files/.forgejo/workflows/ci.yml +35 -0
- package/templates/react-monorepo/files/.husky/pre-commit +1 -0
- package/templates/react-monorepo/files/.nvmrc +1 -0
- package/templates/react-monorepo/files/.prettierignore +6 -0
- package/templates/react-monorepo/files/.prettierrc +9 -0
- package/templates/react-monorepo/files/.yarnrc.yml +2 -0
- package/templates/react-monorepo/files/Dockerfile +90 -0
- package/templates/react-monorepo/files/_gitignore +35 -0
- package/templates/react-monorepo/files/apps/admin/.bin/secrets.js +57 -0
- package/templates/react-monorepo/files/apps/admin/.env.example +16 -0
- package/templates/react-monorepo/files/apps/admin/eslint.config.mjs +3 -0
- package/templates/react-monorepo/files/apps/admin/index.html +57 -0
- package/templates/react-monorepo/files/apps/admin/package.json +33 -0
- package/templates/react-monorepo/files/apps/admin/src/App.tsx +3 -0
- package/templates/react-monorepo/files/apps/admin/src/app/nav.tsx +14 -0
- package/templates/react-monorepo/files/apps/admin/src/app/providers.tsx +42 -0
- package/templates/react-monorepo/files/apps/admin/src/app/router.tsx +50 -0
- package/templates/react-monorepo/files/apps/admin/src/app/store.ts +15 -0
- package/templates/react-monorepo/files/apps/admin/src/lib/env.ts +12 -0
- package/templates/react-monorepo/files/apps/admin/src/main.tsx +14 -0
- package/templates/react-monorepo/files/apps/admin/src/routes/home.tsx +17 -0
- package/templates/react-monorepo/files/apps/admin/src/routes/settings.tsx +10 -0
- package/templates/react-monorepo/files/apps/admin/src/vite-env.d.ts +14 -0
- package/templates/react-monorepo/files/apps/admin/tsconfig.json +10 -0
- package/templates/react-monorepo/files/apps/admin/vite.config.ts +13 -0
- package/templates/react-monorepo/files/apps/auth/.bin/secrets.js +57 -0
- package/templates/react-monorepo/files/apps/auth/.env.example +16 -0
- package/templates/react-monorepo/files/apps/auth/eslint.config.mjs +3 -0
- package/templates/react-monorepo/files/apps/auth/index.html +57 -0
- package/templates/react-monorepo/files/apps/auth/package.json +32 -0
- package/templates/react-monorepo/files/apps/auth/src/App.tsx +3 -0
- package/templates/react-monorepo/files/apps/auth/src/app/providers.tsx +42 -0
- package/templates/react-monorepo/files/apps/auth/src/app/router.tsx +19 -0
- package/templates/react-monorepo/files/apps/auth/src/app/store.ts +15 -0
- package/templates/react-monorepo/files/apps/auth/src/components/auth-card.tsx +23 -0
- package/templates/react-monorepo/files/apps/auth/src/components/checkbox-field.tsx +32 -0
- package/templates/react-monorepo/files/apps/auth/src/components/google-button.tsx +41 -0
- package/templates/react-monorepo/files/apps/auth/src/components/or-divider.tsx +9 -0
- package/templates/react-monorepo/files/apps/auth/src/components/password-field.tsx +70 -0
- package/templates/react-monorepo/files/apps/auth/src/components/submit-button.tsx +16 -0
- package/templates/react-monorepo/files/apps/auth/src/lib/auth-actions.ts +68 -0
- package/templates/react-monorepo/files/apps/auth/src/lib/env.ts +8 -0
- package/templates/react-monorepo/files/apps/auth/src/lib/password-strength.ts +20 -0
- package/templates/react-monorepo/files/apps/auth/src/lib/redirect.ts +6 -0
- package/templates/react-monorepo/files/apps/auth/src/lib/schemas.ts +37 -0
- package/templates/react-monorepo/files/apps/auth/src/main.tsx +14 -0
- package/templates/react-monorepo/files/apps/auth/src/routes/forgot-password.tsx +91 -0
- package/templates/react-monorepo/files/apps/auth/src/routes/login.tsx +82 -0
- package/templates/react-monorepo/files/apps/auth/src/routes/reset-password.tsx +83 -0
- package/templates/react-monorepo/files/apps/auth/src/routes/signup.tsx +117 -0
- package/templates/react-monorepo/files/apps/auth/src/routes/verified.tsx +30 -0
- package/templates/react-monorepo/files/apps/auth/src/routes/verify-email.tsx +96 -0
- package/templates/react-monorepo/files/apps/auth/src/vite-env.d.ts +14 -0
- package/templates/react-monorepo/files/apps/auth/tsconfig.json +10 -0
- package/templates/react-monorepo/files/apps/auth/vite.config.ts +13 -0
- package/templates/react-monorepo/files/apps/client/.bin/secrets.js +57 -0
- package/templates/react-monorepo/files/apps/client/.env.example +16 -0
- package/templates/react-monorepo/files/apps/client/eslint.config.mjs +3 -0
- package/templates/react-monorepo/files/apps/client/index.html +57 -0
- package/templates/react-monorepo/files/apps/client/package.json +35 -0
- package/templates/react-monorepo/files/apps/client/src/App.tsx +3 -0
- package/templates/react-monorepo/files/apps/client/src/app/nav.tsx +14 -0
- package/templates/react-monorepo/files/apps/client/src/app/providers.tsx +42 -0
- package/templates/react-monorepo/files/apps/client/src/app/router.tsx +50 -0
- package/templates/react-monorepo/files/apps/client/src/app/store.ts +15 -0
- package/templates/react-monorepo/files/apps/client/src/lib/env.ts +12 -0
- package/templates/react-monorepo/files/apps/client/src/main.tsx +19 -0
- package/templates/react-monorepo/files/apps/client/src/routes/home.tsx +17 -0
- package/templates/react-monorepo/files/apps/client/src/routes/settings.tsx +10 -0
- package/templates/react-monorepo/files/apps/client/src/vite-env.d.ts +15 -0
- package/templates/react-monorepo/files/apps/client/tsconfig.json +10 -0
- package/templates/react-monorepo/files/apps/client/vite.config.ts +120 -0
- package/templates/react-monorepo/files/apps/landing/.bin/secrets.js +57 -0
- package/templates/react-monorepo/files/apps/landing/.env.example +20 -0
- package/templates/react-monorepo/files/apps/landing/eslint.config.mjs +3 -0
- package/templates/react-monorepo/files/apps/landing/index.html +51 -0
- package/templates/react-monorepo/files/apps/landing/package.json +33 -0
- package/templates/react-monorepo/files/apps/landing/src/App.tsx +3 -0
- package/templates/react-monorepo/files/apps/landing/src/app/providers.tsx +42 -0
- package/templates/react-monorepo/files/apps/landing/src/app/router.tsx +21 -0
- package/templates/react-monorepo/files/apps/landing/src/app/store.ts +18 -0
- package/templates/react-monorepo/files/apps/landing/src/features/seo/routes.ts +65 -0
- package/templates/react-monorepo/files/apps/landing/src/lib/env.ts +10 -0
- package/templates/react-monorepo/files/apps/landing/src/main.tsx +14 -0
- package/templates/react-monorepo/files/apps/landing/src/routes/home.tsx +18 -0
- package/templates/react-monorepo/files/apps/landing/src/vite-env.d.ts +15 -0
- package/templates/react-monorepo/files/apps/landing/tsconfig.json +10 -0
- package/templates/react-monorepo/files/apps/landing/vite.config.ts +169 -0
- package/templates/react-monorepo/files/build.sh +61 -0
- package/templates/react-monorepo/files/docker/nginx.conf +136 -0
- package/templates/react-monorepo/files/package.json +37 -0
- package/templates/react-monorepo/files/packages/.gitkeep +0 -0
- package/templates/react-monorepo/files/packages/api/eslint.config.mjs +3 -0
- package/templates/react-monorepo/files/packages/api/package.json +30 -0
- package/templates/react-monorepo/files/packages/api/src/base-api.ts +24 -0
- package/templates/react-monorepo/files/packages/api/src/base-query.ts +29 -0
- package/templates/react-monorepo/files/packages/api/src/config.ts +21 -0
- package/templates/react-monorepo/files/packages/api/src/index.ts +15 -0
- package/templates/react-monorepo/files/packages/api/src/realtime-events.ts +34 -0
- package/templates/react-monorepo/files/packages/api/src/socket.ts +41 -0
- package/templates/react-monorepo/files/packages/api/src/store.ts +39 -0
- package/templates/react-monorepo/files/packages/api/src/upload-query.ts +115 -0
- package/templates/react-monorepo/files/packages/api/tsconfig.json +4 -0
- package/templates/react-monorepo/files/packages/auth/eslint.config.mjs +3 -0
- package/templates/react-monorepo/files/packages/auth/package.json +33 -0
- package/templates/react-monorepo/files/packages/auth/src/client.ts +27 -0
- package/templates/react-monorepo/files/packages/auth/src/config.ts +22 -0
- package/templates/react-monorepo/files/packages/auth/src/guards.tsx +61 -0
- package/templates/react-monorepo/files/packages/auth/src/hooks.ts +13 -0
- package/templates/react-monorepo/files/packages/auth/src/index.ts +20 -0
- package/templates/react-monorepo/files/packages/auth/src/logout.ts +23 -0
- package/templates/react-monorepo/files/packages/auth/src/provider.tsx +52 -0
- package/templates/react-monorepo/files/packages/auth/src/redirect.ts +37 -0
- package/templates/react-monorepo/files/packages/auth/src/slice.ts +54 -0
- package/templates/react-monorepo/files/packages/auth/tsconfig.json +4 -0
- package/templates/react-monorepo/files/packages/config/README.md +47 -0
- package/templates/react-monorepo/files/packages/config/eslint/base.mjs +83 -0
- package/templates/react-monorepo/files/packages/config/package.json +37 -0
- package/templates/react-monorepo/files/packages/config/tailwind/theme.css +48 -0
- package/templates/react-monorepo/files/packages/config/tsconfig/base.json +22 -0
- package/templates/react-monorepo/files/packages/config/tsconfig/node.json +9 -0
- package/templates/react-monorepo/files/packages/config/tsconfig/react.json +9 -0
- package/templates/react-monorepo/files/packages/config/vite/index.d.ts +18 -0
- package/templates/react-monorepo/files/packages/config/vite/index.mjs +129 -0
- package/templates/react-monorepo/files/packages/hooks/eslint.config.mjs +3 -0
- package/templates/react-monorepo/files/packages/hooks/package.json +16 -0
- package/templates/react-monorepo/files/packages/hooks/src/index.ts +3 -0
- package/templates/react-monorepo/files/packages/hooks/tsconfig.json +4 -0
- package/templates/react-monorepo/files/packages/layouts/eslint.config.mjs +3 -0
- package/templates/react-monorepo/files/packages/layouts/package.json +30 -0
- package/templates/react-monorepo/files/packages/layouts/src/app-shell/app-shell.tsx +225 -0
- package/templates/react-monorepo/files/packages/layouts/src/app-shell/user-menu.tsx +74 -0
- package/templates/react-monorepo/files/packages/layouts/src/auth-layout.tsx +137 -0
- package/templates/react-monorepo/files/packages/layouts/src/error-boundary.tsx +38 -0
- package/templates/react-monorepo/files/packages/layouts/src/index.ts +23 -0
- package/templates/react-monorepo/files/packages/layouts/src/marketing/marketing-layout.tsx +29 -0
- package/templates/react-monorepo/files/packages/layouts/src/marketing/section-heading.tsx +38 -0
- package/templates/react-monorepo/files/packages/layouts/src/marketing/section.tsx +30 -0
- package/templates/react-monorepo/files/packages/layouts/src/states/app-shell-skeleton.tsx +47 -0
- package/templates/react-monorepo/files/packages/layouts/src/states/empty.tsx +22 -0
- package/templates/react-monorepo/files/packages/layouts/src/states/forbidden.tsx +14 -0
- package/templates/react-monorepo/files/packages/layouts/src/states/loading.tsx +11 -0
- package/templates/react-monorepo/files/packages/layouts/src/states/not-found.tsx +21 -0
- package/templates/react-monorepo/files/packages/layouts/src/states/page-skeleton.tsx +39 -0
- package/templates/react-monorepo/files/packages/layouts/src/states/route-fallback.tsx +26 -0
- package/templates/react-monorepo/files/packages/layouts/src/states/state-screen.tsx +22 -0
- package/templates/react-monorepo/files/packages/layouts/tsconfig.json +4 -0
- package/templates/react-monorepo/files/packages/types/.bin/openapi.js +32 -0
- package/templates/react-monorepo/files/packages/types/.bin/secrets.js +57 -0
- package/templates/react-monorepo/files/packages/types/README.md +28 -0
- package/templates/react-monorepo/files/packages/types/eslint.config.mjs +3 -0
- package/templates/react-monorepo/files/packages/types/openapi-ts.config.ts +22 -0
- package/templates/react-monorepo/files/packages/types/package.json +29 -0
- package/templates/react-monorepo/files/packages/types/src/index.ts +4 -0
- package/templates/react-monorepo/files/packages/types/src/types/api/index.ts +9 -0
- package/templates/react-monorepo/files/packages/types/src/types/api/zod.gen.ts +5 -0
- package/templates/react-monorepo/files/packages/types/tsconfig.json +7 -0
- package/templates/react-monorepo/files/packages/ui/components.json +21 -0
- package/templates/react-monorepo/files/packages/ui/eslint.config.mjs +13 -0
- package/templates/react-monorepo/files/packages/ui/package.json +44 -0
- package/templates/react-monorepo/files/packages/ui/src/components/brand/logo.tsx +51 -0
- package/templates/react-monorepo/files/packages/ui/src/components/brand/social-icons.tsx +37 -0
- package/templates/react-monorepo/files/packages/ui/src/components/form/form.tsx +120 -0
- package/templates/react-monorepo/files/packages/ui/src/components/ui/alert.tsx +25 -0
- package/templates/react-monorepo/files/packages/ui/src/components/ui/button.tsx +43 -0
- package/templates/react-monorepo/files/packages/ui/src/components/ui/calendar.tsx +78 -0
- package/templates/react-monorepo/files/packages/ui/src/components/ui/card.tsx +44 -0
- package/templates/react-monorepo/files/packages/ui/src/components/ui/checkbox.tsx +16 -0
- package/templates/react-monorepo/files/packages/ui/src/components/ui/date-picker.tsx +76 -0
- package/templates/react-monorepo/files/packages/ui/src/components/ui/input.tsx +22 -0
- package/templates/react-monorepo/files/packages/ui/src/components/ui/label.tsx +19 -0
- package/templates/react-monorepo/files/packages/ui/src/components/ui/modal.tsx +94 -0
- package/templates/react-monorepo/files/packages/ui/src/components/ui/popover.tsx +31 -0
- package/templates/react-monorepo/files/packages/ui/src/components/ui/progress.tsx +33 -0
- package/templates/react-monorepo/files/packages/ui/src/components/ui/search-input.tsx +69 -0
- package/templates/react-monorepo/files/packages/ui/src/components/ui/select.tsx +80 -0
- package/templates/react-monorepo/files/packages/ui/src/components/ui/skeleton.tsx +12 -0
- package/templates/react-monorepo/files/packages/ui/src/components/ui/sonner.tsx +23 -0
- package/templates/react-monorepo/files/packages/ui/src/components/ui/spinner.tsx +8 -0
- package/templates/react-monorepo/files/packages/ui/src/components/ui/textarea.tsx +22 -0
- package/templates/react-monorepo/files/packages/ui/src/index.ts +45 -0
- package/templates/react-monorepo/files/packages/ui/src/lib/utils.ts +7 -0
- package/templates/react-monorepo/files/packages/ui/src/lib/zod-setup.ts +28 -0
- package/templates/react-monorepo/files/packages/ui/src/meta/brand.ts +18 -0
- package/templates/react-monorepo/files/packages/ui/src/meta/meta-context.ts +30 -0
- package/templates/react-monorepo/files/packages/ui/src/meta/meta-provider.tsx +24 -0
- package/templates/react-monorepo/files/packages/ui/src/meta/page-meta.tsx +69 -0
- package/templates/react-monorepo/files/packages/ui/src/meta/use-meta-config.ts +11 -0
- package/templates/react-monorepo/files/packages/ui/src/styles/globals.css +285 -0
- package/templates/react-monorepo/files/packages/ui/src/theme/init-script.ts +23 -0
- package/templates/react-monorepo/files/packages/ui/src/theme/theme-colors.ts +14 -0
- package/templates/react-monorepo/files/packages/ui/src/theme/theme-context.ts +60 -0
- package/templates/react-monorepo/files/packages/ui/src/theme/theme-provider.tsx +101 -0
- package/templates/react-monorepo/files/packages/ui/src/theme/theme-toggle.tsx +40 -0
- package/templates/react-monorepo/files/packages/ui/src/theme/use-theme.ts +11 -0
- package/templates/react-monorepo/files/packages/ui/tsconfig.json +9 -0
- package/templates/react-monorepo/files/turbo.json +24 -0
- package/templates/react-monorepo/template.json +230 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from bullmq import Worker
|
|
3
|
+
import asyncio
|
|
4
|
+
import signal
|
|
5
|
+
from utils.logger import Logger
|
|
6
|
+
from utils.worker import create_worker
|
|
7
|
+
|
|
8
|
+
# import worker processes
|
|
9
|
+
from workers.hello.process import hello_process
|
|
10
|
+
logger = Logger("worker")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
async def main():
|
|
14
|
+
logger.info("Starting Python 3.14 Worker...")
|
|
15
|
+
shutdown_event = asyncio.Event()
|
|
16
|
+
loop = asyncio.get_running_loop()
|
|
17
|
+
|
|
18
|
+
# Async signal handlers
|
|
19
|
+
for sig in (signal.SIGINT, signal.SIGTERM):
|
|
20
|
+
loop.add_signal_handler(
|
|
21
|
+
sig,
|
|
22
|
+
lambda s=sig: (
|
|
23
|
+
logger.info(f"Signal {s} received, shutting down."),
|
|
24
|
+
shutdown_event.set()
|
|
25
|
+
),
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
# Add workers
|
|
29
|
+
hello = create_worker("hello", hello_process)
|
|
30
|
+
|
|
31
|
+
logger.info("Workers started and waiting for jobs.")
|
|
32
|
+
try:
|
|
33
|
+
await shutdown_event.wait()
|
|
34
|
+
finally:
|
|
35
|
+
logger.info("Cleaning up workers...")
|
|
36
|
+
# Close workers gracefully
|
|
37
|
+
await hello.close()
|
|
38
|
+
logger.info("Workers shut down successfully.")
|
|
39
|
+
|
|
40
|
+
if __name__ == "__main__":
|
|
41
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from bullmq import Job
|
|
2
|
+
|
|
3
|
+
from utils.worker import create_logger, JobUtil
|
|
4
|
+
|
|
5
|
+
logger = create_logger('hello')
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
async def hello_process(job: Job, job_token):
|
|
9
|
+
"""
|
|
10
|
+
Job handler.
|
|
11
|
+
|
|
12
|
+
Raising marks the job failed and lets BullMQ retry it according to the
|
|
13
|
+
producer's attempts/backoff settings — so raise on a genuine failure rather
|
|
14
|
+
than swallowing it and returning normally.
|
|
15
|
+
"""
|
|
16
|
+
util = JobUtil(job, logger)
|
|
17
|
+
logger.info(f"Job[{job.id}]: processing... (token={job_token})")
|
|
18
|
+
await util.process_log("Processing started")
|
|
19
|
+
|
|
20
|
+
# Do the work here.
|
|
21
|
+
|
|
22
|
+
await util.finalize()
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "py-worker",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"title": "Python background worker",
|
|
5
|
+
"description": "A Python BullMQ worker that consumes the same Redis queues your Node API produces to, with SQLAlchemy models over the same Postgres database, structured logging and graceful shutdown. For work that belongs in Python — data processing, ML, scientific libraries.",
|
|
6
|
+
"aliasRoots": {},
|
|
7
|
+
"generatedPaths": [
|
|
8
|
+
"**/__pycache__/**"
|
|
9
|
+
],
|
|
10
|
+
"replacements": [
|
|
11
|
+
{
|
|
12
|
+
"from": "Acme Corp",
|
|
13
|
+
"to": "{{Name}}"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"from": "acme",
|
|
17
|
+
"to": "{{name}}"
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"features": {
|
|
21
|
+
"queue": {
|
|
22
|
+
"title": "BullMQ consumers",
|
|
23
|
+
"description": "Workers pulling from the same Redis queues your Node API produces to, with graceful SIGINT/SIGTERM shutdown.",
|
|
24
|
+
"core": true
|
|
25
|
+
},
|
|
26
|
+
"logging": {
|
|
27
|
+
"title": "Structured logging",
|
|
28
|
+
"core": true
|
|
29
|
+
},
|
|
30
|
+
"database": {
|
|
31
|
+
"title": "SQLAlchemy over Postgres",
|
|
32
|
+
"description": "Direct database access to the same schema your API owns. Models are hand-written here rather than generated, so they must be kept in step with the Prisma schema by hand.",
|
|
33
|
+
"default": true,
|
|
34
|
+
"files": [
|
|
35
|
+
"utils/db.py",
|
|
36
|
+
"models/**"
|
|
37
|
+
],
|
|
38
|
+
"requirements": [
|
|
39
|
+
"SQLAlchemy",
|
|
40
|
+
"psycopg2-binary",
|
|
41
|
+
"greenlet"
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
"docker": {
|
|
45
|
+
"title": "Docker image",
|
|
46
|
+
"default": true,
|
|
47
|
+
"files": [
|
|
48
|
+
"Dockerfile",
|
|
49
|
+
".dockerignore"
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
"ci": {
|
|
53
|
+
"title": "Forgejo Actions CI",
|
|
54
|
+
"default": true,
|
|
55
|
+
"files": [
|
|
56
|
+
".forgejo/**"
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"hooks": [
|
|
61
|
+
{
|
|
62
|
+
"title": "seed .env",
|
|
63
|
+
"run": "cp -n .env.example .env || true",
|
|
64
|
+
"optional": true
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"title": "create a virtualenv",
|
|
68
|
+
"run": "python3 -m venv .venv",
|
|
69
|
+
"optional": true
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"title": "install requirements",
|
|
73
|
+
"run": ".venv/bin/pip install -q -r requirements.txt",
|
|
74
|
+
"optional": true
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"title": "git init",
|
|
78
|
+
"run": "git init -q && git add -A && git commit -qm 'chore: scaffold {{name}} from the py-worker template'",
|
|
79
|
+
"optional": true
|
|
80
|
+
}
|
|
81
|
+
],
|
|
82
|
+
"nextSteps": [
|
|
83
|
+
"Edit .env — DB_* and REDIS_* must match the API's.",
|
|
84
|
+
"source .venv/bin/activate",
|
|
85
|
+
"python worker.py"
|
|
86
|
+
]
|
|
87
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# react-app
|
|
2
|
+
|
|
3
|
+
The `react-monorepo` stack collapsed into a single Vite app: one build, one
|
|
4
|
+
image, one origin.
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
stack new react-app ~/Projects/acme/web --with marketing,admin
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Layout of a generated project
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
src/
|
|
14
|
+
├── main.tsx
|
|
15
|
+
├── app/ providers · router · store · nav
|
|
16
|
+
├── lib/ env · paths
|
|
17
|
+
├── shared/ ui · api · auth · layouts · hooks · types
|
|
18
|
+
├── features/ auth (screens' components + actions) · seo
|
|
19
|
+
└── routes/ home · settings · auth/* · legal/* · marketing/* · admin/*
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`@/` resolves to `src/` (Vite alias + tsconfig `paths`), so `@/shared/ui` is
|
|
23
|
+
what `@scope/ui` was in the monorepo. Nothing else about the code changes.
|
|
24
|
+
|
|
25
|
+
## Where it deliberately differs from the monorepo
|
|
26
|
+
|
|
27
|
+
One origin instead of four, which changes three things and nothing else:
|
|
28
|
+
|
|
29
|
+
- **The session guard navigates.** `ProtectedRoute` renders `<Navigate to="/login?redirect=…" replace />`
|
|
30
|
+
rather than assigning `window.location`. The login screen is in this same
|
|
31
|
+
bundle, so a full page load would re-download and re-boot the app to show a
|
|
32
|
+
screen it already has. The 401 handler still does a hard load, because it fires
|
|
33
|
+
from outside React and discarding in-memory state is the point there.
|
|
34
|
+
- **`trustedOrigins` defaults to this origin.** The open-redirect allowlist stays
|
|
35
|
+
— `?redirect=` is still attacker-controllable — but there is nothing to add to
|
|
36
|
+
it unless you deliberately hand off to another host.
|
|
37
|
+
- **Absolute URLs come from the browser**, not from env. `APP_ORIGIN` is
|
|
38
|
+
`window.location.origin`. The only place an absolute URL is genuinely needed is
|
|
39
|
+
a link that lands in an email, and a build-time `VITE_APP_URL` can only be
|
|
40
|
+
wrong there — a stale value baked into an image sends verification links to the
|
|
41
|
+
previous environment, invisibly, until someone clicks one.
|
|
42
|
+
|
|
43
|
+
## Where the app is mounted
|
|
44
|
+
|
|
45
|
+
`src/lib/paths.ts` owns this. With the `marketing` feature the landing page owns
|
|
46
|
+
`/` and the authenticated app moves to `/app`; without it, the app owns the root.
|
|
47
|
+
The router, the nav and the post-login redirect all read `appPath()`, so they
|
|
48
|
+
cannot disagree.
|
|
49
|
+
|
|
50
|
+
Routes *inside* the app shell stay relative and need none of this.
|
|
51
|
+
|
|
52
|
+
The legal pages (`/terms`, `/privacy`) ship either way, on purpose: the signup
|
|
53
|
+
consent gate links to them, and a checkbox that says "I agree to the Terms" over
|
|
54
|
+
a 404 is not consent.
|
|
55
|
+
|
|
56
|
+
## Maintaining it
|
|
57
|
+
|
|
58
|
+
The shared packages and the page components are the *same source* as
|
|
59
|
+
`react-monorepo` — only their location and their import specifiers differ. Don't
|
|
60
|
+
edit them here.
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
bash templates/react-app/derive.sh # re-flatten from react-monorepo
|
|
64
|
+
stack doctor react-app # always, afterwards
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`derive.sh` rebuilds `src/shared`, `src/features/{auth,seo}`,
|
|
68
|
+
`src/routes/{auth,marketing}` from scratch each run, then copies `overrides/` on
|
|
69
|
+
top. Anything in `overrides/` is a file that genuinely differs in a monolith —
|
|
70
|
+
that directory listing *is* the list of intentional divergences, and it is short
|
|
71
|
+
by design.
|
|
72
|
+
|
|
73
|
+
Everything else (`app/`, `lib/`, `vite.config.ts`, `package.json`, `Dockerfile`)
|
|
74
|
+
is hand-written here and untouched by the script.
|
|
75
|
+
|
|
76
|
+
So: a fix to a UI component or an auth screen goes into `react-monorepo` and
|
|
77
|
+
arrives here on the next `derive.sh`. A fix to routing, config or the build
|
|
78
|
+
belongs to whichever template it is in.
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# Re-derive the mechanically-copyable half of the react-app template from
|
|
4
|
+
# react-monorepo.
|
|
5
|
+
#
|
|
6
|
+
# react-app is the same stack as react-monorepo collapsed into one Vite app, so
|
|
7
|
+
# the shared packages and the page components are *identical source* — only their
|
|
8
|
+
# location and their import specifiers differ. Rather than maintain two copies by
|
|
9
|
+
# hand and watch them drift, this script re-flattens them:
|
|
10
|
+
#
|
|
11
|
+
# packages/<p>/src/** -> src/shared/<p>/**
|
|
12
|
+
# apps/auth/src/{components,lib}/** -> src/features/auth/**
|
|
13
|
+
# apps/auth/src/routes/** -> src/routes/auth/**
|
|
14
|
+
# apps/client/src/routes/** -> src/routes/**
|
|
15
|
+
# apps/landing/src/... -> src/routes/marketing/, src/features/seo/
|
|
16
|
+
#
|
|
17
|
+
# and rewrites `@acme/x` -> `@/shared/x`.
|
|
18
|
+
#
|
|
19
|
+
# A handful of files genuinely differ in a monolith — one origin means the auth
|
|
20
|
+
# guard navigates instead of redirecting across hosts, and the auth screens take
|
|
21
|
+
# in-app paths rather than sibling-app URLs. Those live in `overrides/` and are
|
|
22
|
+
# copied over the derived tree at the end, so this script is idempotent and the
|
|
23
|
+
# divergence from the monorepo is visible in one directory listing.
|
|
24
|
+
#
|
|
25
|
+
# Everything outside the DERIVED trees — the router, store, providers, vite
|
|
26
|
+
# config, package.json, Dockerfile — is hand-written and untouched here.
|
|
27
|
+
#
|
|
28
|
+
# Usage: bash templates/react-app/derive.sh
|
|
29
|
+
# stack doctor react-app # always, afterwards
|
|
30
|
+
set -euo pipefail
|
|
31
|
+
|
|
32
|
+
HERE="$(cd "$(dirname "$0")" && pwd)"
|
|
33
|
+
STACKS="$(cd "$HERE/../.." && pwd)"
|
|
34
|
+
SRC="$STACKS/templates/react-monorepo/files"
|
|
35
|
+
DST="$HERE/files"
|
|
36
|
+
|
|
37
|
+
[ -d "$SRC" ] || { echo "missing $SRC — extract react-monorepo first" >&2; exit 1; }
|
|
38
|
+
|
|
39
|
+
# Trees this script owns end to end and rebuilds from scratch every run.
|
|
40
|
+
DERIVED=(
|
|
41
|
+
src/shared
|
|
42
|
+
src/features/auth
|
|
43
|
+
src/features/seo
|
|
44
|
+
src/routes/auth
|
|
45
|
+
src/routes/marketing
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
echo "==> clearing derived trees"
|
|
49
|
+
for dir in "${DERIVED[@]}"; do
|
|
50
|
+
rm -rf "${DST:?}/$dir"
|
|
51
|
+
done
|
|
52
|
+
|
|
53
|
+
echo "==> flattening packages -> src/shared"
|
|
54
|
+
mkdir -p "$DST/src/shared"
|
|
55
|
+
for pkg in ui api auth layouts hooks types; do
|
|
56
|
+
cp -r "$SRC/packages/$pkg/src" "$DST/src/shared/$pkg"
|
|
57
|
+
done
|
|
58
|
+
# The brand tokens live in the config package in the monorepo because three
|
|
59
|
+
# other packages consume them; here there is one consumer, so they sit next to
|
|
60
|
+
# the stylesheet that imports them.
|
|
61
|
+
cp "$SRC/packages/config/tailwind/theme.css" "$DST/src/shared/ui/styles/theme.css"
|
|
62
|
+
# `packages/types/src/types/api` earns its doubled segment as a package (the
|
|
63
|
+
# package is `types`, the directory of generated output is `types/api`). Flattened
|
|
64
|
+
# into one app it just reads as a stutter, so it lands at `shared/types/api`.
|
|
65
|
+
mv "$DST/src/shared/types/types/api" "$DST/src/shared/types/api"
|
|
66
|
+
rmdir "$DST/src/shared/types/types"
|
|
67
|
+
|
|
68
|
+
echo "==> flattening apps -> src/features, src/routes"
|
|
69
|
+
mkdir -p "$DST/src/features/auth" "$DST/src/routes/auth" "$DST/src/routes/marketing" "$DST/src/features/seo"
|
|
70
|
+
cp -r "$SRC/apps/auth/src/components" "$DST/src/features/auth/components"
|
|
71
|
+
cp -r "$SRC/apps/auth/src/lib" "$DST/src/features/auth/lib"
|
|
72
|
+
# `env.ts` is per-app in the monorepo (four different sets of sibling origins);
|
|
73
|
+
# the monolith has exactly one, hand-written at src/lib/env.ts.
|
|
74
|
+
rm -f "$DST/src/features/auth/lib/env.ts"
|
|
75
|
+
cp "$SRC"/apps/auth/src/routes/*.tsx "$DST/src/routes/auth/"
|
|
76
|
+
cp "$SRC"/apps/client/src/routes/*.tsx "$DST/src/routes/"
|
|
77
|
+
cp "$SRC/apps/landing/src/routes/home.tsx" "$DST/src/routes/marketing/home.tsx"
|
|
78
|
+
cp "$SRC/apps/landing/src/features/seo/routes.ts" "$DST/src/features/seo/routes.ts"
|
|
79
|
+
|
|
80
|
+
echo "==> rewriting import specifiers"
|
|
81
|
+
# Longest first: `@acme/ui/brand` must not be matched by the `@acme/ui` rule.
|
|
82
|
+
# `@` resolves to `src` (vite alias + tsconfig paths), so these are valid from
|
|
83
|
+
# any depth and survive a file being moved.
|
|
84
|
+
find "$DST/src" -type f \( -name '*.ts' -o -name '*.tsx' -o -name '*.css' \) -print0 |
|
|
85
|
+
xargs -0 sed -i \
|
|
86
|
+
-e "s#@acme/ui/theme-colors#@/shared/ui/theme/theme-colors#g" \
|
|
87
|
+
-e "s#@acme/ui/globals.css#@/shared/ui/styles/globals.css#g" \
|
|
88
|
+
-e "s#@acme/ui/brand#@/shared/ui/meta/brand#g" \
|
|
89
|
+
-e "s#@acme/types/zod#@/shared/types/api/zod.gen#g" \
|
|
90
|
+
-e "s#@acme/config/tailwind.css#./theme.css#g" \
|
|
91
|
+
-e "s#@acme/config#theme.css#g" \
|
|
92
|
+
-e "s#@acme/ui#@/shared/ui#g" \
|
|
93
|
+
-e "s#@acme/api#@/shared/api#g" \
|
|
94
|
+
-e "s#@acme/auth#@/shared/auth#g" \
|
|
95
|
+
-e "s#@acme/layouts#@/shared/layouts#g" \
|
|
96
|
+
-e "s#@acme/hooks#@/shared/hooks#g" \
|
|
97
|
+
-e "s#@acme/types#@/shared/types#g"
|
|
98
|
+
|
|
99
|
+
# The auth screens moved one level deeper than their components and lib, so
|
|
100
|
+
# their relative imports no longer reach. Anchor them instead.
|
|
101
|
+
find "$DST/src/routes/auth" -type f -name '*.tsx' -print0 |
|
|
102
|
+
xargs -0 sed -i \
|
|
103
|
+
-e "s#'\.\./components/#'@/features/auth/components/#g" \
|
|
104
|
+
-e "s#'\.\./lib/#'@/features/auth/lib/#g"
|
|
105
|
+
|
|
106
|
+
# ...which the types barrel points at.
|
|
107
|
+
sed -i -e "s#'\./types/api#'./api#g" -e "s#under \./types/api#under ./api#" "$DST/src/shared/types/index.ts"
|
|
108
|
+
|
|
109
|
+
# Package barrels name themselves in their header comment.
|
|
110
|
+
find "$DST/src/shared" -type f -name 'index.ts' -print0 |
|
|
111
|
+
xargs -0 sed -i -e "s#^// @acme/\([a-z]*\) —#// @/shared/\1 —#"
|
|
112
|
+
|
|
113
|
+
echo "==> applying monolith overrides"
|
|
114
|
+
# One origin, one router: these files diverge from the monorepo on purpose.
|
|
115
|
+
# `cp -v` so the list is visible in the output — if one of these ever stops
|
|
116
|
+
# corresponding to a real derived file, it shows up here as a new path rather
|
|
117
|
+
# than silently doing nothing.
|
|
118
|
+
(cd "$HERE/overrides" && find . -type f -print0) |
|
|
119
|
+
while IFS= read -r -d '' rel; do
|
|
120
|
+
target="$DST/${rel#./}"
|
|
121
|
+
[ -f "$target" ] || echo " NOTE: override has no derived counterpart: ${rel#./}"
|
|
122
|
+
mkdir -p "$(dirname "$target")"
|
|
123
|
+
cp "$HERE/overrides/${rel#./}" "$target"
|
|
124
|
+
echo " ${rel#./}"
|
|
125
|
+
done
|
|
126
|
+
|
|
127
|
+
echo
|
|
128
|
+
echo "done. Now run: node $STACKS/cli/stack.mjs doctor react-app"
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import ti from 'tiny-invariant';
|
|
3
|
+
import axios from 'axios';
|
|
4
|
+
import fs from 'fs/promises';
|
|
5
|
+
|
|
6
|
+
const loadSchema = async () => {
|
|
7
|
+
const apiDocUrl = process.env.API_DOC_URL;
|
|
8
|
+
const username = process.env.API_DOC_USER;
|
|
9
|
+
const password = process.env.API_DOC_PASSWORD;
|
|
10
|
+
|
|
11
|
+
ti(apiDocUrl, 'API_DOC_URL is required');
|
|
12
|
+
ti(username, 'API_DOC_USER is required');
|
|
13
|
+
ti(password, 'API_DOC_PASSWORD is required');
|
|
14
|
+
|
|
15
|
+
const response = await axios.get(apiDocUrl, {
|
|
16
|
+
auth: {
|
|
17
|
+
username,
|
|
18
|
+
password
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
return response.data;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
(async () => {
|
|
26
|
+
const schema = await loadSchema();
|
|
27
|
+
await fs.writeFile('openapi.json', JSON.stringify(schema), 'utf-8');
|
|
28
|
+
console.log('💾 Wrote openapi.json');
|
|
29
|
+
})().catch((err) => {
|
|
30
|
+
console.error(err);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
|
|
3
|
+
// Pulls this app's env from Infisical into the matching .env file.
|
|
4
|
+
//
|
|
5
|
+
// The project ID is read from the environment rather than hardcoded: it
|
|
6
|
+
// identifies one organisation's vault, so a value baked in here would follow
|
|
7
|
+
// every copy of this scaffold to projects it has nothing to do with. Put it in
|
|
8
|
+
// your shell profile, or in a committed `.infisical.json`.
|
|
9
|
+
const PROJECT_ID = process.env.INFISICAL_PROJECT_ID;
|
|
10
|
+
const SECRET_PATH = process.env.INFISICAL_PATH ?? '/';
|
|
11
|
+
|
|
12
|
+
const ENV_FILES = {
|
|
13
|
+
dev: '.env',
|
|
14
|
+
test: '.env.test',
|
|
15
|
+
staging: '.env.staging',
|
|
16
|
+
prod: '.env.production'
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const normalizeEnv = (raw) => {
|
|
20
|
+
if (['dev', 'development'].includes(raw)) return 'dev';
|
|
21
|
+
if (['test', 'testing'].includes(raw)) return 'test';
|
|
22
|
+
if (['prod', 'production'].includes(raw)) return 'prod';
|
|
23
|
+
if (raw === 'staging') return 'staging';
|
|
24
|
+
throw new Error(`Unknown env '${raw}' (use one of: dev, test, staging, prod)`);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const parseEnvArg = () => {
|
|
28
|
+
const args = process.argv.slice(2);
|
|
29
|
+
const flagIndex = args.findIndex((a) => a === '-e' || a === '--env');
|
|
30
|
+
if (flagIndex !== -1 && args[flagIndex + 1]) return args[flagIndex + 1];
|
|
31
|
+
const inline = args.find((a) => a.startsWith('--env='));
|
|
32
|
+
if (inline) return inline.slice('--env='.length);
|
|
33
|
+
return 'development';
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
if (!PROJECT_ID) {
|
|
37
|
+
console.error('INFISICAL_PROJECT_ID is not set — nothing to fetch from.');
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const env = normalizeEnv(parseEnvArg());
|
|
42
|
+
const envFile = ENV_FILES[env];
|
|
43
|
+
|
|
44
|
+
console.log(`Fetching secrets (${env}) -> ${envFile}...`);
|
|
45
|
+
execSync(`infisical export --projectId="${PROJECT_ID}" --path="${SECRET_PATH}" --env=${env} > ${envFile}`, {
|
|
46
|
+
stdio: 'inherit'
|
|
47
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Keep the build context small and the image reproducible.
|
|
2
|
+
node_modules
|
|
3
|
+
dist
|
|
4
|
+
dev-dist
|
|
5
|
+
|
|
6
|
+
# Env files are NOT copied into the image — the URLs are passed as build args.
|
|
7
|
+
# Copying them would bake whichever environment happened to be checked out.
|
|
8
|
+
.env
|
|
9
|
+
.env.*
|
|
10
|
+
!.env.example
|
|
11
|
+
|
|
12
|
+
.git
|
|
13
|
+
.github
|
|
14
|
+
.forgejo
|
|
15
|
+
*.log
|
|
16
|
+
.DS_Store
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Copy to .env. Vite only exposes variables prefixed VITE_, and inlines them at
|
|
2
|
+
# build time — never put a secret here, it ships to the browser.
|
|
3
|
+
|
|
4
|
+
# Backend base URL. Better Auth lives at ${VITE_APP_API_URL}/auth.
|
|
5
|
+
VITE_APP_API_URL='http://localhost:5000'
|
|
6
|
+
|
|
7
|
+
# Dev server port.
|
|
8
|
+
PORT='3000'
|
|
9
|
+
|
|
10
|
+
# Comma-separated hostnames the dev server will answer to, beyond localhost.
|
|
11
|
+
# Needed when you reach the dev server through a tunnel or a wildcard DNS name.
|
|
12
|
+
VITE_APP_ALLOWED_HOSTS=''
|
|
13
|
+
|
|
14
|
+
# @feature:start marketing
|
|
15
|
+
# The canonical public origin — the ONE origin that may be indexed. Must match
|
|
16
|
+
# PRODUCTION_ORIGIN in src/features/seo/routes.ts. Anything else (previews,
|
|
17
|
+
# staging, unset) is treated as non-production: the build then emits `noindex`
|
|
18
|
+
# and a disallowing robots.txt, so a preview cannot outrank production.
|
|
19
|
+
VITE_APP_SITE_URL=''
|
|
20
|
+
|
|
21
|
+
# Published in /.well-known/security.txt. Leave empty and the file is not
|
|
22
|
+
# emitted at all — a security contact pointing at an unmonitored mailbox is
|
|
23
|
+
# worse than none.
|
|
24
|
+
VITE_APP_SUPPORT_EMAIL=''
|
|
25
|
+
# @feature:end
|
|
26
|
+
|
|
27
|
+
# @feature:start types
|
|
28
|
+
# Credentials for the backend's OpenAPI document, used by `yarn gen` only.
|
|
29
|
+
# Not VITE_-prefixed on purpose: these are read by a Node script, and prefixing
|
|
30
|
+
# them would inline them into the browser bundle.
|
|
31
|
+
API_DOC_URL='http://localhost:5000/openapi-json'
|
|
32
|
+
API_DOC_USER=''
|
|
33
|
+
API_DOC_PASSWORD=''
|
|
34
|
+
# @feature:end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Builds and pushes the app image.
|
|
2
|
+
#
|
|
3
|
+
# Vite compiles the VITE_* URLs into the bundle at build time, so this image is
|
|
4
|
+
# specific to one environment — see the note at the top of the Dockerfile.
|
|
5
|
+
|
|
6
|
+
name: Build and Push
|
|
7
|
+
|
|
8
|
+
on:
|
|
9
|
+
push:
|
|
10
|
+
branches:
|
|
11
|
+
- main
|
|
12
|
+
# Day-to-day work happens on `development`; this lets a build be cut without
|
|
13
|
+
# merging to main first.
|
|
14
|
+
workflow_dispatch:
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
build-and-push:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- name: Checkout repository
|
|
21
|
+
uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Generate image tag
|
|
24
|
+
id: tag
|
|
25
|
+
run: |
|
|
26
|
+
DATE=$(date +'%y_%m_%d')
|
|
27
|
+
RAND=$(printf '%05d' "$((RANDOM % 100000))")
|
|
28
|
+
echo "TAG=${DATE}_${RAND}" >> "$GITHUB_OUTPUT"
|
|
29
|
+
echo "OWNER=$(echo '${{ github.repository }}' | cut -d/ -f1)" >> "$GITHUB_OUTPUT"
|
|
30
|
+
|
|
31
|
+
- name: Setup Docker Buildx
|
|
32
|
+
uses: docker/setup-buildx-action@v3
|
|
33
|
+
|
|
34
|
+
- name: Login to Registry
|
|
35
|
+
uses: docker/login-action@v3
|
|
36
|
+
with:
|
|
37
|
+
registry: ${{ secrets.REGISTRY_URL }}
|
|
38
|
+
username: ${{ secrets.DK_USER }}
|
|
39
|
+
password: ${{ secrets.DK_ACCESS_TOKEN }}
|
|
40
|
+
|
|
41
|
+
- name: Build and Push
|
|
42
|
+
uses: docker/build-push-action@v6
|
|
43
|
+
with:
|
|
44
|
+
push: true
|
|
45
|
+
context: .
|
|
46
|
+
build-args: |
|
|
47
|
+
VITE_APP_API_URL=${{ secrets.VITE_APP_API_URL }}
|
|
48
|
+
VITE_APP_SITE_URL=${{ secrets.VITE_APP_SITE_URL }}
|
|
49
|
+
VITE_APP_SUPPORT_EMAIL=${{ secrets.VITE_APP_SUPPORT_EMAIL }}
|
|
50
|
+
tags: |
|
|
51
|
+
${{ secrets.REGISTRY }}/${{ steps.tag.outputs.OWNER }}/web:latest
|
|
52
|
+
${{ secrets.REGISTRY }}/${{ steps.tag.outputs.OWNER }}/web:${{ steps.tag.outputs.TAG }}
|
|
53
|
+
|
|
54
|
+
- name: Summary
|
|
55
|
+
run: echo "Pushed web:${{ steps.tag.outputs.TAG }}" >> "$GITHUB_STEP_SUMMARY"
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- "**"
|
|
7
|
+
- "!main"
|
|
8
|
+
- "!development"
|
|
9
|
+
pull_request:
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
verify:
|
|
13
|
+
name: Lint, typecheck, build
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout repository
|
|
17
|
+
uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Enable Corepack
|
|
20
|
+
run: corepack enable
|
|
21
|
+
|
|
22
|
+
- name: Use Node.js 24
|
|
23
|
+
uses: actions/setup-node@v4
|
|
24
|
+
with:
|
|
25
|
+
node-version: 24
|
|
26
|
+
cache: 'yarn'
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: yarn install --immutable
|
|
30
|
+
|
|
31
|
+
- name: Format check
|
|
32
|
+
run: yarn format:check
|
|
33
|
+
|
|
34
|
+
- name: Lint
|
|
35
|
+
run: yarn lint
|
|
36
|
+
|
|
37
|
+
# `build` typechecks first, so this covers both.
|
|
38
|
+
- name: Typecheck and build
|
|
39
|
+
run: yarn build
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
yarn lint-staged
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
24.13.0
|