├── .github └── dependabot.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── cli-templates.yaml └── v1 ├── apollo-server ├── .gitignore ├── README.md ├── nitric.aws.yaml ├── nitric.yaml ├── package.json ├── services │ └── demo.ts └── tsconfig.json ├── auth-firebase ├── README.md ├── assets │ ├── firebase-service-account.png │ └── firebase-web-app.png ├── frontend │ ├── .gitignore │ ├── .vscode │ │ ├── extensions.json │ │ └── launch.json │ ├── README.md │ ├── astro.config.mjs │ ├── components.json │ ├── package.json │ ├── public │ │ └── favicon.svg │ ├── src │ │ ├── components │ │ │ ├── FetchData.tsx │ │ │ ├── auth │ │ │ │ ├── Google.tsx │ │ │ │ └── Logout.tsx │ │ │ └── ui │ │ │ │ ├── badge.tsx │ │ │ │ ├── button.tsx │ │ │ │ ├── input.tsx │ │ │ │ ├── label.tsx │ │ │ │ └── select.tsx │ │ ├── env.d.ts │ │ ├── images │ │ │ └── logo.svg │ │ ├── layouts │ │ │ └── Layout.astro │ │ ├── lib │ │ │ ├── auth.ts │ │ │ ├── firebase.ts │ │ │ └── utils.ts │ │ ├── pages │ │ │ ├── dashboard.astro │ │ │ └── index.astro │ │ ├── styles │ │ │ └── globals.css │ │ └── types.ts │ ├── tailwind.config.mjs │ └── tsconfig.json ├── python │ ├── .env │ ├── .gitignore │ ├── .python-version │ ├── README.md │ ├── nitric.yaml │ ├── pyproject.toml │ ├── python.dockerfile │ ├── python.dockerfile.dockerignore │ └── services │ │ └── api.py └── typescript │ ├── .env.example │ ├── .gitignore │ ├── README.md │ ├── nitric.yaml │ ├── package.json │ ├── services │ └── example.ts │ └── tsconfig.json ├── blender-render ├── .env ├── .python-version ├── README.md ├── batches │ └── renderer.py ├── blender.dockerfile ├── blender.dockerignore ├── common │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-311.pyc │ │ └── resources.cpython-311.pyc │ └── resources.py ├── nitric.yaml ├── pyproject.toml ├── python.dockerfile ├── python.dockerignore ├── services │ └── main.py └── uv.lock ├── cloudflare-lb ├── .env.template ├── .gitignore ├── README.md ├── infra │ ├── config.ts │ ├── down.ts │ └── up.ts ├── nitric.prod-aws.yaml ├── nitric.prod-gcp.yaml ├── nitric.yaml ├── node.dockerfile ├── node.dockerfile.dockerignore ├── package.json ├── services │ └── hello.ts └── tsconfig.json ├── cockroach-example ├── README.md └── typescript │ ├── .env.template │ ├── .gitignore │ ├── README.md │ ├── nitric.yaml │ ├── package.json │ ├── services │ └── hello.ts │ └── tsconfig.json ├── custom-dockerfile-nestjs ├── .eslintrc.js ├── .gitignore ├── .prettierrc ├── README.md ├── nest-cli.json ├── nitric.yaml ├── node.dockerfile ├── package.json ├── src │ ├── app.module.ts │ ├── main.ts │ └── profile │ │ ├── profile.controller.spec.ts │ │ ├── profile.controller.ts │ │ └── profile.service.ts ├── test │ ├── app.e2e-spec.ts │ └── jest-e2e.json ├── tsconfig.build.json └── tsconfig.json ├── dart-starter ├── .gitignore ├── README.md ├── analysis_options.yaml ├── dart.dockerfile ├── dart.dockerfile.dockerignore ├── nitric.yaml ├── pubspec.yaml └── services │ └── api.dart ├── dynamic-load ├── README.md └── typescript │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── animals │ ├── cat │ │ └── greeting.ts │ ├── dog │ │ └── greeting.ts │ ├── donkey │ │ └── greeting.ts │ └── process │ │ └── greeting.ts │ ├── common │ └── handlers.ts │ ├── nitric.yaml │ ├── package.json │ ├── services │ └── api.ts │ ├── test │ └── speak.test.ts │ └── tsconfig.json ├── flutter ├── .gitignore ├── .metadata ├── README.md ├── analysis_options.yaml ├── docker │ ├── flutter.dockerfile │ └── flutter.dockerignore ├── lib │ ├── cors.dart │ ├── favorite.dart │ ├── main.dart │ ├── pages │ │ ├── favorites.dart │ │ ├── generator.dart │ │ └── home.dart │ ├── providers │ │ ├── favorites.dart │ │ └── word.dart │ └── services │ │ └── main.dart ├── nitric-spec.json ├── nitric.dev.yaml ├── nitric.yaml └── pubspec.yaml ├── go-starter ├── .gitignore ├── .vscode │ └── launch.json ├── README.md ├── go.mod ├── go.sum ├── golang.dockerfile ├── nitric.yaml └── services │ └── hello │ └── main.go ├── javascript-starter ├── .gitignore ├── README.md ├── nitric.yaml ├── node.dockerfile ├── node.dockerfile.dockerignore ├── package.json └── services │ └── api.js ├── llama-rag ├── .env ├── .gitignore ├── .python-version ├── README.md ├── build_query_engine.py ├── common │ ├── __init__.py │ └── model_parameters.py ├── nitric.yaml ├── pyproject.toml ├── python.dockerfile ├── python.dockerfile.dockerignore └── services │ └── api.py ├── middleware-demo ├── README.md └── typescript │ ├── .gitignore │ ├── README.md │ ├── nitric.yaml │ ├── package.json │ ├── services │ └── hello.ts │ └── tsconfig.json ├── multi-language ├── README.md ├── architecture.png ├── go │ ├── .gitignore │ ├── README.md │ ├── go.mod │ ├── go.sum │ ├── golang.dockerfile │ └── services │ │ └── hello │ │ └── main.go ├── nitric.yaml └── ts │ ├── .gitignore │ ├── package.json │ ├── services │ └── hello.ts │ └── tsconfig.json ├── neon-tasklist ├── README.md └── javascript │ ├── .env.template │ ├── .gitignore │ ├── README.md │ ├── nitric.yaml │ ├── package.json │ ├── resources │ └── db.js │ └── services │ └── task-api.js ├── neon ├── README.md └── javascript │ ├── .env.template │ ├── .gitignore │ ├── README.md │ ├── nitric.yaml │ ├── package.json │ ├── resources │ └── db.js │ └── services │ └── neon.js ├── nitric-drizzle ├── .env.template ├── .gitignore ├── README.md ├── db.ts ├── drizzle.config.ts ├── migrate.dockerfile ├── nitric.aws-staging.yaml ├── nitric.yaml ├── package.json ├── schema.ts ├── services │ └── todos.ts └── tsconfig.json ├── nitric-express ├── .env.template ├── .gitignore ├── README.md ├── nitric.aws.yaml ├── nitric.yaml ├── package.json ├── services │ └── url.ts └── tsconfig.json ├── nitric-fastify ├── .gitignore ├── README.md ├── nitric.yaml ├── package.json ├── services │ └── url.ts └── tsconfig.json ├── nitric-hono ├── .gitignore ├── README.md ├── nitric.yaml ├── package.json ├── services │ └── url.ts └── tsconfig.json ├── nitric-koa ├── .env.template ├── .gitignore ├── README.md ├── nitric.yaml ├── package.json ├── services │ └── url.ts └── tsconfig.json ├── nitric-meme-generator ├── .gitignore ├── .vercelignore ├── README.md ├── app │ ├── favicon.ico │ ├── globals.css │ ├── layout.tsx │ ├── loading.tsx │ └── page.tsx ├── backend │ ├── README.md │ ├── nitric.dev.yaml │ ├── nitric.yaml │ ├── node.dockerfile │ ├── node.dockerfile.dockerignore │ ├── package.json │ ├── pnpm-lock.yaml │ ├── services │ │ └── api.ts │ └── tsconfig.json ├── components.json ├── components │ ├── Header.tsx │ ├── ImageDisplay.tsx │ ├── ImageGround.tsx │ ├── ModelCardCarousel.tsx │ ├── ModelSelect.tsx │ ├── PromptInput.tsx │ ├── QualityModeToggle.tsx │ ├── Stopwatch.tsx │ ├── theme-provider.tsx │ └── ui │ │ ├── alert.tsx │ │ ├── button.tsx │ │ ├── card.tsx │ │ ├── carousel.tsx │ │ ├── collapsible.tsx │ │ ├── input.tsx │ │ ├── label.tsx │ │ ├── scroll-area.tsx │ │ ├── select.tsx │ │ ├── spinner.tsx │ │ ├── textarea.tsx │ │ ├── theme.tsx │ │ ├── toast.tsx │ │ ├── toaster.tsx │ │ ├── toggle.tsx │ │ └── tooltip.tsx ├── eslint.config.mjs ├── hooks │ ├── use-image-generation.ts │ ├── use-toast.ts │ └── useMemeContext.tsx ├── lib │ ├── api-types.ts │ ├── image-helpers.ts │ ├── image-types.ts │ ├── logos.tsx │ ├── provider-config.ts │ ├── suggestions.ts │ └── utils.ts ├── next.config.ts ├── package.json ├── pnpm-lock.yaml ├── postcss.config.mjs ├── public │ ├── file.svg │ ├── globe.svg │ ├── next.svg │ ├── provider-icons │ │ └── openai.svg │ ├── vercel.svg │ └── window.svg ├── tailwind.config.ts └── tsconfig.json ├── nitric-monorepo └── with-berry │ ├── .editorconfig │ ├── .gitattributes │ ├── .gitignore │ ├── .yarn │ └── releases │ │ └── yarn-berry.cjs │ ├── .yarnrc.yml │ ├── README.md │ ├── apps │ └── server │ │ ├── .gitignore │ │ ├── Dockerfile │ │ ├── Dockerfile.dockerignore │ │ ├── nitric.yaml │ │ ├── package.json │ │ ├── services │ │ └── hello.ts │ │ └── tsconfig.json │ ├── package.json │ └── packages │ ├── cors │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json │ ├── logger │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json │ └── tsconfig │ ├── base.json │ └── package.json ├── nitric-nest ├── .eslintrc.js ├── .gitignore ├── .prettierrc ├── README.md ├── nest-cli.json ├── nitric.yaml ├── node.dockerfile ├── node.dockerfile.dockerignore ├── package.json ├── src │ ├── app.controller.ts │ ├── app.module.ts │ ├── app.service.ts │ └── main.ts ├── tsconfig.build.json └── tsconfig.json ├── nitric-oak ├── .gitignore ├── README.md ├── deno.dockerfile ├── deno.dockerfile.dockerignore ├── deno.json ├── nitric.yaml └── services │ └── api.ts ├── nitric-pgsql ├── .gitignore ├── README.md ├── migrations │ └── todos │ │ └── 1_create_table.up.sql ├── nitric.yaml ├── node.dockerfile ├── node.dockerfile.dockerignore ├── package.json ├── resources │ └── db.ts ├── services │ └── api.ts └── tsconfig.json ├── nitric-prisma ├── .env.template ├── .gitignore ├── README.md ├── db.ts ├── migrate.dockerfile ├── nitric.aws-staging.yaml ├── nitric.yaml ├── package.json ├── prisma │ └── schema.prisma ├── services │ └── todos.ts └── tsconfig.json ├── nitric-vite-react ├── .gitignore ├── README.md ├── main-website │ ├── .gitignore │ ├── README.md │ ├── eslint.config.js │ ├── index.html │ ├── package.json │ ├── public │ │ └── vite.svg │ ├── src │ │ ├── App.css │ │ ├── App.tsx │ │ ├── assets │ │ │ └── react.svg │ │ ├── index.css │ │ ├── main.tsx │ │ └── vite-env.d.ts │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── nitric.yaml ├── node.dockerfile ├── node.dockerfile.dockerignore ├── package.json ├── services │ └── api.ts └── tsconfig.json ├── openai-embeddings ├── README.md └── typescript │ ├── .env.template │ ├── .gitignore │ ├── README.md │ ├── common │ ├── helper.ts │ └── resources.ts │ ├── db_types.ts │ ├── nitric.yaml │ ├── package.json │ ├── services │ ├── learn.ts │ └── query.ts │ └── tsconfig.json ├── podcast-transcription ├── .env ├── .gitignore ├── .python-version ├── README.md ├── batches │ └── transcribe.py ├── common │ ├── __init__.py │ └── resources.py ├── download_model.py ├── nitric.yaml ├── pyproject.toml ├── python.dockerfile ├── python.dockerfile.dockerignore ├── services │ └── api.py ├── transcribe.dockerfile └── transcribe.dockerignore ├── product-inventory ├── README.md └── typescript │ ├── .env.template │ ├── .gitignore │ ├── README.md │ ├── common │ ├── email.ts │ └── resources.ts │ ├── nitric.aws.yaml │ ├── nitric.yaml │ ├── package.json │ ├── services │ ├── inventory.ts │ └── notify.ts │ └── tsconfig.json ├── profile-api-graphql ├── README.md └── typescript │ ├── .gitignore │ ├── README.md │ ├── nitric.yaml │ ├── package.json │ ├── services │ └── graphql.ts │ └── tsconfig.json ├── python-debugpy ├── .env ├── .gitignore ├── .python-version ├── .vscode │ └── launch.json ├── README.md ├── nitric.yaml ├── pyproject.toml ├── python.dockerfile ├── python.dockerfile.dockerignore ├── services │ ├── one.py │ └── two.py └── uv.lock ├── python-prediction ├── .env ├── .gitignore ├── .python-version ├── README.md ├── clean_data.txt ├── data.txt ├── nitric.yaml ├── prediction │ ├── preprocess.py │ └── training.py ├── pyproject.toml ├── python.dockerfile ├── python.dockerfile.dockerignore └── services │ └── prediction.py ├── python-starter-pipenv ├── .gitignore ├── Pipfile ├── README.md ├── nitric.yaml ├── python.dockerfile ├── python.dockerfile.dockerignore └── services │ └── hello.py ├── python-starter ├── .env ├── .gitignore ├── .python-version ├── README.md ├── nitric.yaml ├── pyproject.toml ├── python.dockerfile ├── python.dockerfile.dockerignore └── services │ └── api.py ├── realtime-chat-app └── README.md ├── scheduled-report ├── README.md └── python │ ├── .env │ ├── .gitignore │ ├── .python-version │ ├── nitric.aws.yaml │ ├── nitric.yaml │ ├── pyproject.toml │ ├── python.dockerfile │ ├── python.dockerfile.dockerignore │ └── services │ ├── hello.py │ └── helpers │ ├── __init__.py │ └── google.py ├── scheduled-tasks ├── README.md └── typescript │ ├── .gitignore │ ├── README.md │ ├── nitric.yaml │ ├── package.json │ ├── services │ └── tidy.ts │ └── tsconfig.json ├── stripe-payments ├── README.md └── typescript │ ├── .env.template │ ├── README.md │ ├── nitric.yaml │ ├── package.json │ ├── services │ └── payment.ts │ └── tsconfig.json ├── surveys-auth0 ├── README.md ├── src │ ├── .gitignore │ ├── apis │ │ ├── forms.ts │ │ └── receipts.ts │ ├── forms │ │ ├── form │ │ │ ├── index.ts │ │ │ ├── receipt.ts │ │ │ └── schema.ts │ │ ├── index.ts │ │ └── submissions.ts │ ├── handlers │ │ ├── deliver.ts │ │ └── pdfs.ts │ ├── nitric.yaml │ ├── package.json │ ├── resources │ │ ├── buckets.ts │ │ ├── index.ts │ │ ├── middleware.ts │ │ ├── store.ts │ │ └── topics.ts │ └── tsconfig.json ├── ui-noauth │ ├── .env.local.template │ ├── .eslintrc.json │ ├── .gitignore │ ├── LICENSE.md │ ├── jsconfig.json │ ├── next-env.d.ts │ ├── next.config.js │ ├── package.json │ ├── postcss.config.js │ ├── prettier.config.js │ ├── public │ │ ├── favicon.ico │ │ ├── fonts │ │ │ ├── Inter-italic.var.woff2 │ │ │ └── Inter-roman.var.woff2 │ │ └── images │ │ │ └── office.png │ ├── src │ │ ├── components │ │ │ ├── Button.tsx │ │ │ ├── Container.tsx │ │ │ ├── Footer.tsx │ │ │ ├── Form.tsx │ │ │ ├── Header.tsx │ │ │ ├── Logo.tsx │ │ │ └── NavLinks.tsx │ │ ├── pages │ │ │ ├── _app.tsx │ │ │ ├── _document.tsx │ │ │ ├── index.tsx │ │ │ └── survey.tsx │ │ ├── services │ │ │ └── apiClient.tsx │ │ └── styles │ │ │ └── tailwind.css │ ├── tailwind.config.js │ └── tsconfig.json └── ui │ ├── .env.local.template │ ├── .eslintrc.json │ ├── .gitignore │ ├── LICENSE.md │ ├── jsconfig.json │ ├── next-env.d.ts │ ├── next.config.js │ ├── package.json │ ├── postcss.config.js │ ├── prettier.config.js │ ├── public │ ├── favicon.ico │ ├── fonts │ │ ├── Inter-italic.var.woff2 │ │ └── Inter-roman.var.woff2 │ └── images │ │ └── office.png │ ├── src │ ├── components │ │ ├── Button.tsx │ │ ├── Container.tsx │ │ ├── Footer.tsx │ │ ├── Form.tsx │ │ ├── Header.tsx │ │ ├── LandingHeader.tsx │ │ ├── Logo.tsx │ │ └── NavLinks.tsx │ ├── pages │ │ ├── _app.tsx │ │ ├── _document.tsx │ │ ├── api │ │ │ └── auth │ │ │ │ └── [...auth0].tsx │ │ ├── index.tsx │ │ ├── resume.tsx │ │ └── survey.tsx │ ├── services │ │ └── apiClient.tsx │ └── styles │ │ └── tailwind.css │ ├── tailwind.config.js │ └── tsconfig.json ├── typescript-starter-deno ├── .gitignore ├── README.md ├── deno.dockerfile ├── deno.dockerfile.dockerignore ├── deno.json ├── nitric.yaml └── services │ └── api.ts ├── typescript-starter ├── .gitignore ├── README.md ├── nitric.yaml ├── node.dockerfile ├── node.dockerfile.dockerignore ├── package.json ├── services │ └── api.ts └── tsconfig.json ├── upload-secure-url ├── README.md └── typescript │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── common │ ├── handlers.ts │ └── resources.ts │ ├── nitric.aws.yaml │ ├── nitric.yaml │ ├── package.json │ ├── services │ └── images.ts │ ├── test │ └── url.test.ts │ └── tsconfig.json ├── uptime-monitoring ├── README.md └── assets │ ├── arch-diagram.png │ └── frontend.png ├── url-shortener-notify ├── README.md └── go │ ├── .gitignore │ ├── .vscode │ └── launch.json │ ├── README.md │ ├── go.mod │ ├── go.sum │ ├── golang.dockerfile │ ├── nitric.aws.yaml │ ├── nitric.yaml │ ├── resources │ └── main.go │ └── services │ ├── notify │ └── main.go │ └── shortener │ └── main.go ├── url-shortener ├── README.md └── go │ ├── .gitignore │ ├── .vscode │ └── launch.json │ ├── README.md │ ├── go.mod │ ├── go.sum │ ├── golang.dockerfile │ ├── nitric.aws.yaml │ ├── nitric.yaml │ ├── resources │ └── main.go │ └── services │ └── shortener │ └── main.go ├── user-onboarding ├── README.md └── typescript │ ├── .babelrc │ ├── .env.template │ ├── .gitignore │ ├── README.md │ ├── arch_diagram.png │ ├── common │ ├── email.ts │ └── resources.ts │ ├── nitric.aws.yaml │ ├── nitric.yaml │ ├── package.json │ ├── services │ ├── notify.ts │ └── onboard.ts │ └── tsconfig.json ├── website-status ├── README.md └── typescript │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── common │ ├── handlers.ts │ └── resources.ts │ ├── nitric.yaml │ ├── package.json │ ├── services │ └── ping.ts │ ├── test │ └── ping.test.ts │ └── tsconfig.json ├── websocket-app ├── .gitignore ├── README.md ├── go.mod ├── go.sum ├── golang.dockerfile ├── nitric.yaml └── services │ └── websockets │ └── main.go └── websockets ├── .gitignore ├── README.md ├── nitric.yaml ├── package.json ├── services └── messaging.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ 3 | .DS_Store 4 | .next 5 | **/yarn.lock -------------------------------------------------------------------------------- /v1/apollo-server/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ 3 | .npmrc 4 | git.store -------------------------------------------------------------------------------- /v1/apollo-server/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: apollo-demo 2 | services: 3 | - match: services/*.ts 4 | runtime: "" 5 | type: "" 6 | start: npm run dev:services $SERVICE_PATH 7 | -------------------------------------------------------------------------------- /v1/apollo-server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "private": true, 6 | "dependencies": { 7 | "@apollo/server": "^4.10.4", 8 | "@nitric/sdk": "^1.3.3", 9 | "cors": "^2.8.5", 10 | "graphql": "^16.8.1" 11 | }, 12 | "devDependencies": { 13 | "dotenv": "^16.4.4", 14 | "nodemon": "^3.1.4", 15 | "ts-node": "^10.9.2", 16 | "typescript": "^5.3.3" 17 | }, 18 | "scripts": { 19 | "dev:services": "nodemon -r dotenv/config" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /v1/apollo-server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/auth-firebase/assets/firebase-service-account.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitrictech/examples/865ca7e9ea7b95d171474e41b8b1b0b1f9bd99e2/v1/auth-firebase/assets/firebase-service-account.png -------------------------------------------------------------------------------- /v1/auth-firebase/assets/firebase-web-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitrictech/examples/865ca7e9ea7b95d171474e41b8b1b0b1f9bd99e2/v1/auth-firebase/assets/firebase-web-app.png -------------------------------------------------------------------------------- /v1/auth-firebase/frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | 4 | # generated types 5 | .astro/ 6 | 7 | # dependencies 8 | node_modules/ 9 | 10 | # logs 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # environment variables 17 | .env 18 | .env.production 19 | 20 | # macOS-specific files 21 | .DS_Store 22 | -------------------------------------------------------------------------------- /v1/auth-firebase/frontend/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["astro-build.astro-vscode"], 3 | "unwantedRecommendations": [] 4 | } 5 | -------------------------------------------------------------------------------- /v1/auth-firebase/frontend/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "command": "./node_modules/.bin/astro dev", 6 | "name": "Development server", 7 | "request": "launch", 8 | "type": "node-terminal" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /v1/auth-firebase/frontend/astro.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "astro/config"; 2 | import react from "@astrojs/react"; 3 | 4 | import tailwind from "@astrojs/tailwind"; 5 | 6 | // https://astro.build/config 7 | export default defineConfig({ 8 | integrations: [ 9 | react(), 10 | tailwind({ 11 | applyBaseStyles: false, 12 | }), 13 | ], 14 | }); 15 | -------------------------------------------------------------------------------- /v1/auth-firebase/frontend/components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "rsc": false, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.js", 8 | "css": "src/styles/globals.css", 9 | "baseColor": "slate", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils" 16 | } 17 | } -------------------------------------------------------------------------------- /v1/auth-firebase/frontend/src/components/auth/Google.tsx: -------------------------------------------------------------------------------- 1 | import { signInWithGoogle } from "@/lib/auth"; 2 | import { Button } from "../ui/button"; 3 | 4 | export const GoogleOauth = () => { 5 | return ( 6 | 7 | 12 | 13 | 14 | 15 | Sign up with Google 16 | 17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /v1/auth-firebase/frontend/src/components/auth/Logout.tsx: -------------------------------------------------------------------------------- 1 | import { logOut } from "@/lib/auth"; 2 | import { Button } from "../ui/button"; 3 | 4 | export const Logout = () => { 5 | return ( 6 | 7 | Log Out 8 | 9 | ); 10 | }; 11 | -------------------------------------------------------------------------------- /v1/auth-firebase/frontend/src/components/ui/input.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | export interface InputProps 6 | extends React.InputHTMLAttributes {} 7 | 8 | const Input = React.forwardRef( 9 | ({ className, type, ...props }, ref) => { 10 | return ( 11 | 20 | ) 21 | } 22 | ) 23 | Input.displayName = "Input" 24 | 25 | export { Input } 26 | -------------------------------------------------------------------------------- /v1/auth-firebase/frontend/src/components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import * as LabelPrimitive from "@radix-ui/react-label" 3 | import { cva, type VariantProps } from "class-variance-authority" 4 | 5 | import { cn } from "@/lib/utils" 6 | 7 | const labelVariants = cva( 8 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 9 | ) 10 | 11 | const Label = React.forwardRef< 12 | React.ElementRef, 13 | React.ComponentPropsWithoutRef & 14 | VariantProps 15 | >(({ className, ...props }, ref) => ( 16 | 21 | )) 22 | Label.displayName = LabelPrimitive.Root.displayName 23 | 24 | export { Label } 25 | -------------------------------------------------------------------------------- /v1/auth-firebase/frontend/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /v1/auth-firebase/frontend/src/lib/auth.ts: -------------------------------------------------------------------------------- 1 | import { GoogleAuthProvider, signInWithPopup, signOut } from "firebase/auth"; 2 | import { auth } from "@/lib/firebase"; 3 | 4 | const provider = new GoogleAuthProvider(); 5 | 6 | export const signInWithGoogle = () => { 7 | signInWithPopup(auth, provider) 8 | .then(() => (window.location.href = "/dashboard")) 9 | .catch((error) => console.log(error)); 10 | }; 11 | 12 | export const logOut = () => { 13 | signOut(auth) 14 | .then(() => (window.location.href = "/")) 15 | .catch((error) => console.log(error)); 16 | }; 17 | -------------------------------------------------------------------------------- /v1/auth-firebase/frontend/src/lib/firebase.ts: -------------------------------------------------------------------------------- 1 | import { initializeApp } from "firebase/app"; 2 | import { getAuth } from "firebase/auth"; 3 | 4 | // replace with yours 5 | const firebaseConfig = { 6 | apiKey: "", 7 | authDomain: "", 8 | projectId: "", 9 | storageBucket: "", 10 | messagingSenderId: "", 11 | appId: "", 12 | }; 13 | 14 | const app = initializeApp(firebaseConfig); 15 | 16 | export const auth = getAuth(app); 17 | -------------------------------------------------------------------------------- /v1/auth-firebase/frontend/src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { type ClassValue, clsx } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /v1/auth-firebase/frontend/src/pages/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { GoogleOauth } from "@/components/auth/Google"; 3 | import Layout from "../layouts/Layout.astro"; 4 | --- 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /v1/auth-firebase/frontend/src/types.ts: -------------------------------------------------------------------------------- 1 | export interface Site { 2 | url: string; 3 | discord: string; 4 | lastChecked: string; 5 | up: boolean; 6 | } 7 | -------------------------------------------------------------------------------- /v1/auth-firebase/frontend/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict", 3 | "compilerOptions": { 4 | "jsx": "react-jsx", 5 | "jsxImportSource": "react", 6 | "baseUrl": ".", 7 | "paths": { 8 | "@/*": ["./src/*"] 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /v1/auth-firebase/python/.env: -------------------------------------------------------------------------------- 1 | PYTHONPATH=. 2 | GOOGLE_APPLICATION_CREDENTIALS_JSON={"type": "service_account","project_id": "","private_key_id": "","private_key": "","client_email": "","client_id": "","auth_uri": "https://accounts.google.com/o/oauth2/auth","token_uri": "https://oauth2.googleapis.com/token","auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs","client_x509_cert_url": "","universe_domain": "googleapis.com"} -------------------------------------------------------------------------------- /v1/auth-firebase/python/.gitignore: -------------------------------------------------------------------------------- 1 | .nitric/ 2 | .venv 3 | __pycache__ 4 | -------------------------------------------------------------------------------- /v1/auth-firebase/python/.python-version: -------------------------------------------------------------------------------- 1 | 3.11 -------------------------------------------------------------------------------- /v1/auth-firebase/python/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: python-starter 2 | services: 3 | - match: services/*.py 4 | start: uv run watchmedo auto-restart -p *.py --no-restart-on-command-exit -R uv run $SERVICE_PATH 5 | runtime: python 6 | runtimes: 7 | python: 8 | dockerfile: "./python.dockerfile" 9 | -------------------------------------------------------------------------------- /v1/auth-firebase/python/pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "auth-firebase" 3 | version = "0.1.0" 4 | description = "Add your description here" 5 | readme = "README.md" 6 | requires-python = ">=3.11" 7 | dependencies = [ 8 | "nitric ==1.2.3", 9 | "betterproto ==2.0.0b6", 10 | "firebase-admin >=6.6.0" 11 | ] 12 | 13 | [tool.uv] 14 | dev-dependencies = [ 15 | "watchdog>=5.0.3", 16 | ] 17 | -------------------------------------------------------------------------------- /v1/auth-firebase/python/python.dockerfile.dockerignore: -------------------------------------------------------------------------------- 1 | .mypy_cache/ 2 | .nitric/ 3 | .venv/ 4 | nitric-spec.json 5 | nitric.yaml 6 | README.md -------------------------------------------------------------------------------- /v1/auth-firebase/typescript/.env.example: -------------------------------------------------------------------------------- 1 | GOOGLE_APPLICATION_CREDENTIALS_JSON={"type": "service_account","project_id": "","private_key_id": "","private_key": "","client_email": "","client_id": "","auth_uri": "https://accounts.google.com/o/oauth2/auth","token_uri": "https://oauth2.googleapis.com/token","auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs","client_x509_cert_url": "","universe_domain": "googleapis.com"} -------------------------------------------------------------------------------- /v1/auth-firebase/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ 3 | .npmrc 4 | git.store -------------------------------------------------------------------------------- /v1/auth-firebase/typescript/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: typescript 2 | services: 3 | - match: services/*.ts 4 | runtime: "" 5 | type: "" 6 | start: npm run dev:services $SERVICE_PATH 7 | -------------------------------------------------------------------------------- /v1/auth-firebase/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "private": true, 6 | "dependencies": { 7 | "@nitric/sdk": "^1.1.1", 8 | "firebase-admin": "^12.0.0" 9 | }, 10 | "devDependencies": { 11 | "dotenv": "^16.4.4", 12 | "nodemon": "^3.1.4", 13 | "ts-node": "^10.9.2", 14 | "typescript": "^5.3.3" 15 | }, 16 | "scripts": { 17 | "dev:services": "nodemon -r dotenv/config" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /v1/auth-firebase/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/blender-render/.env: -------------------------------------------------------------------------------- 1 | PYTHONPATH=. -------------------------------------------------------------------------------- /v1/blender-render/.python-version: -------------------------------------------------------------------------------- 1 | 3.11 -------------------------------------------------------------------------------- /v1/blender-render/blender.dockerignore: -------------------------------------------------------------------------------- 1 | .mypy_cache/ 2 | .nitric/ 3 | .venv/ 4 | nitric-spec.json 5 | nitric.yaml 6 | README.md -------------------------------------------------------------------------------- /v1/blender-render/common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitrictech/examples/865ca7e9ea7b95d171474e41b8b1b0b1f9bd99e2/v1/blender-render/common/__init__.py -------------------------------------------------------------------------------- /v1/blender-render/common/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitrictech/examples/865ca7e9ea7b95d171474e41b8b1b0b1f9bd99e2/v1/blender-render/common/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /v1/blender-render/common/__pycache__/resources.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitrictech/examples/865ca7e9ea7b95d171474e41b8b1b0b1f9bd99e2/v1/blender-render/common/__pycache__/resources.cpython-311.pyc -------------------------------------------------------------------------------- /v1/blender-render/common/resources.py: -------------------------------------------------------------------------------- 1 | from nitric.resources import api, job, bucket 2 | 3 | main_api = api("main") 4 | 5 | renderer_job = job("render-image") 6 | 7 | blend_bucket = bucket("blend-files") 8 | rendered_bucket = bucket("rendered-bucket") -------------------------------------------------------------------------------- /v1/blender-render/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: blender-render 2 | services: 3 | - match: services/main.py 4 | start: uv run watchmedo auto-restart -p *.py --no-restart-on-command-exit -R python -- -u $SERVICE_PATH 5 | runtime: python 6 | 7 | batch-services: 8 | - match: batches/renderer.py 9 | start: uv run watchmedo auto-restart -p *.py --no-restart-on-command-exit -R python -- -u $SERVICE_PATH 10 | runtime: blender 11 | 12 | runtimes: 13 | blender: 14 | dockerfile: blender.dockerfile 15 | python: 16 | dockerfile: python.dockerfile 17 | 18 | preview: 19 | - batch-services 20 | -------------------------------------------------------------------------------- /v1/blender-render/pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "python-uv-starter" 3 | version = "0.1.0" 4 | description = "Add your description here" 5 | readme = "README.md" 6 | requires-python = ">=3.11" 7 | dependencies = [ 8 | "nitric ==1.2.3", 9 | "betterproto ==2.0.0b6", 10 | ] 11 | 12 | [project.optional-dependencies] 13 | ml = [ 14 | "bpy>=4.2.0", 15 | ] 16 | 17 | [tool.uv] 18 | dev-dependencies = [ 19 | "watchdog>=5.0.3", 20 | ] 21 | -------------------------------------------------------------------------------- /v1/blender-render/python.dockerfile: -------------------------------------------------------------------------------- 1 | # The python version must match the version in .python-version 2 | FROM ghcr.io/astral-sh/uv:python3.11-bookworm-slim AS builder 3 | 4 | ARG HANDLER 5 | ENV HANDLER=${HANDLER} 6 | 7 | ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy PYTHONPATH=. 8 | WORKDIR /app 9 | COPY uv.lock pyproject.toml /app/ 10 | RUN --mount=type=cache,target=/root/.cache/uv \ 11 | uv sync --frozen --no-install-project --no-dev --no-python-downloads 12 | COPY . /app 13 | RUN --mount=type=cache,target=/root/.cache/uv \ 14 | uv sync --frozen --no-dev --no-python-downloads 15 | 16 | 17 | # Then, use a final image without uv 18 | FROM python:3.11-slim-bookworm 19 | 20 | ARG HANDLER 21 | ENV HANDLER=${HANDLER} PYTHONPATH=. 22 | 23 | # Copy the application from the builder 24 | COPY --from=builder /app /app 25 | WORKDIR /app 26 | 27 | # Place executables in the environment at the front of the path 28 | ENV PATH="/app/.venv/bin:$PATH" 29 | 30 | # Run the service using the path to the handler 31 | ENTRYPOINT python -u $HANDLER -------------------------------------------------------------------------------- /v1/blender-render/python.dockerignore: -------------------------------------------------------------------------------- 1 | .mypy_cache/ 2 | .nitric/ 3 | .venv/ 4 | nitric-spec.json 5 | nitric.yaml 6 | README.md -------------------------------------------------------------------------------- /v1/cloudflare-lb/.env.template: -------------------------------------------------------------------------------- 1 | CLOUDFLARE_ACCOUNT_ID= 2 | CLOUDFLARE_API_TOKEN= 3 | DOMAIN= 4 | SUBDOMAIN=demo 5 | -------------------------------------------------------------------------------- /v1/cloudflare-lb/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ -------------------------------------------------------------------------------- /v1/cloudflare-lb/infra/config.ts: -------------------------------------------------------------------------------- 1 | require('dotenv').config() 2 | import { LocalWorkspace } from "@pulumi/pulumi/automation"; 3 | import YAML from "yaml"; 4 | import * as fs from "fs"; 5 | 6 | export const getNitricYaml = () => { 7 | // read the nitric.yaml file 8 | return YAML.parse(fs.readFileSync("nitric.yaml").toString()); 9 | }; 10 | 11 | export const getNitricStacks = async () => { 12 | const project = getNitricYaml(); 13 | 14 | // Get the existing nitric stack 15 | const aws = await LocalWorkspace.selectStack({ 16 | projectName: project["name"], 17 | stackName: `${project["name"]}-prod-aws`, 18 | // we're just reading the resources, 19 | // so no need to run updates 20 | program: null, 21 | }); 22 | 23 | const gcp = await LocalWorkspace.selectStack({ 24 | projectName: project["name"], 25 | stackName: `${project["name"]}-prod-gcp`, 26 | // we're just reading the resources, 27 | // so no need to run updates 28 | program: null, 29 | }); 30 | 31 | return { aws, gcp }; 32 | } -------------------------------------------------------------------------------- /v1/cloudflare-lb/infra/down.ts: -------------------------------------------------------------------------------- 1 | // alias the nitric gateway 2 | import { LocalWorkspace } from "@pulumi/pulumi/automation"; 3 | import { getNitricYaml } from "./config"; 4 | 5 | const run = async () => { 6 | // read the nitric.yaml file 7 | const project = getNitricYaml(); 8 | 9 | // get the current nitric stack 10 | const dnsStack = await LocalWorkspace.createOrSelectStack({ 11 | projectName: `${project['name']}-dns`, 12 | stackName: `${project['name']}-dns-multicloud`, 13 | program: null, 14 | }); 15 | 16 | await dnsStack.destroy(); 17 | }; 18 | 19 | run().catch((err) => console.log(err)); -------------------------------------------------------------------------------- /v1/cloudflare-lb/nitric.prod-aws.yaml: -------------------------------------------------------------------------------- 1 | provider: nitric/aws@1.16.7 2 | region: us-east-1 3 | -------------------------------------------------------------------------------- /v1/cloudflare-lb/nitric.prod-gcp.yaml: -------------------------------------------------------------------------------- 1 | provider: nitric/gcp@1.16.7 2 | gcp-project-id: 3 | region: us-west2 4 | -------------------------------------------------------------------------------- /v1/cloudflare-lb/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: cloudflare-lb 2 | services: 3 | - basedir: "" 4 | match: services/*.ts 5 | runtime: node 6 | start: npm run dev:services $SERVICE_PATH 7 | batch-services: [] 8 | runtimes: 9 | node: 10 | dockerfile: ./node.dockerfile 11 | context: "" 12 | args: {} 13 | -------------------------------------------------------------------------------- /v1/cloudflare-lb/node.dockerfile.dockerignore: -------------------------------------------------------------------------------- 1 | .nitric/ 2 | .git/ 3 | .idea/ 4 | .vscode/ 5 | .github/ 6 | *.dockerfile 7 | *.dockerignore 8 | node_modules/ 9 | README.md -------------------------------------------------------------------------------- /v1/cloudflare-lb/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "main": "index.js", 6 | "private": true, 7 | "dependencies": { 8 | "@nitric/sdk": "^1.2.2" 9 | }, 10 | "devDependencies": { 11 | "@pulumi/aws": "^5.32.0", 12 | "@pulumi/cloudflare": "^5.0.0", 13 | "@pulumi/pulumi": "^3.58.0", 14 | "dotenv": "^16.4.4", 15 | "nodemon": "^3.1.4", 16 | "ts-node": "^10.9.2", 17 | "typescript": "^5.3.3", 18 | "yaml": "^2.2.1" 19 | }, 20 | "scripts": { 21 | "deploy:lb": "ts-node ./infra/up.ts", 22 | "destroy:lb": "ts-node ./infra/down.ts", 23 | "dev:services": "nodemon -r dotenv/config" 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /v1/cloudflare-lb/services/hello.ts: -------------------------------------------------------------------------------- 1 | import { api } from "@nitric/sdk"; 2 | 3 | const helloApi = api('main'); 4 | 5 | helloApi.get("/hello/:name", async (ctx) => { 6 | const { name } = ctx.req.params; 7 | 8 | ctx.res.body = `Hello ${name}`; 9 | 10 | return ctx; 11 | }); -------------------------------------------------------------------------------- /v1/cloudflare-lb/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/cockroach-example/typescript/.env.template: -------------------------------------------------------------------------------- 1 | DATABASE_URL=postgresql:/ 2 | -------------------------------------------------------------------------------- /v1/cockroach-example/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ -------------------------------------------------------------------------------- /v1/cockroach-example/typescript/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: cockroach-example 2 | services: 3 | - match: services/*.ts 4 | start: npm run dev:services $SERVICE_PATH 5 | -------------------------------------------------------------------------------- /v1/cockroach-example/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "main": "index.js", 6 | "private": true, 7 | "dependencies": { 8 | "@nitric/sdk": "^1.2.2", 9 | "pg": "^8.10.0" 10 | }, 11 | "devDependencies": { 12 | "dotenv": "^16.4.4", 13 | "nodemon": "^3.1.4", 14 | "ts-node": "^10.9.2", 15 | "typescript": "^5.3.3" 16 | }, 17 | "scripts": { 18 | "dev:services": "nodemon -r dotenv/config" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /v1/cockroach-example/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/custom-dockerfile-nestjs/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | parserOptions: { 4 | project: 'tsconfig.json', 5 | tsconfigRootDir: __dirname, 6 | sourceType: 'module', 7 | }, 8 | plugins: ['@typescript-eslint/eslint-plugin'], 9 | extends: [ 10 | 'plugin:@typescript-eslint/recommended', 11 | 'plugin:prettier/recommended', 12 | ], 13 | root: true, 14 | env: { 15 | node: true, 16 | jest: true, 17 | }, 18 | ignorePatterns: ['.eslintrc.js'], 19 | rules: { 20 | '@typescript-eslint/interface-name-prefix': 'off', 21 | '@typescript-eslint/explicit-function-return-type': 'off', 22 | '@typescript-eslint/explicit-module-boundary-types': 'off', 23 | '@typescript-eslint/no-explicit-any': 'off', 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /v1/custom-dockerfile-nestjs/.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist 3 | /node_modules 4 | 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | pnpm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | lerna-debug.log* 13 | 14 | # OS 15 | .DS_Store 16 | 17 | # Tests 18 | /coverage 19 | /.nyc_output 20 | 21 | # IDEs and editors 22 | /.idea 23 | .project 24 | .classpath 25 | .c9/ 26 | *.launch 27 | .settings/ 28 | *.sublime-workspace 29 | 30 | # IDE - VSCode 31 | .vscode/* 32 | !.vscode/settings.json 33 | !.vscode/tasks.json 34 | !.vscode/launch.json 35 | !.vscode/extensions.json -------------------------------------------------------------------------------- /v1/custom-dockerfile-nestjs/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all" 4 | } -------------------------------------------------------------------------------- /v1/custom-dockerfile-nestjs/nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/nest-cli", 3 | "collection": "@nestjs/schematics", 4 | "sourceRoot": "src", 5 | "compilerOptions": { 6 | "deleteOutDir": true 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /v1/custom-dockerfile-nestjs/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: test-http-wrapper 2 | services: 3 | - match: src/main.ts 4 | start: yarn start:dev 5 | type: default 6 | runtime: docker-wrapper 7 | runtimes: 8 | docker-wrapper: 9 | dockerfile: ./node.dockerfile 10 | args: {} 11 | -------------------------------------------------------------------------------- /v1/custom-dockerfile-nestjs/node.dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:alpine as build 2 | 3 | ARG HANDLER 4 | 5 | # Python and make are required by certain native package build processes in NPM packages. 6 | RUN apk add g++ make py3-pip 7 | RUN yarn global add typescript @vercel/ncc 8 | 9 | WORKDIR /usr/app 10 | 11 | COPY package.json yarn.lock ./ 12 | 13 | RUN yarn install --production --frozen-lockfile --cache-folder /tmp/.cache && \ 14 | rm -rf /tmp/.cache 15 | 16 | COPY . . 17 | 18 | RUN \ 19 | --mount=type=cache,target=/tmp/ncc-cache \ 20 | ncc build ${HANDLER} -o lib/ -t 21 | 22 | FROM node:alpine as final 23 | 24 | WORKDIR /usr/app 25 | 26 | RUN apk update && \ 27 | apk add --no-cache ca-certificates && \ 28 | update-ca-certificates 29 | 30 | COPY package.json yarn.lock ./ 31 | 32 | RUN yarn install --production --frozen-lockfile --cache-folder /tmp/.cache && \ 33 | rm -rf /tmp/.cache 34 | 35 | COPY . . 36 | 37 | COPY --from=build /usr/app/lib/ ./lib/ 38 | 39 | ENTRYPOINT ["node", "lib/index.js"] -------------------------------------------------------------------------------- /v1/custom-dockerfile-nestjs/src/app.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { ProfileController } from './profile/profile.controller'; 3 | import { ProfileService } from './profile/profile.service'; 4 | 5 | @Module({ 6 | imports: [], 7 | controllers: [ProfileController], 8 | providers: [ProfileService], 9 | }) 10 | export class AppModule {} 11 | -------------------------------------------------------------------------------- /v1/custom-dockerfile-nestjs/src/main.ts: -------------------------------------------------------------------------------- 1 | import { http } from '@nitric/sdk'; 2 | import { NestFactory } from '@nestjs/core'; 3 | import { AppModule } from './app.module'; 4 | 5 | async function bootstrap(port: number) { 6 | const app = await NestFactory.create(AppModule); 7 | return await app.listen(port); 8 | } 9 | 10 | http(bootstrap); 11 | -------------------------------------------------------------------------------- /v1/custom-dockerfile-nestjs/src/profile/profile.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get, Post, Delete, Param, Req } from '@nestjs/common'; 2 | import { Profile, ProfileService } from './profile.service'; 3 | import { Request } from 'express'; 4 | 5 | @Controller() 6 | export class ProfileController { 7 | constructor(private readonly profileService: ProfileService) {} 8 | 9 | @Get('/profile/:id') 10 | async getProfile(@Param('id') id: string) { 11 | return await this.profileService.getProfile(id); 12 | } 13 | 14 | @Post('/profile') 15 | async createProfile(@Req() req: Request>) { 16 | return await this.profileService.createProfile(req.body); 17 | } 18 | 19 | @Delete('/profile/:id') 20 | async deleteProfile(@Param('id') id: string) { 21 | return await this.profileService.deleteProfile(id); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /v1/custom-dockerfile-nestjs/test/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { INestApplication } from '@nestjs/common'; 3 | import * as request from 'supertest'; 4 | import { AppModule } from '../src/app.module'; 5 | 6 | describe('AppController (e2e)', () => { 7 | let app: INestApplication; 8 | 9 | beforeEach(async () => { 10 | const moduleFixture: TestingModule = await Test.createTestingModule({ 11 | imports: [AppModule], 12 | }).compile(); 13 | 14 | app = moduleFixture.createNestApplication(); 15 | await app.init(); 16 | }); 17 | 18 | it('/ (GET)', () => { 19 | return request(app.getHttpServer()) 20 | .get('/') 21 | .expect(200) 22 | .expect('Hello World!'); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /v1/custom-dockerfile-nestjs/test/jest-e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "moduleFileExtensions": ["js", "json", "ts"], 3 | "rootDir": ".", 4 | "testEnvironment": "node", 5 | "testRegex": ".e2e-spec.ts$", 6 | "transform": { 7 | "^.+\\.(t|j)s$": "ts-jest" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /v1/custom-dockerfile-nestjs/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /v1/custom-dockerfile-nestjs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "declaration": true, 5 | "removeComments": true, 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "allowSyntheticDefaultImports": true, 9 | "target": "ES2021", 10 | "sourceMap": true, 11 | "outDir": "./dist", 12 | "baseUrl": "./", 13 | "incremental": true, 14 | "skipLibCheck": true, 15 | "strictNullChecks": false, 16 | "noImplicitAny": false, 17 | "strictBindCallApply": false, 18 | "forceConsistentCasingInFileNames": false, 19 | "noFallthroughCasesInSwitch": false 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /v1/dart-starter/.gitignore: -------------------------------------------------------------------------------- 1 | # https://dart.dev/guides/libraries/private-files 2 | # Created by `dart pub` 3 | .dart_tool/ 4 | 5 | .nitric -------------------------------------------------------------------------------- /v1/dart-starter/dart.dockerfile: -------------------------------------------------------------------------------- 1 | FROM dart:stable AS build 2 | 3 | ARG HANDLER 4 | WORKDIR /app 5 | 6 | # Resolve app dependencies. 7 | COPY pubspec.* ./ 8 | RUN dart pub get 9 | 10 | # Ensure the ./bin folder exists 11 | RUN mkdir -p ./bin 12 | 13 | # Copy app source code and AOT compile it. 14 | COPY . . 15 | # Ensure packages are still up-to-date if anything has changed 16 | RUN dart pub get --offline 17 | RUN dart compile exe ./${HANDLER} -o bin/main 18 | 19 | # Build a minimal serving image from AOT-compiled `/server` and required system 20 | # libraries and configuration files stored in `/runtime/` from the build stage. 21 | FROM alpine 22 | 23 | COPY --from=build /runtime/ / 24 | COPY --from=build /app/bin/main /app/bin/ 25 | 26 | ENTRYPOINT ["/app/bin/main"] 27 | -------------------------------------------------------------------------------- /v1/dart-starter/dart.dockerfile.dockerignore: -------------------------------------------------------------------------------- 1 | .nitric/ 2 | .git/ 3 | .idea/ 4 | .vscode/ 5 | .github/ 6 | *.dockerfile 7 | *.dockerignore 8 | .dart_tool/ -------------------------------------------------------------------------------- /v1/dart-starter/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: dart-starter 2 | services: 3 | - match: services/*.dart 4 | start: dart run --observe $SERVICE_PATH 5 | runtime: dart 6 | 7 | runtimes: 8 | dart: 9 | dockerfile: ./dart.dockerfile 10 | args: {} 11 | -------------------------------------------------------------------------------- /v1/dart-starter/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: dart_starter 2 | description: A sample command-line application. 3 | version: 1.0.0 4 | # repository: https://github.com/my_org/my_repo 5 | 6 | environment: 7 | sdk: ^3.3.0 8 | 9 | # Add regular dependencies here. 10 | dependencies: 11 | nitric_sdk: ^1.5.0 12 | 13 | dev_dependencies: 14 | lints: ^3.0.0 15 | test: ^1.24.0 16 | -------------------------------------------------------------------------------- /v1/dart-starter/services/api.dart: -------------------------------------------------------------------------------- 1 | import 'package:nitric_sdk/nitric.dart'; 2 | 3 | void main() { 4 | final mainApi = Nitric.api("main"); 5 | 6 | mainApi.get("/hello/:name", (ctx) async { 7 | final name = ctx.req.pathParams["name"]!; 8 | 9 | ctx.res.body = "Hello $name"; 10 | 11 | return ctx; 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /v1/dynamic-load/typescript/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "targets": { 7 | "node": "current" 8 | } 9 | } 10 | ] 11 | ] 12 | } -------------------------------------------------------------------------------- /v1/dynamic-load/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ -------------------------------------------------------------------------------- /v1/dynamic-load/typescript/animals/cat/greeting.ts: -------------------------------------------------------------------------------- 1 | export function sayHello() { 2 | return "meow"; 3 | } 4 | -------------------------------------------------------------------------------- /v1/dynamic-load/typescript/animals/dog/greeting.ts: -------------------------------------------------------------------------------- 1 | export function sayHello() { 2 | return "woof woof!"; 3 | } 4 | -------------------------------------------------------------------------------- /v1/dynamic-load/typescript/animals/donkey/greeting.ts: -------------------------------------------------------------------------------- 1 | export function sayHello() { 2 | return "eyooreee eyorreee!"; 3 | } 4 | -------------------------------------------------------------------------------- /v1/dynamic-load/typescript/animals/process/greeting.ts: -------------------------------------------------------------------------------- 1 | export function sayHello() { 2 | return process.env.GREETING as string; 3 | } 4 | -------------------------------------------------------------------------------- /v1/dynamic-load/typescript/common/handlers.ts: -------------------------------------------------------------------------------- 1 | export const speak = async (ctx) => { 2 | const { animal } = ctx.req.params; 3 | try { 4 | // Dynamically load the module 5 | const handler = await require(`../animals/${animal}/greeting`); 6 | ctx.res.json({ 7 | message: `${handler.sayHello()}`, 8 | }); 9 | } catch (error) { 10 | ctx.res.json({ 11 | message: `No module found for animal with name ${animal}`, 12 | }); 13 | ctx.res.status = 501; 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /v1/dynamic-load/typescript/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: Nitric-DynamicLoad 2 | services: 3 | - match: services/*.ts 4 | start: npm run dev:services $SERVICE_PATH 5 | -------------------------------------------------------------------------------- /v1/dynamic-load/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "main": "index.js", 6 | "private": true, 7 | "dependencies": { 8 | "@nitric/sdk": "^1.2.2", 9 | "jest": "^29.5.0" 10 | }, 11 | "devDependencies": { 12 | "@types/jest": "^29.5.1", 13 | "babel-jest": "^29.5.0", 14 | "@babel/preset-env": "^7.21.4", 15 | "dotenv": "^16.4.4", 16 | "nodemon": "^3.1.4", 17 | "ts-node": "^10.9.2", 18 | "typescript": "^5.3.3" 19 | }, 20 | "scripts": { 21 | "dev:services": "nodemon -r dotenv/config", 22 | "test": "jest" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /v1/dynamic-load/typescript/services/api.ts: -------------------------------------------------------------------------------- 1 | import { api } from "@nitric/sdk"; 2 | import { speak } from "../common/handlers"; 3 | 4 | // Create a secure api 5 | const animalsApi = api("main"); 6 | 7 | // Create and expose a GET method on our api 8 | animalsApi.get("/hello/:animal", speak); 9 | -------------------------------------------------------------------------------- /v1/dynamic-load/typescript/test/speak.test.ts: -------------------------------------------------------------------------------- 1 | import { speak } from "../common/handlers"; 2 | 3 | describe("speak", () => { 4 | let ctx; 5 | 6 | beforeEach(() => { 7 | ctx = { 8 | req: { 9 | params: { 10 | animal: "dog", 11 | }, 12 | }, 13 | res: { 14 | json: jest.fn(), 15 | status: jest.fn(), 16 | }, 17 | }; 18 | }); 19 | 20 | it("should return a greeting for a valid animal", async () => { 21 | const mockSayHelloMock = jest.fn(() => "Woof!"); 22 | jest.mock("../animals/dog/greeting", () => ({ 23 | sayHello: mockSayHelloMock, 24 | })); 25 | 26 | await speak(ctx); 27 | 28 | expect(mockSayHelloMock).toHaveBeenCalled(); 29 | expect(ctx.res.json).toHaveBeenCalledWith({ message: "Woof!" }); 30 | expect(ctx.res.status).not.toHaveBeenCalled(); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /v1/dynamic-load/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/flutter/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | **/ios/Flutter/.last_build_id 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Symbolication related 35 | app.*.symbols 36 | 37 | # Obfuscation related 38 | app.*.map.json 39 | 40 | # Android Studio will place build artifacts here 41 | /android/app/debug 42 | /android/app/profile 43 | /android/app/release 44 | -------------------------------------------------------------------------------- /v1/flutter/docker/flutter.dockerignore: -------------------------------------------------------------------------------- 1 | build 2 | test 3 | .nitric 4 | .idea 5 | .dart_tool 6 | .git 7 | docker 8 | android 9 | ios 10 | linux 11 | macos 12 | web 13 | windows -------------------------------------------------------------------------------- /v1/flutter/lib/cors.dart: -------------------------------------------------------------------------------- 1 | import 'package:nitric_sdk/nitric.dart'; 2 | 3 | /// Handle Preflight Options requests by returning status 200 to the requests 4 | Future optionsHandler(HttpContext ctx) async { 5 | ctx.res.headers["Content-Type"] = ["text/html; charset=ascii"]; 6 | ctx.res.body = "OK"; 7 | 8 | return ctx.next(); 9 | } 10 | 11 | /// Add CORS headers to responses 12 | Future addCors(HttpContext ctx) async { 13 | ctx.res.headers["Access-Control-Allow-Origin"] = ["*"]; 14 | ctx.res.headers["Access-Control-Allow-Headers"] = [ 15 | "Origin, X-Requested-With, Content-Type, Accept, Authorization", 16 | ]; 17 | ctx.res.headers["Access-Control-Allow-Methods"] = [ 18 | "GET, PUT, POST, PATCH, OPTIONS, DELETE", 19 | ]; 20 | ctx.res.headers["Access-Control-Max-Age"] = ["7200"]; 21 | 22 | return ctx.next(); 23 | } 24 | -------------------------------------------------------------------------------- /v1/flutter/lib/favorite.dart: -------------------------------------------------------------------------------- 1 | class Favorite { 2 | /// The name of the favorite 3 | String name; 4 | 5 | Favorite(this.name); 6 | 7 | /// Convert a json decodable map to a Favorite object 8 | Favorite.fromJson(Map json) : name = json['name']; 9 | 10 | /// Convert a Favorite object to a json encodable 11 | static Map toJson(Favorite favorite) => 12 | {'name': favorite.name}; 13 | } 14 | -------------------------------------------------------------------------------- /v1/flutter/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:provider/provider.dart'; 3 | import 'package:word_generator/pages/home.dart'; 4 | import 'package:word_generator/providers/favorites.dart'; 5 | import 'package:word_generator/providers/word.dart'; 6 | 7 | void main() => runApp(Application()); 8 | 9 | class Application extends StatelessWidget { 10 | const Application({super.key}); 11 | @override 12 | Widget build(BuildContext context) { 13 | return MultiProvider( 14 | providers: [ 15 | ChangeNotifierProvider(create: (context) => FavoritesProvider()), 16 | ChangeNotifierProvider(create: (context) => WordProvider()), 17 | ], 18 | child: MaterialApp( 19 | title: 'Word Generator App', 20 | theme: ThemeData( 21 | useMaterial3: true, 22 | colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue), 23 | ), 24 | home: HomePage(), // <-- Change here 25 | ), 26 | ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /v1/flutter/lib/providers/word.dart: -------------------------------------------------------------------------------- 1 | import 'package:english_words/english_words.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class WordProvider extends ChangeNotifier { 5 | // The current word pair 6 | var current = WordPair.random(); 7 | // A list of all generated word pairs 8 | var history = []; 9 | 10 | // A key that is used to get a reference to the history list state 11 | GlobalKey? historyListKey; 12 | 13 | // Generate a new word pair and notify the listeners 14 | void getNext() { 15 | // Add the current pair to the start of the history list 16 | history.insert(0, current); 17 | 18 | // Adds space to the start of the animated list and triggers an animation to start 19 | var animatedList = historyListKey?.currentState as AnimatedListState?; 20 | animatedList?.insertItem(0); 21 | 22 | current = WordPair.random(); 23 | notifyListeners(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /v1/flutter/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: backend 2 | services: 3 | - match: lib/services/*.dart 4 | runtime: flutter 5 | start: dart run $SERVICE_PATH 6 | runtimes: 7 | flutter: 8 | dockerfile: ./docker/flutter.dockerfile 9 | args: {} 10 | -------------------------------------------------------------------------------- /v1/go-starter/.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # 'nitric run' log directory 15 | .nitric/ 16 | 17 | git.store -------------------------------------------------------------------------------- /v1/go-starter/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "go", 9 | "name": "Debug Nitric App", 10 | "request": "launch", 11 | "mode": "debug", 12 | "program": "${workspaceFolder}/services/hello/main.go", 13 | "cwd": "${workspaceFolder}" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /v1/go-starter/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/nitrictech/templates/go-starter 2 | 3 | go 1.22.1 4 | 5 | toolchain go1.22.8 6 | 7 | require github.com/nitrictech/go-sdk v1.1.1 8 | 9 | require ( 10 | github.com/missionMeteora/toolkit v0.0.0-20170713173850-88364e3ef8cc // indirect 11 | github.com/nitrictech/nitric/core v0.0.0-20241003062412-76ea6275fb0b // indirect 12 | github.com/nitrictech/protoutils v0.0.0-20220321044654-02667a814cdf // indirect 13 | golang.org/x/net v0.28.0 // indirect 14 | golang.org/x/sys v0.25.0 // indirect 15 | golang.org/x/text v0.18.0 // indirect 16 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect 17 | google.golang.org/grpc v1.66.0 // indirect 18 | google.golang.org/protobuf v1.34.2 // indirect 19 | ) 20 | -------------------------------------------------------------------------------- /v1/go-starter/golang.dockerfile: -------------------------------------------------------------------------------- 1 | 2 | FROM golang:alpine as build 3 | 4 | ARG HANDLER 5 | 6 | WORKDIR /app/ 7 | 8 | COPY go.mod *.sum ./ 9 | 10 | RUN go mod download 11 | 12 | COPY . . 13 | 14 | # Build the Go App from the provided HANDLER (this will be based on matches in your nitric.yaml fle) 15 | RUN go build -o /bin/main ./${HANDLER}/... 16 | 17 | FROM alpine 18 | 19 | COPY --from=build /bin/main /bin/main 20 | 21 | RUN chmod +x-rw /bin/main 22 | RUN apk update && \ 23 | apk add --no-cache tzdata ca-certificates && \ 24 | update-ca-certificates 25 | 26 | ENTRYPOINT ["/bin/main"] -------------------------------------------------------------------------------- /v1/go-starter/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: go-starter 2 | services: 3 | - match: services/* 4 | start: go run ./$SERVICE_PATH/... 5 | runtime: go 6 | 7 | 8 | runtimes: 9 | go: 10 | dockerfile: ./golang.dockerfile 11 | args: {} -------------------------------------------------------------------------------- /v1/go-starter/services/hello/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/nitrictech/go-sdk/nitric" 7 | "github.com/nitrictech/go-sdk/nitric/apis" 8 | ) 9 | 10 | func main() { 11 | api := nitric.NewApi("main") 12 | 13 | api.Get("/hello/:name", func(ctx *apis.Ctx) { 14 | name := ctx.Request.PathParams()["name"] 15 | ctx.Response.Body = []byte(fmt.Sprintf("Hello %s", name)) 16 | }) 17 | 18 | nitric.Run() 19 | } 20 | -------------------------------------------------------------------------------- /v1/javascript-starter/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ 3 | .npmrc 4 | git.store -------------------------------------------------------------------------------- /v1/javascript-starter/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: javascript-starter 2 | services: 3 | - match: ./services/*.js 4 | start: npm run dev:services $SERVICE_PATH 5 | runtime: node 6 | runtimes: 7 | node: 8 | dockerfile: ./node.dockerfile 9 | args: {} 10 | -------------------------------------------------------------------------------- /v1/javascript-starter/node.dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | FROM node:22.4.1-alpine 3 | 4 | ARG HANDLER 5 | ENV HANDLER=${HANDLER} 6 | 7 | # Python and make are required by certain native package build processes in NPM packages. 8 | RUN --mount=type=cache,sharing=locked,target=/etc/apk/cache \ 9 | apk --update-cache add git g++ make py3-pip 10 | 11 | RUN apk update && \ 12 | apk add --no-cache ca-certificates && \ 13 | update-ca-certificates 14 | 15 | COPY . . 16 | 17 | RUN yarn import || echo Lockfile already exists 18 | 19 | RUN \ 20 | set -ex; \ 21 | yarn install --production --frozen-lockfile --cache-folder /tmp/.cache; \ 22 | rm -rf /tmp/.cache; 23 | 24 | ENTRYPOINT node --import ./$HANDLER 25 | -------------------------------------------------------------------------------- /v1/javascript-starter/node.dockerfile.dockerignore: -------------------------------------------------------------------------------- 1 | .nitric/ 2 | .git/ 3 | .idea/ 4 | .vscode/ 5 | .github/ 6 | *.dockerfile 7 | *.dockerignore 8 | node_modules/ 9 | README.md -------------------------------------------------------------------------------- /v1/javascript-starter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "javascript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric javascript starter template", 5 | "private": true, 6 | "type": "module", 7 | "dependencies": { 8 | "@nitric/sdk": "^1.3.3" 9 | }, 10 | "devDependencies": { 11 | "dotenv": "^16.4.5", 12 | "nodemon": "^3.1.4" 13 | }, 14 | "scripts": { 15 | "dev:services": "nodemon -r dotenv/config" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /v1/javascript-starter/services/api.js: -------------------------------------------------------------------------------- 1 | import { api } from "@nitric/sdk"; 2 | 3 | const mainApi = api("main"); 4 | 5 | mainApi.get("/hello/:name", async (ctx) => { 6 | const { name } = ctx.req.params; 7 | 8 | ctx.res.body = `Hello ${name}`; 9 | 10 | return ctx; 11 | }); 12 | -------------------------------------------------------------------------------- /v1/llama-rag/.env: -------------------------------------------------------------------------------- 1 | PYTHONPATH=. -------------------------------------------------------------------------------- /v1/llama-rag/.gitignore: -------------------------------------------------------------------------------- 1 | .nitric/ 2 | .venv/ 3 | nitric-spec.json 4 | __pycache__ 5 | model/ 6 | query_engine_vectors/ -------------------------------------------------------------------------------- /v1/llama-rag/.python-version: -------------------------------------------------------------------------------- 1 | 3.11 -------------------------------------------------------------------------------- /v1/llama-rag/build_query_engine.py: -------------------------------------------------------------------------------- 1 | from common.model_parameters import llm, embed_model, persist_dir 2 | 3 | from llama_index.core import SimpleDirectoryReader, VectorStoreIndex, Settings 4 | 5 | input_dir_path = "..." 6 | 7 | Settings.llm = llm 8 | Settings.embed_model = embed_model 9 | 10 | # load data 11 | loader = SimpleDirectoryReader( 12 | input_dir = input_dir_path, 13 | required_exts=[".mdx"], 14 | recursive=True 15 | ) 16 | docs = loader.load_data() 17 | 18 | index = VectorStoreIndex.from_documents(docs, show_progress=True) 19 | 20 | index.storage_context.persist(persist_dir) -------------------------------------------------------------------------------- /v1/llama-rag/common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitrictech/examples/865ca7e9ea7b95d171474e41b8b1b0b1f9bd99e2/v1/llama-rag/common/__init__.py -------------------------------------------------------------------------------- /v1/llama-rag/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: llama-rag 2 | services: 3 | - basedir: "" 4 | match: services/*.py 5 | runtime: python 6 | start: uv run watchmedo auto-restart -p *.py --no-restart-on-command-exit -R uv run $SERVICE_PATH 7 | runtimes: 8 | python: 9 | dockerfile: ./python.dockerfile 10 | -------------------------------------------------------------------------------- /v1/llama-rag/pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "llama-rag" 3 | version = "0.1.0" 4 | description = "Use Retrieval Augmented Generation (RAG) with a Llama 3.2 model" 5 | readme = "README.md" 6 | requires-python = ">=3.11" 7 | dependencies = [ 8 | "nitric ==1.2.3", 9 | "betterproto ==2.0.0b6", 10 | "llama-index>=0.11.22", 11 | "llama-index-embeddings-huggingface>=0.3.1", 12 | "llama-index-llms-ollama>=0.3.6", 13 | "llama-index-llms-llama-cpp>=0.2.3", 14 | ] 15 | 16 | [tool.uv] 17 | dev-dependencies = [ 18 | "watchdog>=5.0.3", 19 | ] 20 | -------------------------------------------------------------------------------- /v1/llama-rag/python.dockerfile: -------------------------------------------------------------------------------- 1 | # The python version must match the version in .python-version 2 | FROM ghcr.io/astral-sh/uv:python3.11-bookworm AS builder 3 | 4 | ARG HANDLER 5 | ENV HANDLER=${HANDLER} 6 | 7 | ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy PYTHONPATH=. 8 | WORKDIR /app 9 | COPY uv.lock pyproject.toml /app/ 10 | RUN --mount=type=cache,target=/root/.cache/uv \ 11 | uv sync --frozen --no-install-project --no-dev --no-python-downloads 12 | COPY . /app 13 | RUN --mount=type=cache,target=/root/.cache/uv \ 14 | uv sync --frozen --no-dev --no-python-downloads 15 | 16 | 17 | # Then, use a final image without uv 18 | FROM python:3.11-bookworm 19 | 20 | ARG HANDLER 21 | ENV HANDLER=${HANDLER} PYTHONPATH=. 22 | 23 | # Copy the application from the builder 24 | COPY --from=builder /app /app 25 | WORKDIR /app 26 | 27 | # Place executables in the environment at the front of the path 28 | ENV PATH="/app/.venv/bin:$PATH" 29 | 30 | # Run the service using the path to the handler 31 | ENTRYPOINT python -u $HANDLER -------------------------------------------------------------------------------- /v1/llama-rag/python.dockerfile.dockerignore: -------------------------------------------------------------------------------- 1 | .mypy_cache/ 2 | .nitric/ 3 | .venv/ 4 | nitric-spec.json 5 | nitric.yaml 6 | README.md -------------------------------------------------------------------------------- /v1/middleware-demo/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ -------------------------------------------------------------------------------- /v1/middleware-demo/typescript/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: typescript 2 | services: 3 | - match: services/*.ts 4 | start: npm run dev:services $SERVICE_PATH 5 | -------------------------------------------------------------------------------- /v1/middleware-demo/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "main": "index.js", 6 | "private": true, 7 | "dependencies": { 8 | "@nitric/sdk": "^1.2.2" 9 | }, 10 | "devDependencies": { 11 | "dotenv": "^16.4.4", 12 | "nodemon": "^3.1.4", 13 | "ts-node": "^10.9.2", 14 | "typescript": "^5.3.3" 15 | }, 16 | "scripts": { 17 | "dev:services": "nodemon -r dotenv/config" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /v1/middleware-demo/typescript/services/hello.ts: -------------------------------------------------------------------------------- 1 | import { api } from "@nitric/sdk"; 2 | 3 | const validate = (ctx, next) => { 4 | // Perform request validation, etc. 5 | console.log("This is your middleware function running ..."); 6 | next(ctx); 7 | }; 8 | 9 | const helloApi = api("hello", { 10 | middleware: [validate], 11 | }); 12 | 13 | helloApi.get("/hello/:name", async (ctx) => { 14 | const { name } = ctx.req.params; 15 | console.log("This is your main function running ..."); 16 | ctx.res.body = `Hello ${name}`; 17 | 18 | return ctx; 19 | }); 20 | -------------------------------------------------------------------------------- /v1/middleware-demo/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/multi-language/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitrictech/examples/865ca7e9ea7b95d171474e41b8b1b0b1f9bd99e2/v1/multi-language/architecture.png -------------------------------------------------------------------------------- /v1/multi-language/go/.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # 'nitric run' log directory 15 | .nitric/ 16 | 17 | git.store -------------------------------------------------------------------------------- /v1/multi-language/go/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/nitrictech/templates/go-starter 2 | 3 | go 1.21 4 | 5 | toolchain go1.21.4 6 | 7 | require github.com/nitrictech/go-sdk v1.0.7 8 | 9 | require ( 10 | github.com/missionMeteora/toolkit v0.0.0-20170713173850-88364e3ef8cc // indirect 11 | github.com/nitrictech/nitric/core v0.0.0-20240614052744-71e6e05bc47e // indirect 12 | github.com/nitrictech/protoutils v0.0.0-20220321044654-02667a814cdf // indirect 13 | golang.org/x/net v0.33.0 // indirect 14 | golang.org/x/sys v0.28.0 // indirect 15 | golang.org/x/text v0.21.0 // indirect 16 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d // indirect 17 | google.golang.org/grpc v1.64.1 // indirect 18 | google.golang.org/protobuf v1.34.2 // indirect 19 | ) 20 | -------------------------------------------------------------------------------- /v1/multi-language/go/golang.dockerfile: -------------------------------------------------------------------------------- 1 | 2 | FROM golang:alpine as build 3 | 4 | ARG HANDLER 5 | 6 | WORKDIR /app/ 7 | 8 | COPY go.mod *.sum ./ 9 | 10 | RUN go mod download 11 | 12 | COPY . . 13 | 14 | # Build the Go App from the provided HANDLER (this will be based on matches in your nitric.yaml fle) 15 | RUN go build -o /bin/main ./${HANDLER}/... 16 | 17 | FROM alpine 18 | 19 | COPY --from=build /bin/main /bin/main 20 | 21 | RUN chmod +x-rw /bin/main 22 | RUN apk update && \ 23 | apk add --no-cache tzdata ca-certificates && \ 24 | update-ca-certificates 25 | 26 | ENTRYPOINT ["/bin/main"] -------------------------------------------------------------------------------- /v1/multi-language/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: multi-language 2 | services: 3 | - basedir: ./ts 4 | match: services/*.ts 5 | start: npm run dev:services $SERVICE_PATH 6 | - basedir: ./go 7 | match: services/* 8 | runtime: go 9 | start: go run ./$SERVICE_PATH/... 10 | runtimes: 11 | go: 12 | dockerfile: ./go/golang.dockerfile 13 | args: {} 14 | -------------------------------------------------------------------------------- /v1/multi-language/ts/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ 3 | .npmrc 4 | git.store -------------------------------------------------------------------------------- /v1/multi-language/ts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "private": true, 6 | "dependencies": { 7 | "@nitric/sdk": "^1.2.2" 8 | }, 9 | "devDependencies": { 10 | "@types/node": "^22.1.0", 11 | "dotenv": "^16.4.5", 12 | "nodemon": "^3.1.4", 13 | "ts-node": "^10.9.2", 14 | "typescript": "^5.5.4" 15 | }, 16 | "scripts": { 17 | "dev:services": "nodemon -r dotenv/config" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /v1/multi-language/ts/services/hello.ts: -------------------------------------------------------------------------------- 1 | import * as nitric from "@nitric/sdk"; 2 | 3 | const api = nitric.api("main"); 4 | const helloTypescriptTopic = nitric.topic("hello-typescript"); 5 | const helloGolangTopic = nitric.topic("hello-golang").allow("publish"); 6 | 7 | api.get("/hello-golang", async (ctx) => { 8 | // Publish a message to the Golang topic 9 | await helloGolangTopic.publish({message: "Hello from Typescript"}); 10 | 11 | ctx.res.body = "Saying hello to Golang from Typescript"; 12 | }) 13 | 14 | helloTypescriptTopic.subscribe(async () => { 15 | console.log("Received a message from Golang"); 16 | }); 17 | -------------------------------------------------------------------------------- /v1/multi-language/ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/neon-tasklist/javascript/.env.template: -------------------------------------------------------------------------------- 1 | DATABASE_URL= -------------------------------------------------------------------------------- /v1/neon-tasklist/javascript/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ 3 | .env -------------------------------------------------------------------------------- /v1/neon-tasklist/javascript/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: echo 2 | services: 3 | - match: services/*.js 4 | start: npm run dev:services $SERVICE_PATH 5 | -------------------------------------------------------------------------------- /v1/neon-tasklist/javascript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "javascript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric javascript starter template", 5 | "main": "index.js", 6 | "private": true, 7 | "type": "module", 8 | "dependencies": { 9 | "@nitric/sdk": "^1.2.2", 10 | "pg": "^8.11.0" 11 | }, 12 | "devDependencies": { 13 | "dotenv": "^16.4.4", 14 | "nodemon": "^3.1.4" 15 | }, 16 | "scripts": { 17 | "dev:services": "nodemon -r dotenv/config" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /v1/neon-tasklist/javascript/resources/db.js: -------------------------------------------------------------------------------- 1 | import pg from "pg" 2 | 3 | const { Pool } = pg; 4 | 5 | const { DATABASE_URL } = process.env; 6 | export const conn = new Pool({ 7 | connectionString: DATABASE_URL, 8 | ssl: { 9 | rejectUnauthorized: false, 10 | }, 11 | }); 12 | 13 | -------------------------------------------------------------------------------- /v1/neon/javascript/.env.template: -------------------------------------------------------------------------------- 1 | DATABASE_URL= -------------------------------------------------------------------------------- /v1/neon/javascript/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ 3 | .env -------------------------------------------------------------------------------- /v1/neon/javascript/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: echo 2 | services: 3 | - match: services/*.js 4 | start: npm run dev:services $SERVICE_PATH 5 | -------------------------------------------------------------------------------- /v1/neon/javascript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "javascript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric javascript starter template", 5 | "main": "index.js", 6 | "private": true, 7 | "type": "module", 8 | "dependencies": { 9 | "@nitric/sdk": "^1.2.2", 10 | "pg": "^8.11.0" 11 | }, 12 | "devDependencies": { 13 | "dotenv": "^16.4.4", 14 | "nodemon": "^3.1.4", 15 | "ts-node": "^10.9.2", 16 | "typescript": "^5.3.3" 17 | }, 18 | "scripts": { 19 | "dev:services": "nodemon -r dotenv/config" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /v1/neon/javascript/resources/db.js: -------------------------------------------------------------------------------- 1 | import pg from "pg" 2 | 3 | const { Pool } = pg; 4 | 5 | const { DATABASE_URL } = process.env; 6 | export const pool = new Pool({ 7 | connectionString: DATABASE_URL, 8 | ssl: { 9 | rejectUnauthorized: false, 10 | }, 11 | }); 12 | 13 | -------------------------------------------------------------------------------- /v1/neon/javascript/services/neon.js: -------------------------------------------------------------------------------- 1 | import { api } from "@nitric/sdk"; 2 | import { pool } from "../resources/db.js"; 3 | 4 | const echo = api('main'); 5 | 6 | export async function getPostgresVersion() { 7 | const client = await pool.connect(); 8 | try { 9 | const version = await client.query('SELECT version()'); 10 | return version.rows; 11 | } finally { 12 | client.release(); 13 | } 14 | } 15 | 16 | echo.get("/version", async (ctx) => { 17 | ctx.res.json(await getPostgresVersion()); 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /v1/nitric-drizzle/.env.template: -------------------------------------------------------------------------------- 1 | DB_URL="postgresql://postgres:localsecret@localhost:5432/todos" -------------------------------------------------------------------------------- /v1/nitric-drizzle/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ 3 | .npmrc 4 | git.store -------------------------------------------------------------------------------- /v1/nitric-drizzle/db.ts: -------------------------------------------------------------------------------- 1 | import { sql } from "@nitric/sdk"; 2 | import { type PostgresJsDatabase, drizzle } from "drizzle-orm/postgres-js"; 3 | import postgres from "postgres"; 4 | 5 | const db = sql("todos", { 6 | // points to our custom drizzle migration dockerfile 7 | migrations: "dockerfile://migrate.dockerfile", 8 | }); 9 | 10 | let drizzleClient: PostgresJsDatabase; 11 | 12 | const getClient = async () => { 13 | // ensure we only create the client once 14 | if (!drizzleClient) { 15 | const connectionString = await db.connectionString(); 16 | 17 | const queryClient = postgres(connectionString); 18 | drizzleClient = drizzle(queryClient); 19 | } 20 | return drizzleClient; 21 | }; 22 | 23 | // export our getClient function, which will be used to get the drizzle client during runtime 24 | export default getClient; 25 | -------------------------------------------------------------------------------- /v1/nitric-drizzle/drizzle.config.ts: -------------------------------------------------------------------------------- 1 | import "dotenv/config"; 2 | import { defineConfig } from "drizzle-kit"; 3 | 4 | export default defineConfig({ 5 | schema: "./schema.ts", 6 | out: "./drizzle", 7 | dialect: "postgresql", 8 | dbCredentials: { 9 | url: process.env.DB_URL, 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /v1/nitric-drizzle/migrate.dockerfile: -------------------------------------------------------------------------------- 1 | # Use an official Node.js runtime as the base image 2 | FROM node 3 | 4 | ENV DB_URL="" 5 | ENV NITRIC_DB_NAME="" 6 | 7 | # Copy package.json and package-lock.json into the Docker image 8 | COPY package*.json ./ 9 | 10 | # Install the application's dependencies inside the Docker image 11 | RUN npm ci 12 | 13 | # Copy the rest of the application into the Docker image 14 | COPY . . 15 | 16 | # Build the Prisma client 17 | RUN npx drizzle-kit generate 18 | 19 | # Run the migrations and start the application when the Docker container starts 20 | # We define the entrypoint like this so we can correctly copy it out when running it 21 | # in the various clouds (e.g. AWS Codebuild does not respect ENTRYPOINT and CMD) 22 | ENTRYPOINT ["sh", "-c", "npx drizzle-kit migrate"] -------------------------------------------------------------------------------- /v1/nitric-drizzle/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: todo-app 2 | services: 3 | - match: services/*.ts 4 | runtime: "" 5 | type: "" 6 | start: npm run dev:services $SERVICE_PATH 7 | preview: 8 | - sql-databases 9 | -------------------------------------------------------------------------------- /v1/nitric-drizzle/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "private": true, 6 | "dependencies": { 7 | "@nitric/sdk": "^1.3.3", 8 | "drizzle-orm": "^0.31.2", 9 | "postgres": "^3.4.4" 10 | }, 11 | "devDependencies": { 12 | "dotenv": "^16.4.4", 13 | "drizzle-kit": "^0.22.7", 14 | "nodemon": "^3.1.4", 15 | "ts-node": "^10.9.2", 16 | "typescript": "^5.3.3" 17 | }, 18 | "scripts": { 19 | "dev:services": "nodemon -r dotenv/config" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /v1/nitric-drizzle/schema.ts: -------------------------------------------------------------------------------- 1 | import { integer, text, boolean, pgTable } from "drizzle-orm/pg-core"; 2 | 3 | export const todo = pgTable("todo", { 4 | id: integer("id").primaryKey(), 5 | text: text("text").notNull(), 6 | done: boolean("done").default(false).notNull(), 7 | }); 8 | -------------------------------------------------------------------------------- /v1/nitric-drizzle/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/nitric-express/.env.template: -------------------------------------------------------------------------------- 1 | NITRIC_HTTP_PROXY_PORT=3000 -------------------------------------------------------------------------------- /v1/nitric-express/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ -------------------------------------------------------------------------------- /v1/nitric-express/nitric.aws.yaml: -------------------------------------------------------------------------------- 1 | provider: nitric/aws@1.0.2 2 | region: us-east-1 3 | -------------------------------------------------------------------------------- /v1/nitric-express/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: nitric-express 2 | services: 3 | - match: services/*.ts 4 | start: npm run dev:services $SERVICE_PATH 5 | -------------------------------------------------------------------------------- /v1/nitric-express/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express-secure-url", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "main": "index.js", 6 | "private": true, 7 | "dependencies": { 8 | "@nitric/sdk": "^1.2.2", 9 | "express": "^4.18.2" 10 | }, 11 | "devDependencies": { 12 | "@types/express": "^4.17.21", 13 | "dotenv": "^16.4.4", 14 | "nodemon": "^3.1.4", 15 | "ts-node": "^10.9.2", 16 | "typescript": "^5.3.3" 17 | }, 18 | "scripts": { 19 | "dev:services": "nodemon -r dotenv/config" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /v1/nitric-express/services/url.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import { http, bucket } from "@nitric/sdk"; 3 | 4 | export const imgBucket = bucket("images").for("reading", "writing"); 5 | 6 | const app = express(); 7 | 8 | app.get("/upload/:id", async (req, res) => { 9 | try { 10 | const { id } = req.params; 11 | const img = imgBucket.file(`images/${id}/photo.png`); 12 | 13 | res.json({ 14 | url: await img.getUploadUrl(), 15 | }); 16 | } catch (err) { 17 | res.statusCode = 500; 18 | res.json({ 19 | message: "Error getting file URL", 20 | }); 21 | } 22 | }); 23 | 24 | http(app, () => { 25 | console.log(`Application started`); 26 | }); 27 | -------------------------------------------------------------------------------- /v1/nitric-express/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/nitric-fastify/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ -------------------------------------------------------------------------------- /v1/nitric-fastify/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: nitric-fastify 2 | services: 3 | - match: services/*.ts 4 | start: npm run dev:services $SERVICE_PATH 5 | -------------------------------------------------------------------------------- /v1/nitric-fastify/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "main": "index.js", 6 | "private": true, 7 | "dependencies": { 8 | "@nitric/sdk": "^1.2.2", 9 | "fastify": "^4.26.1" 10 | }, 11 | "devDependencies": { 12 | "dotenv": "^16.4.4", 13 | "nodemon": "^3.1.4", 14 | "ts-node": "^10.9.2", 15 | "typescript": "^5.3.3" 16 | }, 17 | "scripts": { 18 | "dev:services": "nodemon -r dotenv/config" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /v1/nitric-fastify/services/url.ts: -------------------------------------------------------------------------------- 1 | import Fastify from "fastify"; 2 | import { http, bucket } from "@nitric/sdk"; 3 | 4 | const fastify = Fastify({ 5 | logger: true, 6 | }); 7 | 8 | export const imgBucket = bucket("images").allow("read", "write"); 9 | 10 | interface Params { 11 | id: string; 12 | } 13 | 14 | fastify.get<{ Params: Params }>("/upload/:id", async (request, reply) => { 15 | try { 16 | const { id } = request.params; 17 | const img = imgBucket.file(`images/${id}/photo.png`); 18 | 19 | reply.code(200).send({ url: await img.getUploadUrl() }); 20 | } catch (err) { 21 | reply.code(500).send("Error getting file URL"); 22 | } 23 | }); 24 | 25 | async function bootstrap(port: number) { 26 | await fastify.listen({ port }); 27 | 28 | return fastify.server; 29 | } 30 | 31 | http(bootstrap, () => { 32 | console.log(`Application started`); 33 | }); 34 | -------------------------------------------------------------------------------- /v1/nitric-fastify/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/nitric-hono/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ -------------------------------------------------------------------------------- /v1/nitric-hono/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: nitric-hono 2 | services: 3 | - match: services/*.ts 4 | start: npm run dev:services $SERVICE_PATH 5 | -------------------------------------------------------------------------------- /v1/nitric-hono/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "main": "index.js", 6 | "private": true, 7 | "dependencies": { 8 | "@hono/node-server": "^1.8.1", 9 | "@nitric/sdk": "^1.2.2", 10 | "hono": "^4.0.7" 11 | }, 12 | "devDependencies": { 13 | "dotenv": "^16.4.4", 14 | "nodemon": "^3.1.4", 15 | "ts-node": "^10.9.2", 16 | "typescript": "^5.3.3" 17 | }, 18 | "scripts": { 19 | "dev:services": "nodemon -r dotenv/config" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /v1/nitric-hono/services/url.ts: -------------------------------------------------------------------------------- 1 | import { bucket, http } from "@nitric/sdk"; 2 | import { serve } from "@hono/node-server"; 3 | import { Hono } from "hono"; 4 | 5 | const app = new Hono(); 6 | 7 | async function bootstrap(port: number) { 8 | return serve({ 9 | fetch: app.fetch, 10 | port, 11 | }); 12 | } 13 | 14 | export const imgBucket = bucket("images").allow("read", "write"); 15 | 16 | app.get("/upload/:id", async (c) => { 17 | try { 18 | const { id } = c.req.param(); 19 | const img = imgBucket.file(`images/${id}/photo.png`); 20 | 21 | return c.json({ url: await img.getUploadUrl() }); 22 | } catch (err) { 23 | c.status(500); 24 | c.text("Error getting file URL"); 25 | } 26 | }); 27 | 28 | http(bootstrap, () => { 29 | console.log(`Application started`); 30 | }); 31 | -------------------------------------------------------------------------------- /v1/nitric-hono/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/nitric-koa/.env.template: -------------------------------------------------------------------------------- 1 | NITRIC_HTTP_PROXY_PORT=3000 -------------------------------------------------------------------------------- /v1/nitric-koa/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ -------------------------------------------------------------------------------- /v1/nitric-koa/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: nitric-koa 2 | services: 3 | - match: services/*.ts 4 | start: npm run dev:services $SERVICE_PATH 5 | -------------------------------------------------------------------------------- /v1/nitric-koa/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "main": "index.js", 6 | "private": true, 7 | "dependencies": { 8 | "@nitric/sdk": "^1.2.2", 9 | "koa": "^2.15.0", 10 | "koa-router": "^12.0.1" 11 | }, 12 | "devDependencies": { 13 | "@types/koa": "^2.15.0", 14 | "@types/koa-router": "^7.4.8", 15 | "dotenv": "^16.4.4", 16 | "nodemon": "^3.1.4", 17 | "ts-node": "^10.9.2", 18 | "typescript": "^5.3.3" 19 | }, 20 | "scripts": { 21 | "dev:services": "nodemon -r dotenv/config" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /v1/nitric-koa/services/url.ts: -------------------------------------------------------------------------------- 1 | import Koa from "koa"; 2 | import Router from "koa-router"; 3 | import { http, bucket } from "@nitric/sdk"; 4 | 5 | export const imgBucket = bucket("images").allow("read", "write"); 6 | 7 | const app = new Koa(); 8 | const router = new Router(); 9 | 10 | router.get("/upload/:id", async (ctx) => { 11 | try { 12 | const { id } = ctx.params; 13 | const img = imgBucket.file(`images/${id}/photo.png`); 14 | 15 | ctx.body = { 16 | url: await img.getUploadUrl(), 17 | }; 18 | } catch (err) { 19 | ctx.throw(500, "Error getting file URL"); 20 | } 21 | }); 22 | 23 | app.use(router.routes()); 24 | 25 | http(app, () => { 26 | console.log(`Application started`); 27 | }); 28 | -------------------------------------------------------------------------------- /v1/nitric-koa/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.* 7 | .yarn/* 8 | !.yarn/patches 9 | !.yarn/plugins 10 | !.yarn/releases 11 | !.yarn/versions 12 | 13 | /backend/node_modules 14 | /backend/.nitric 15 | 16 | # testing 17 | /coverage 18 | 19 | # next.js 20 | /.next/ 21 | /out/ 22 | 23 | # production 24 | /build 25 | 26 | # misc 27 | .DS_Store 28 | *.pem 29 | 30 | # debug 31 | npm-debug.log* 32 | yarn-debug.log* 33 | yarn-error.log* 34 | .pnpm-debug.log* 35 | 36 | # env files (can opt-in for committing if needed) 37 | .env* 38 | 39 | # vercel 40 | .vercel 41 | 42 | # typescript 43 | *.tsbuildinfo 44 | next-env.d.ts 45 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/.vercelignore: -------------------------------------------------------------------------------- 1 | backend/ -------------------------------------------------------------------------------- /v1/nitric-meme-generator/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitrictech/examples/865ca7e9ea7b95d171474e41b8b1b0b1f9bd99e2/v1/nitric-meme-generator/app/favicon.ico -------------------------------------------------------------------------------- /v1/nitric-meme-generator/app/loading.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const loading = () => { 4 | return loading; 5 | }; 6 | 7 | export default loading; 8 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/app/page.tsx: -------------------------------------------------------------------------------- 1 | import { ImageGround } from "@/components/ImageGround"; 2 | import { getRandomSuggestions } from "@/lib/suggestions"; 3 | 4 | export const dynamic = "force-dynamic"; 5 | 6 | export default function Home() { 7 | return ; 8 | } 9 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/backend/README.md: -------------------------------------------------------------------------------- 1 | # Guide 2 | 3 | brew install nitrictech/tap/nitric 4 | 5 | curl -L "https://nitric.io/install?version=latest" | bash 6 | 7 | nitric new serverless-meme ts-starter -------------------------------------------------------------------------------- /v1/nitric-meme-generator/backend/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: serverless-meme 2 | services: 3 | - basedir: "" 4 | match: services/*.ts 5 | runtime: node 6 | start: npm run dev:services $SERVICE_PATH 7 | batch-services: [] 8 | runtimes: 9 | node: 10 | dockerfile: ./node.dockerfile 11 | context: "" 12 | args: {} 13 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/backend/node.dockerfile.dockerignore: -------------------------------------------------------------------------------- 1 | .nitric/ 2 | .git/ 3 | .idea/ 4 | .vscode/ 5 | .github/ 6 | *.dockerfile 7 | *.dockerignore 8 | node_modules/ 9 | README.md -------------------------------------------------------------------------------- /v1/nitric-meme-generator/backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "private": true, 6 | "dependencies": { 7 | "@nitric/sdk": "^1.3.3", 8 | "dotenv": "^16.4.7", 9 | "openai": "^4.85.1", 10 | "util": "^0.12.5", 11 | "zlib": "^1.0.5" 12 | }, 13 | "devDependencies": { 14 | "@types/node": "^22.1.0", 15 | "nodemon": "^3.1.4", 16 | "ts-node": "^10.9.2", 17 | "typescript": "^5.5.4" 18 | }, 19 | "scripts": { 20 | "dev:services": "nodemon -r dotenv/config" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/backend/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.ts", 8 | "css": "app/globals.css", 9 | "baseColor": "slate", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | }, 20 | "iconLibrary": "lucide" 21 | } -------------------------------------------------------------------------------- /v1/nitric-meme-generator/components/Stopwatch.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | 3 | export function Stopwatch({ startTime }: { startTime: number }) { 4 | const [elapsed, setElapsed] = useState(0); 5 | 6 | useEffect(() => { 7 | const interval = setInterval(() => { 8 | setElapsed(Date.now() - startTime); 9 | }, 100); 10 | 11 | return () => clearInterval(interval); 12 | }, [startTime]); 13 | 14 | return ( 15 | 16 | {(elapsed / 1000).toFixed(1)}s 17 | 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/components/theme-provider.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import * as React from "react"; 4 | import { ThemeProvider as NextThemesProvider } from "next-themes"; 5 | 6 | export function ThemeProvider({ 7 | children, 8 | ...props 9 | }: React.ComponentProps) { 10 | return {children}; 11 | } 12 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/components/ui/collapsible.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as CollapsiblePrimitive from "@radix-ui/react-collapsible" 4 | 5 | const Collapsible = CollapsiblePrimitive.Root 6 | 7 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger 8 | 9 | const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent 10 | 11 | export { Collapsible, CollapsibleTrigger, CollapsibleContent } 12 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/components/ui/input.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | const Input = React.forwardRef>( 6 | ({ className, type, ...props }, ref) => { 7 | return ( 8 | 17 | ) 18 | } 19 | ) 20 | Input.displayName = "Input" 21 | 22 | export { Input } 23 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as LabelPrimitive from "@radix-ui/react-label" 5 | import { cva, type VariantProps } from "class-variance-authority" 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | const labelVariants = cva( 10 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 11 | ) 12 | 13 | const Label = React.forwardRef< 14 | React.ElementRef, 15 | React.ComponentPropsWithoutRef & 16 | VariantProps 17 | >(({ className, ...props }, ref) => ( 18 | 23 | )) 24 | Label.displayName = LabelPrimitive.Root.displayName 25 | 26 | export { Label } 27 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/components/ui/spinner.tsx: -------------------------------------------------------------------------------- 1 | import { Loader2 } from "lucide-react"; 2 | 3 | export function Spinner({ className }: { className?: string }) { 4 | return ; 5 | } 6 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | const Textarea = React.forwardRef< 6 | HTMLTextAreaElement, 7 | React.ComponentProps<"textarea"> 8 | >(({ className, ...props }, ref) => { 9 | return ( 10 | 18 | ) 19 | }) 20 | Textarea.displayName = "Textarea" 21 | 22 | export { Textarea } 23 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/components/ui/theme.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { useTheme } from "next-themes"; 4 | import { Button } from "@/components/ui/button"; 5 | import { Sun, Moon } from "lucide-react"; 6 | import { useEffect, useState } from "react"; 7 | 8 | export function ModeToggle() { 9 | const { theme, setTheme } = useTheme(); 10 | const isDark = theme === "dark"; 11 | const [mounted, setMounted] = useState(false); 12 | 13 | useEffect(() => { 14 | setMounted(true); 15 | }, []); 16 | 17 | if (!mounted) return null; 18 | 19 | return ( 20 | setTheme(isDark ? "light" : "dark")} 23 | > 24 | {isDark ? : } 25 | 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/components/ui/toaster.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { useToast } from "@/hooks/use-toast" 4 | import { 5 | Toast, 6 | ToastClose, 7 | ToastDescription, 8 | ToastProvider, 9 | ToastTitle, 10 | ToastViewport, 11 | } from "@/components/ui/toast" 12 | 13 | export function Toaster() { 14 | const { toasts } = useToast() 15 | 16 | return ( 17 | 18 | {toasts.map(function ({ id, title, description, action, ...props }) { 19 | return ( 20 | 21 | 22 | {title && {title}} 23 | {description && ( 24 | {description} 25 | )} 26 | 27 | {action} 28 | 29 | 30 | ) 31 | })} 32 | 33 | 34 | ) 35 | } 36 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { dirname } from "path"; 2 | import { fileURLToPath } from "url"; 3 | import { FlatCompat } from "@eslint/eslintrc"; 4 | 5 | const __filename = fileURLToPath(import.meta.url); 6 | const __dirname = dirname(__filename); 7 | 8 | const compat = new FlatCompat({ 9 | baseDirectory: __dirname, 10 | }); 11 | 12 | const eslintConfig = [ 13 | ...compat.extends("next/core-web-vitals", "next/typescript"), 14 | ]; 15 | 16 | export default eslintConfig; 17 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/lib/api-types.ts: -------------------------------------------------------------------------------- 1 | import { ProviderKey } from "./provider-config"; 2 | 3 | export interface GenerateImageRequest { 4 | prompt: string; 5 | provider: ProviderKey; 6 | modelId: string; 7 | } 8 | 9 | export interface GenerateImageResponse { 10 | image?: string; 11 | error?: string; 12 | } 13 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/lib/image-types.ts: -------------------------------------------------------------------------------- 1 | import { ProviderKey } from "./provider-config"; 2 | 3 | export interface GeneratedImage { 4 | provider: ProviderKey; 5 | image: string | null; 6 | modelId?: string; 7 | } 8 | 9 | export interface ImageResult { 10 | provider: ProviderKey; 11 | image: string | null; 12 | modelId?: string; 13 | } 14 | 15 | export interface ImageError { 16 | provider: ProviderKey; 17 | message: string; 18 | } 19 | 20 | export interface ProviderTiming { 21 | startTime?: number; 22 | completionTime?: number; 23 | elapsed?: number; 24 | } 25 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/lib/provider-config.ts: -------------------------------------------------------------------------------- 1 | export type ModelMode = "performance" | "quality"; 2 | 3 | export type ProviderKey = "openai"; 4 | 5 | export const PROVIDERS: Record< 6 | ProviderKey, 7 | { 8 | displayName: string; 9 | iconPath: string; 10 | color: string; 11 | models: string[]; 12 | } 13 | > = { 14 | openai: { 15 | displayName: "OpenAI", 16 | iconPath: "/provider-icons/openai.svg", 17 | color: "from-blue-500 to-cyan-500", 18 | models: ["dall-e-2", "dall-e-3"], 19 | }, 20 | }; 21 | 22 | export const MODEL_CONFIGS: Record> = { 23 | performance: { 24 | openai: "dall-e-2", 25 | }, 26 | quality: { 27 | openai: "dall-e-3", 28 | }, 29 | }; 30 | 31 | export const PROVIDER_ORDER: ProviderKey[] = ["openai"]; 32 | 33 | export const initializeProviderRecord = (defaultValue?: T) => 34 | Object.fromEntries( 35 | PROVIDER_ORDER.map((key) => [key, defaultValue]) 36 | ) as Record; 37 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { clsx, type ClassValue } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/next.config.ts: -------------------------------------------------------------------------------- 1 | import type { NextConfig } from "next"; 2 | 3 | const nextConfig: NextConfig = { 4 | images: { 5 | remotePatterns: [ 6 | { 7 | protocol: "https", 8 | hostname: "**", 9 | }, 10 | ], 11 | domains: [], 12 | }, 13 | }; 14 | 15 | export default nextConfig; 16 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/public/file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/public/window.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /v1/nitric-meme-generator/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2017", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "noEmit": true, 9 | "esModuleInterop": true, 10 | "module": "esnext", 11 | "moduleResolution": "bundler", 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "jsx": "preserve", 15 | "incremental": true, 16 | "plugins": [ 17 | { 18 | "name": "next" 19 | } 20 | ], 21 | "paths": { 22 | "@/*": ["./*"] 23 | } 24 | }, 25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 26 | "exclude": ["node_modules"] 27 | } 28 | -------------------------------------------------------------------------------- /v1/nitric-monorepo/with-berry/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | 7 | [*.{js,json,yml}] 8 | charset = utf-8 9 | indent_style = space 10 | indent_size = 2 11 | -------------------------------------------------------------------------------- /v1/nitric-monorepo/with-berry/.gitattributes: -------------------------------------------------------------------------------- 1 | /.yarn/** linguist-vendored 2 | /.yarn/releases/* binary 3 | /.yarn/plugins/**/* binary 4 | /.pnp.* binary linguist-generated 5 | -------------------------------------------------------------------------------- /v1/nitric-monorepo/with-berry/.gitignore: -------------------------------------------------------------------------------- 1 | .yarn/* 2 | !.yarn/patches 3 | !.yarn/plugins 4 | !.yarn/releases 5 | !.yarn/sdks 6 | !.yarn/versions 7 | 8 | # Swap the comments on the following lines if you wish to use zero-installs 9 | # In that case, don't forget to run `yarn config set enableGlobalCache false`! 10 | # Documentation here: https://yarnpkg.com/features/caching#zero-installs 11 | 12 | #!.yarn/cache 13 | .pnp.* 14 | node_modules 15 | 16 | **/dist 17 | -------------------------------------------------------------------------------- /v1/nitric-monorepo/with-berry/.yarnrc.yml: -------------------------------------------------------------------------------- 1 | yarnPath: ".yarn/releases/yarn-berry.cjs" 2 | nodeLinker: node-modules 3 | -------------------------------------------------------------------------------- /v1/nitric-monorepo/with-berry/apps/server/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ 3 | .npmrc 4 | git.store 5 | lib 6 | .env -------------------------------------------------------------------------------- /v1/nitric-monorepo/with-berry/apps/server/Dockerfile.dockerignore: -------------------------------------------------------------------------------- 1 | **/node_modules/ -------------------------------------------------------------------------------- /v1/nitric-monorepo/with-berry/apps/server/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: server 2 | services: 3 | - match: services/*.ts 4 | runtime: custom 5 | type: "" 6 | start: yarn dev:services $SERVICE_PATH 7 | runtimes: 8 | custom: 9 | # All services that specify the 'custom' runtime will be built using this dockerfile 10 | dockerfile: ./Dockerfile 11 | context: ../../ 12 | args: 13 | PACKAGE_SCOPE: "server" 14 | -------------------------------------------------------------------------------- /v1/nitric-monorepo/with-berry/apps/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev:services": "nodemon -r dotenv/config" 7 | }, 8 | "dependencies": { 9 | "@nitric/sdk": "^1.2.2", 10 | "@repo/cors": "workspace:*", 11 | "@repo/logger": "workspace:*" 12 | }, 13 | "devDependencies": { 14 | "@types/node": "^20.11.24", 15 | "dotenv": "^16.4.5", 16 | "nodemon": "^3.1.4", 17 | "ts-node": "^10.9.2", 18 | "typescript": "^5.5.3" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /v1/nitric-monorepo/with-berry/apps/server/services/hello.ts: -------------------------------------------------------------------------------- 1 | import { api } from "@nitric/sdk"; 2 | import { cors } from "@repo/cors"; 3 | import { log } from "@repo/logger"; 4 | 5 | // Define a new service called 'hello' 6 | const main = api("main", { 7 | middleware: [cors], 8 | }); 9 | 10 | main.get("/message/:name", async (ctx) => { 11 | const { name } = ctx.req.params; 12 | 13 | log(`Received request for ${name}`); 14 | 15 | return ctx.res.json({ message: `hello ${name}` }); 16 | }); 17 | 18 | main.get("/status", async (ctx) => { 19 | return ctx.res.json({ ok: true }); 20 | }); 21 | -------------------------------------------------------------------------------- /v1/nitric-monorepo/with-berry/apps/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/nitric-monorepo/with-berry/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "with-berry", 3 | "packageManager": "yarn@4.3.1", 4 | "workspaces": [ 5 | "apps/*", 6 | "packages/*" 7 | ], 8 | "devDependencies": { 9 | "ts-node": "^10.9.2" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /v1/nitric-monorepo/with-berry/packages/cors/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@repo/cors", 3 | "version": "0.0.0", 4 | "private": true, 5 | "main": "./src/index.ts", 6 | "dependencies": { 7 | "@nitric/sdk": "^1.2.2" 8 | }, 9 | "devDependencies": { 10 | "@repo/tsconfig": "workspace:*", 11 | "typescript": "^5.5.3" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /v1/nitric-monorepo/with-berry/packages/cors/src/index.ts: -------------------------------------------------------------------------------- 1 | import type { HttpMiddleware } from "@nitric/sdk"; 2 | 3 | export const optionsHandler: HttpMiddleware = (ctx) => { 4 | ctx.res.headers["Content-Type"] = ["text/html; charset=ascii"]; 5 | ctx.res.status = 200; 6 | ctx.res.body = "OK"; 7 | 8 | return ctx; 9 | }; 10 | 11 | export const cors: HttpMiddleware = (ctx, next) => { 12 | ctx.res.headers["Access-Control-Allow-Origin"] = ["*"]; 13 | ctx.res.headers["Access-Control-Allow-Headers"] = [ 14 | "Origin, Content-Type, Accept, Authorization", 15 | ]; 16 | ctx.res.headers["Access-Control-Allow-Methods"] = [ 17 | "GET, PUT, POST, OPTIONS, DELETE", 18 | ]; 19 | ctx.res.headers["Access-Control-Allow-Credentials"] = ["true"]; 20 | 21 | if (next) { 22 | return next(ctx); 23 | } 24 | 25 | return ctx; 26 | }; 27 | -------------------------------------------------------------------------------- /v1/nitric-monorepo/with-berry/packages/cors/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@repo/tsconfig/base.json", 3 | "compilerOptions": { 4 | "outDir": "./dist", 5 | "rootDir": "./src" 6 | }, 7 | "include": ["src"], 8 | "exclude": ["dist", "build", "node_modules"] 9 | } 10 | -------------------------------------------------------------------------------- /v1/nitric-monorepo/with-berry/packages/logger/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@repo/logger", 3 | "version": "0.0.0", 4 | "private": true, 5 | "main": "./src/index.ts", 6 | "devDependencies": { 7 | "@repo/tsconfig": "workspace:*", 8 | "typescript": "^5.5.3" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /v1/nitric-monorepo/with-berry/packages/logger/src/index.ts: -------------------------------------------------------------------------------- 1 | export const log = (message: string) => { 2 | console.log(`[LOG] ${message}`); 3 | }; 4 | -------------------------------------------------------------------------------- /v1/nitric-monorepo/with-berry/packages/logger/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@repo/tsconfig/base.json", 3 | "compilerOptions": { 4 | "outDir": "./dist", 5 | "rootDir": "./src" 6 | }, 7 | "include": ["src"], 8 | "exclude": ["dist", "build", "node_modules"] 9 | } 10 | -------------------------------------------------------------------------------- /v1/nitric-monorepo/with-berry/packages/tsconfig/base.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Default", 4 | "compilerOptions": { 5 | "composite": false, 6 | "declaration": true, 7 | "declarationMap": true, 8 | "esModuleInterop": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "inlineSources": false, 11 | "isolatedModules": true, 12 | "module": "NodeNext", 13 | "moduleResolution": "NodeNext", 14 | "noUnusedLocals": false, 15 | "noUnusedParameters": false, 16 | "preserveWatchOutput": true, 17 | "skipLibCheck": true, 18 | "strict": true 19 | }, 20 | "exclude": ["node_modules"] 21 | } 22 | -------------------------------------------------------------------------------- /v1/nitric-monorepo/with-berry/packages/tsconfig/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@repo/tsconfig", 3 | "version": "0.0.0", 4 | "private": true 5 | } 6 | -------------------------------------------------------------------------------- /v1/nitric-nest/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | parserOptions: { 4 | project: 'tsconfig.json', 5 | tsconfigRootDir: __dirname, 6 | sourceType: 'module', 7 | }, 8 | plugins: ['@typescript-eslint/eslint-plugin'], 9 | extends: [ 10 | 'plugin:@typescript-eslint/recommended', 11 | 'plugin:prettier/recommended', 12 | ], 13 | root: true, 14 | env: { 15 | node: true, 16 | jest: true, 17 | }, 18 | ignorePatterns: ['.eslintrc.js'], 19 | rules: { 20 | '@typescript-eslint/interface-name-prefix': 'off', 21 | '@typescript-eslint/explicit-function-return-type': 'off', 22 | '@typescript-eslint/explicit-module-boundary-types': 'off', 23 | '@typescript-eslint/no-explicit-any': 'off', 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /v1/nitric-nest/.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist 3 | /node_modules 4 | 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | pnpm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | lerna-debug.log* 13 | 14 | # OS 15 | .DS_Store 16 | 17 | # Tests 18 | /coverage 19 | /.nyc_output 20 | 21 | # IDEs and editors 22 | /.idea 23 | .project 24 | .classpath 25 | .c9/ 26 | *.launch 27 | .settings/ 28 | *.sublime-workspace 29 | 30 | # IDE - VSCode 31 | .vscode/* 32 | !.vscode/settings.json 33 | !.vscode/tasks.json 34 | !.vscode/launch.json 35 | !.vscode/extensions.json -------------------------------------------------------------------------------- /v1/nitric-nest/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all" 4 | } -------------------------------------------------------------------------------- /v1/nitric-nest/nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/nest-cli", 3 | "collection": "@nestjs/schematics", 4 | "sourceRoot": "src", 5 | "compilerOptions": { 6 | "deleteOutDir": true 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /v1/nitric-nest/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: nitric-nest 2 | services: 3 | - match: src/main.ts 4 | runtime: node 5 | start: npm run dev:services $SERVICE_PATH 6 | batch-services: [] 7 | runtimes: 8 | node: 9 | dockerfile: ./node.dockerfile 10 | -------------------------------------------------------------------------------- /v1/nitric-nest/node.dockerfile.dockerignore: -------------------------------------------------------------------------------- 1 | .nitric/ 2 | .git/ 3 | .idea/ 4 | .vscode/ 5 | .github/ 6 | *.dockerfile 7 | *.dockerignore 8 | node_modules/ 9 | README.md -------------------------------------------------------------------------------- /v1/nitric-nest/src/app.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get, Post, Delete, Param, Req } from '@nestjs/common'; 2 | import { Profile, AppService } from './app.service'; 3 | import { Request } from 'express'; 4 | 5 | @Controller() 6 | export class AppController { 7 | constructor(private readonly appService: AppService) {} 8 | 9 | @Get('/profile/:id') 10 | async getProfile(@Param('id') id: string) { 11 | return await this.appService.getProfile(id); 12 | } 13 | 14 | @Post('/profile') 15 | async createProfile(@Req() req: Request>) { 16 | return await this.appService.createProfile(req.body); 17 | } 18 | 19 | @Delete('/profile/:id') 20 | async deleteProfile(@Param('id') id: string) { 21 | return await this.appService.deleteProfile(id); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /v1/nitric-nest/src/app.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { AppController } from './app.controller'; 3 | import { AppService } from './app.service'; 4 | 5 | @Module({ 6 | imports: [], 7 | controllers: [AppController], 8 | providers: [AppService], 9 | }) 10 | export class AppModule {} 11 | -------------------------------------------------------------------------------- /v1/nitric-nest/src/app.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, NotFoundException } from '@nestjs/common'; 2 | import { kv } from '@nitric/sdk'; 3 | import { v4 as uuidv4 } from 'uuid'; 4 | 5 | export interface Profile { 6 | id: string; 7 | name: string; 8 | age: number; 9 | } 10 | 11 | const profiles = kv('profiles').allow('get', 'set', 'delete'); 12 | 13 | @Injectable() 14 | export class AppService { 15 | async createProfile(createProfileReq: Omit): Promise { 16 | const id: string = uuidv4(); 17 | 18 | const profile = { id, ...createProfileReq } as Profile; 19 | 20 | await profiles.set(id, profile); 21 | 22 | return profile; 23 | } 24 | 25 | async getProfile(id: string): Promise { 26 | const profile = await profiles.get(id); 27 | 28 | if (!profile) { 29 | throw new NotFoundException(); 30 | } 31 | 32 | return profile; 33 | } 34 | 35 | async deleteProfile(id: string): Promise { 36 | await profiles.delete(id); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /v1/nitric-nest/src/main.ts: -------------------------------------------------------------------------------- 1 | import { http } from '@nitric/sdk'; 2 | import { NestFactory } from '@nestjs/core'; 3 | import { AppModule } from './app.module'; 4 | 5 | async function bootstrap(port: number) { 6 | const app = await NestFactory.create(AppModule); 7 | return await app.listen(port); 8 | } 9 | 10 | http(bootstrap); 11 | -------------------------------------------------------------------------------- /v1/nitric-nest/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /v1/nitric-nest/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "declaration": true, 5 | "removeComments": true, 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "allowSyntheticDefaultImports": true, 9 | "target": "ES2021", 10 | "sourceMap": true, 11 | "outDir": "./dist", 12 | "baseUrl": "./", 13 | "incremental": true, 14 | "skipLibCheck": true, 15 | "strictNullChecks": false, 16 | "noImplicitAny": false, 17 | "strictBindCallApply": false, 18 | "forceConsistentCasingInFileNames": false, 19 | "noFallthroughCasesInSwitch": false 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /v1/nitric-oak/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | .nitric/ 4 | .npmrc 5 | git.store -------------------------------------------------------------------------------- /v1/nitric-oak/deno.dockerfile: -------------------------------------------------------------------------------- 1 | FROM denoland/deno:2.0.2 AS build 2 | 3 | ARG HANDLER 4 | 5 | WORKDIR /app 6 | 7 | # Set Deno install location to a directory we can cache 8 | ENV DENO_INSTALL_ROOT="/app/.deno" 9 | ENV PATH="$DENO_INSTALL_ROOT/bin:$PATH" 10 | 11 | RUN --mount=type=cache,target=/app/.deno \ 12 | --mount=type=bind,source=deno.lock,target=deno.lock \ 13 | --mount=type=bind,source=deno.json,target=deno.json \ 14 | deno install --allow-scripts 15 | 16 | COPY . . 17 | 18 | # Consider reducing permissions 19 | RUN deno compile -o /bin/main --allow-all ${HANDLER} 20 | 21 | FROM debian:bookworm-slim 22 | 23 | COPY --from=build /bin/main /bin/main 24 | 25 | RUN chmod +xr-w /bin/main 26 | 27 | RUN apt update && \ 28 | apt install -y tzdata ca-certificates && \ 29 | rm -rf /var/lib/apt/lists/* 30 | 31 | ENTRYPOINT ["/bin/main"] -------------------------------------------------------------------------------- /v1/nitric-oak/deno.dockerfile.dockerignore: -------------------------------------------------------------------------------- 1 | .nitric/ 2 | node_modules/ 3 | nitric-spec.json 4 | nitric.yaml 5 | README.md -------------------------------------------------------------------------------- /v1/nitric-oak/deno.json: -------------------------------------------------------------------------------- 1 | { 2 | "imports": { 3 | "@nitric/sdk": "npm:@nitric/sdk@^1.3.3", 4 | "@oak/oak": "jsr:@oak/oak@^17.1.4" 5 | }, 6 | "nodeModulesDir": "auto" 7 | } 8 | -------------------------------------------------------------------------------- /v1/nitric-oak/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: nitric-oak 2 | services: 3 | - basedir: "" 4 | match: services/*.ts 5 | runtime: deno 6 | start: deno run --watch --allow-all $SERVICE_PATH 7 | batch-services: [] 8 | runtimes: 9 | deno: 10 | dockerfile: ./deno.dockerfile 11 | context: "" 12 | args: {} 13 | -------------------------------------------------------------------------------- /v1/nitric-oak/services/api.ts: -------------------------------------------------------------------------------- 1 | import { http, bucket } from "npm:@nitric/sdk"; 2 | import { Application, Router } from "jsr:@oak/oak"; 3 | 4 | export const imgBucket = bucket("images").allow("read", "write"); 5 | 6 | const app = new Application(); 7 | const router = new Router(); 8 | 9 | app.use(router.routes()); 10 | app.use(router.allowedMethods()); 11 | 12 | router.get("/upload/:id", async (ctx) => { 13 | try { 14 | const img = imgBucket.file(`images/${ctx.params.id}/photo.png`); 15 | 16 | ctx.response.type = "application/json"; 17 | ctx.response.body = { url: await img.getUploadUrl() }; 18 | } catch (_err) { 19 | ctx.response.status = 500; 20 | ctx.response.body = "Error getting file URL"; 21 | } 22 | }); 23 | 24 | async function bootstrap(port: number) { 25 | await app.listen({ port }); 26 | 27 | return { 28 | on: app.addEventListener, 29 | }; 30 | } 31 | 32 | http(bootstrap); 33 | -------------------------------------------------------------------------------- /v1/nitric-pgsql/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ 3 | .npmrc 4 | git.store -------------------------------------------------------------------------------- /v1/nitric-pgsql/migrations/todos/1_create_table.up.sql: -------------------------------------------------------------------------------- 1 | -- migrations/1_create_table.up.sql 2 | CREATE TABLE IF NOT EXISTS todos ( 3 | id SERIAL PRIMARY KEY, 4 | content TEXT NOT NULL, 5 | done BOOLEAN DEFAULT FALSE 6 | ); -------------------------------------------------------------------------------- /v1/nitric-pgsql/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: nitric-pgsql 2 | services: 3 | - basedir: "" 4 | match: services/*.ts 5 | runtime: node 6 | start: npm run dev:services $SERVICE_PATH 7 | batch-services: [] 8 | websites: [] 9 | runtimes: 10 | node: 11 | dockerfile: ./node.dockerfile 12 | context: "" 13 | args: {} 14 | preview: 15 | - sql-databases 16 | -------------------------------------------------------------------------------- /v1/nitric-pgsql/node.dockerfile.dockerignore: -------------------------------------------------------------------------------- 1 | .nitric/ 2 | .git/ 3 | .idea/ 4 | .vscode/ 5 | .github/ 6 | *.dockerfile 7 | *.dockerignore 8 | node_modules/ 9 | README.md -------------------------------------------------------------------------------- /v1/nitric-pgsql/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "private": true, 6 | "dependencies": { 7 | "@nitric/sdk": "^1.3.3", 8 | "pg": "^8.14.1" 9 | }, 10 | "devDependencies": { 11 | "@types/node": "^22.1.0", 12 | "dotenv": "^16.4.5", 13 | "nodemon": "^3.1.4", 14 | "ts-node": "^10.9.2", 15 | "typescript": "^5.5.4" 16 | }, 17 | "scripts": { 18 | "dev:services": "nodemon -r dotenv/config" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /v1/nitric-pgsql/resources/db.ts: -------------------------------------------------------------------------------- 1 | import { sql } from "@nitric/sdk"; 2 | import { Client } from "pg"; 3 | 4 | const db = sql("todo-db", { 5 | migrations: "file://migrations/todos", 6 | }); 7 | 8 | let client: Client; 9 | 10 | const getClient = async () => { 11 | if (!client) { 12 | const connectionString = await db.connectionString(); 13 | client = new Client({ connectionString }); 14 | await client.connect(); 15 | } 16 | return client; 17 | }; 18 | 19 | export default getClient; 20 | -------------------------------------------------------------------------------- /v1/nitric-pgsql/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/nitric-prisma/.env.template: -------------------------------------------------------------------------------- 1 | DB_URL="postgresql://postgres:localsecret@localhost:5432/todos" -------------------------------------------------------------------------------- /v1/nitric-prisma/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ 3 | .npmrc 4 | git.store -------------------------------------------------------------------------------- /v1/nitric-prisma/db.ts: -------------------------------------------------------------------------------- 1 | import { sql } from "@nitric/sdk"; 2 | import { PrismaClient } from "@prisma/client"; 3 | 4 | const db = sql("todos", { 5 | // points to our custom prisma migration dockerfile 6 | migrations: "dockerfile://migrate.dockerfile", 7 | }); 8 | 9 | let prisma: PrismaClient; 10 | 11 | const getClient = async () => { 12 | // ensure we only create the client once 13 | if (!prisma) { 14 | const connectionString = await db.connectionString(); 15 | 16 | prisma = new PrismaClient({ 17 | datasources: { 18 | db: { 19 | url: connectionString, 20 | }, 21 | }, 22 | }); 23 | } 24 | return prisma; 25 | }; 26 | 27 | // export our getClient function, which will be used to get the prisma client during runtime 28 | export default getClient; 29 | -------------------------------------------------------------------------------- /v1/nitric-prisma/migrate.dockerfile: -------------------------------------------------------------------------------- 1 | # Use an official Node.js runtime as the base image 2 | FROM node 3 | 4 | ENV DB_URL="" 5 | ENV NITRIC_DB_NAME="" 6 | 7 | # Copy package.json and package-lock.json into the Docker image 8 | COPY package*.json ./ 9 | 10 | # Install the application's dependencies inside the Docker image 11 | RUN npm ci 12 | 13 | # Copy the rest of the application into the Docker image 14 | COPY . . 15 | 16 | # Generate Prisma client 17 | RUN npx prisma generate 18 | 19 | # Run the migrations and start the application when the Docker container starts 20 | ENTRYPOINT ["sh", "-c", "npx prisma migrate deploy"] -------------------------------------------------------------------------------- /v1/nitric-prisma/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: nitric-prisma-blah 2 | services: 3 | - match: services/*.ts 4 | runtime: "" 5 | type: "" 6 | start: npm run dev:services $SERVICE_PATH 7 | preview: 8 | - sql-databases 9 | -------------------------------------------------------------------------------- /v1/nitric-prisma/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "private": true, 6 | "dependencies": { 7 | "@nitric/sdk": "^1.3.3", 8 | "@prisma/client": "^5.15.0", 9 | "prisma": "^5.15.0" 10 | }, 11 | "devDependencies": { 12 | "dotenv": "^16.4.4", 13 | "nodemon": "^3.1.4", 14 | "ts-node": "^10.9.2", 15 | "typescript": "^5.3.3" 16 | }, 17 | "scripts": { 18 | "dev:services": "nodemon -r dotenv/config" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /v1/nitric-prisma/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | datasource db { 2 | provider = "postgresql" 3 | url = env("DB_URL") 4 | } 5 | 6 | generator client { 7 | provider = "prisma-client-js" 8 | } 9 | 10 | model Todo { 11 | id Int @id @default(autoincrement()) 12 | text String 13 | done Boolean @default(false) 14 | } -------------------------------------------------------------------------------- /v1/nitric-prisma/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/nitric-vite-react/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ 3 | .npmrc 4 | git.store -------------------------------------------------------------------------------- /v1/nitric-vite-react/main-website/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /v1/nitric-vite-react/main-website/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import reactHooks from 'eslint-plugin-react-hooks' 4 | import reactRefresh from 'eslint-plugin-react-refresh' 5 | import tseslint from 'typescript-eslint' 6 | 7 | export default tseslint.config( 8 | { ignores: ['dist'] }, 9 | { 10 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 11 | files: ['**/*.{ts,tsx}'], 12 | languageOptions: { 13 | ecmaVersion: 2020, 14 | globals: globals.browser, 15 | }, 16 | plugins: { 17 | 'react-hooks': reactHooks, 18 | 'react-refresh': reactRefresh, 19 | }, 20 | rules: { 21 | ...reactHooks.configs.recommended.rules, 22 | 'react-refresh/only-export-components': [ 23 | 'warn', 24 | { allowConstantExport: true }, 25 | ], 26 | }, 27 | }, 28 | ) 29 | -------------------------------------------------------------------------------- /v1/nitric-vite-react/main-website/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /v1/nitric-vite-react/main-website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "main-website", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc -b && vite build", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "react": "^19.0.0", 14 | "react-dom": "^19.0.0" 15 | }, 16 | "devDependencies": { 17 | "@eslint/js": "^9.21.0", 18 | "@types/react": "^19.0.10", 19 | "@types/react-dom": "^19.0.4", 20 | "@vitejs/plugin-react": "^4.3.4", 21 | "eslint": "^9.21.0", 22 | "eslint-plugin-react-hooks": "^5.1.0", 23 | "eslint-plugin-react-refresh": "^0.4.19", 24 | "globals": "^15.15.0", 25 | "typescript": "~5.7.2", 26 | "typescript-eslint": "^8.24.1", 27 | "vite": "^6.2.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /v1/nitric-vite-react/main-website/src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | -------------------------------------------------------------------------------- /v1/nitric-vite-react/main-website/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react' 2 | import { createRoot } from 'react-dom/client' 3 | import './index.css' 4 | import App from './App.tsx' 5 | 6 | createRoot(document.getElementById('root')!).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /v1/nitric-vite-react/main-website/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /v1/nitric-vite-react/main-website/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 4 | "target": "ES2020", 5 | "useDefineForClassFields": true, 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "module": "ESNext", 8 | "skipLibCheck": true, 9 | 10 | /* Bundler mode */ 11 | "moduleResolution": "bundler", 12 | "allowImportingTsExtensions": true, 13 | "isolatedModules": true, 14 | "moduleDetection": "force", 15 | "noEmit": true, 16 | "jsx": "react-jsx", 17 | 18 | /* Linting */ 19 | "strict": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "noFallthroughCasesInSwitch": true, 23 | "noUncheckedSideEffectImports": true 24 | }, 25 | "include": ["src"] 26 | } 27 | -------------------------------------------------------------------------------- /v1/nitric-vite-react/main-website/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.app.json" }, 5 | { "path": "./tsconfig.node.json" } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /v1/nitric-vite-react/main-website/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 4 | "target": "ES2022", 5 | "lib": ["ES2023"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "noUncheckedSideEffectImports": true 22 | }, 23 | "include": ["vite.config.ts"] 24 | } 25 | -------------------------------------------------------------------------------- /v1/nitric-vite-react/main-website/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vite.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /v1/nitric-vite-react/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: nitric-vite-react 2 | services: 3 | - basedir: "" 4 | match: services/*.ts 5 | runtime: node 6 | start: npm run dev:services $SERVICE_PATH 7 | batch-services: [] 8 | websites: 9 | - basedir: ./main-website 10 | # Since this is a Single Page Application (SPA), we need to redirect all requests to the index.html file. 11 | error: index.html 12 | build: 13 | command: npm run build 14 | output: dist 15 | dev: 16 | command: npm run dev -- --port 3000 17 | url: http://localhost:3000 18 | runtimes: 19 | node: 20 | dockerfile: ./node.dockerfile 21 | context: "" 22 | args: {} 23 | preview: 24 | - websites 25 | -------------------------------------------------------------------------------- /v1/nitric-vite-react/node.dockerfile.dockerignore: -------------------------------------------------------------------------------- 1 | .nitric/ 2 | .git/ 3 | .idea/ 4 | .vscode/ 5 | .github/ 6 | *.dockerfile 7 | *.dockerignore 8 | node_modules/ 9 | README.md 10 | 11 | main-website/ -------------------------------------------------------------------------------- /v1/nitric-vite-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "private": true, 6 | "dependencies": { 7 | "@nitric/sdk": "^1.3.3" 8 | }, 9 | "devDependencies": { 10 | "@types/node": "^22.1.0", 11 | "dotenv": "^16.4.5", 12 | "nodemon": "^3.1.4", 13 | "ts-node": "^10.9.2", 14 | "typescript": "^5.5.4" 15 | }, 16 | "scripts": { 17 | "dev:services": "nodemon -r dotenv/config" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /v1/nitric-vite-react/services/api.ts: -------------------------------------------------------------------------------- 1 | import { api } from "@nitric/sdk"; 2 | 3 | const mainApi = api("main"); 4 | 5 | mainApi.get("/hello/:name", async (ctx) => { 6 | const { name } = ctx.req.params; 7 | 8 | ctx.res.body = `Hello ${name}`; 9 | 10 | return ctx; 11 | }); 12 | -------------------------------------------------------------------------------- /v1/nitric-vite-react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/openai-embeddings/typescript/.env.template: -------------------------------------------------------------------------------- 1 | OPENAI_SECRET_KEY= 2 | NEXT_PUBLIC_SUPABASE_URL= 3 | SUPABASE_SECRET_KEY= 4 | -------------------------------------------------------------------------------- /v1/openai-embeddings/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ 3 | .env -------------------------------------------------------------------------------- /v1/openai-embeddings/typescript/common/resources.ts: -------------------------------------------------------------------------------- 1 | import { api } from "@nitric/sdk"; 2 | import { createClient } from "@supabase/supabase-js"; 3 | import { Configuration, OpenAIApi } from "openai"; 4 | import { Database } from "../db_types"; 5 | 6 | export const docsApi = api("openai"); 7 | 8 | // OpenAI configuration creation 9 | const configuration = new Configuration({ 10 | apiKey: process.env.OPENAI_SECRET_KEY, 11 | }); 12 | 13 | export const supabase = createClient( 14 | process.env.NEXT_PUBLIC_SUPABASE_URL, 15 | process.env.SUPABASE_SECRET_KEY 16 | ); 17 | 18 | export const openai = new OpenAIApi(configuration); 19 | -------------------------------------------------------------------------------- /v1/openai-embeddings/typescript/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: openAPI 2 | services: 3 | - match: services/*.ts 4 | start: npm run dev:services $SERVICE_PATH 5 | -------------------------------------------------------------------------------- /v1/openai-embeddings/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "main": "index.js", 6 | "private": true, 7 | "dependencies": { 8 | "@nitric/sdk": "^1.2.2", 9 | "@supabase/supabase-js": "^2.20.0", 10 | "common-tags": "^1.8.2", 11 | "github-slugger": "^2.0.0", 12 | "gpt3-tokenizer": "^1.1.5", 13 | "mdast-util-from-markdown": "^1.3.0", 14 | "openai": "^3.2.1" 15 | }, 16 | "devDependencies": { 17 | "@types/common-tags": "^1.8.4", 18 | "@types/node": "^18.16.0", 19 | "dotenv": "^16.4.4", 20 | "nodemon": "^3.1.4", 21 | "ts-node": "^10.9.2", 22 | "typescript": "^5.3.3" 23 | }, 24 | "scripts": { 25 | "dev:services": "nodemon -r dotenv/config" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /v1/openai-embeddings/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/podcast-transcription/.env: -------------------------------------------------------------------------------- 1 | PYTHONPATH=. -------------------------------------------------------------------------------- /v1/podcast-transcription/.gitignore: -------------------------------------------------------------------------------- 1 | .nitric/ 2 | .venv/ 3 | .model/ 4 | nitric-spec.json -------------------------------------------------------------------------------- /v1/podcast-transcription/.python-version: -------------------------------------------------------------------------------- 1 | 3.11 -------------------------------------------------------------------------------- /v1/podcast-transcription/common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitrictech/examples/865ca7e9ea7b95d171474e41b8b1b0b1f9bd99e2/v1/podcast-transcription/common/__init__.py -------------------------------------------------------------------------------- /v1/podcast-transcription/common/resources.py: -------------------------------------------------------------------------------- 1 | from nitric.resources import job, bucket, api 2 | 3 | main_api = api("main") 4 | 5 | transcribe_job = job("transcribe") 6 | 7 | podcast_bucket = bucket("podcasts") 8 | transcript_bucket = bucket("transcripts") -------------------------------------------------------------------------------- /v1/podcast-transcription/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: translate 2 | services: 3 | - match: src/services/api.py 4 | runtime: python 5 | start: uv run watchmedo auto-restart -p *.py --no-restart-on-command-exit -R python -- -u $SERVICE_PATH 6 | 7 | batch-services: 8 | - match: batches/transcribe.py 9 | runtime: transcribe 10 | start: uv run watchmedo auto-restart -p *.py --no-restart-on-command-exit -R python -- -u $SERVICE_PATH 11 | runtimes: 12 | python: 13 | dockerfile: python.dockerfile 14 | transcribe: 15 | dockerfile: transcribe.dockerfile 16 | 17 | preview: 18 | - batch-services 19 | -------------------------------------------------------------------------------- /v1/podcast-transcription/pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "nitric-python-whisper-example" 3 | version = "0.1.0" 4 | description = "An example project using Nitric and Whisper to transcribe audio" 5 | readme = "README.md" 6 | requires-python = ">=3.11" 7 | dependencies = [ 8 | "nitric ==1.2.3", 9 | "betterproto ==2.0.0b6", 10 | "requests>=2.32.3", 11 | ] 12 | 13 | [project.optional-dependencies] 14 | ml = [ 15 | "librosa>=0.10.2.post1", 16 | "numpy>=2.0.2", 17 | "openai-whisper>=20240930", 18 | ] 19 | 20 | [tool.uv] 21 | dev-dependencies = [ 22 | "watchdog>=5.0.3", 23 | ] 24 | -------------------------------------------------------------------------------- /v1/podcast-transcription/python.dockerfile.dockerignore: -------------------------------------------------------------------------------- 1 | .mypy_cache/ 2 | .nitric/ 3 | .venv/ 4 | .model/ 5 | nitric-spec.json 6 | nitric.yaml 7 | README.md -------------------------------------------------------------------------------- /v1/podcast-transcription/transcribe.dockerignore: -------------------------------------------------------------------------------- 1 | .mypy_cache/ 2 | .nitric/ 3 | .venv/ 4 | nitric.yaml 5 | README.md -------------------------------------------------------------------------------- /v1/product-inventory/typescript/.env.template: -------------------------------------------------------------------------------- 1 | AWS_SES_REGION="us-east-1" 2 | AWS_SES_ACCESS_KEY_ID="XXXXXXXXX" 3 | AWS_SES_SECRET_ACCESS_KEY="XXXXXXXXXX" 4 | 5 | SENDER_EMAIL="abc@abc.com" 6 | SYS_ADMIN_EMAIL="abc@abc.com" 7 | 8 | BUCKETNAME="images-" -------------------------------------------------------------------------------- /v1/product-inventory/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ 3 | .env -------------------------------------------------------------------------------- /v1/product-inventory/typescript/nitric.aws.yaml: -------------------------------------------------------------------------------- 1 | provider: nitric/aws@1.0.4 2 | region: us-east-1 3 | -------------------------------------------------------------------------------- /v1/product-inventory/typescript/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: inventory 2 | services: 3 | - match: ./services/*.ts 4 | start: npm run dev:services $SERVICE_PATH 5 | -------------------------------------------------------------------------------- /v1/product-inventory/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "private": true, 6 | "dependencies": { 7 | "@aws-sdk/client-rekognition": "^3.523.0", 8 | "@aws-sdk/client-ses": "^3.121.0", 9 | "@nitric/sdk": "^1.2.2", 10 | "mustache": "^4.2.0", 11 | "uuidv4": "^6.2.13" 12 | }, 13 | "devDependencies": { 14 | "dotenv": "^16.4.4", 15 | "nodemon": "^3.1.4", 16 | "ts-node": "^10.9.2", 17 | "typescript": "^5.3.3" 18 | }, 19 | "scripts": { 20 | "dev:services": "nodemon -r dotenv/config" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /v1/product-inventory/typescript/services/notify.ts: -------------------------------------------------------------------------------- 1 | import { sendEmail, createEmailRequest } from "../common/email"; 2 | import { inventorySub } from "../common/resources"; 3 | import * as Mustache from "mustache"; 4 | 5 | inventorySub.subscribe(async (ctx) => { 6 | // Send the email notification 7 | sendEmail( 8 | createEmailRequest({ 9 | sender: process.env.SENDER_EMAIL, 10 | recipient: [ctx.req.json().recipient], 11 | body: "", 12 | html: Mustache.render(ctx.req.json().template, ctx.req.json().data), 13 | subject: Mustache.render(ctx.req.json().subject, ctx.req.json().data), 14 | }) 15 | ); 16 | 17 | return ctx; 18 | }); 19 | -------------------------------------------------------------------------------- /v1/product-inventory/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/profile-api-graphql/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ -------------------------------------------------------------------------------- /v1/profile-api-graphql/typescript/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: typescript 2 | services: 3 | - match: services/*.ts 4 | start: npm run dev:services $SERVICE_PATH 5 | -------------------------------------------------------------------------------- /v1/profile-api-graphql/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "main": "index.js", 6 | "private": true, 7 | "dependencies": { 8 | "@nitric/sdk": "^1.2.2", 9 | "graphql": "^16.6.0", 10 | "uuidv4": "^6.2.13" 11 | }, 12 | "devDependencies": { 13 | "dotenv": "^16.4.4", 14 | "nodemon": "^3.1.4", 15 | "ts-node": "^10.9.2", 16 | "typescript": "^5.3.3" 17 | }, 18 | "scripts": { 19 | "dev:services": "nodemon -r dotenv/config" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /v1/profile-api-graphql/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/python-debugpy/.env: -------------------------------------------------------------------------------- 1 | PYTHONPATH=. -------------------------------------------------------------------------------- /v1/python-debugpy/.gitignore: -------------------------------------------------------------------------------- 1 | .nitric/ 2 | .venv/ 3 | nitric-spec.json -------------------------------------------------------------------------------- /v1/python-debugpy/.python-version: -------------------------------------------------------------------------------- 1 | 3.11 -------------------------------------------------------------------------------- /v1/python-debugpy/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: python-debugpy 2 | services: 3 | - basedir: "" 4 | match: services/*.py 5 | runtime: python 6 | start: uv run -- watchmedo auto-restart -p "*.py" --no-restart-on-command-exit -R -- python -Xfrozen_modules=off $SERVICE_PATH 7 | batch-services: [] 8 | websites: [] 9 | runtimes: 10 | python: 11 | dockerfile: ./python.dockerfile 12 | context: "" 13 | args: {} 14 | -------------------------------------------------------------------------------- /v1/python-debugpy/pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "python-uv-starter" 3 | version = "0.1.0" 4 | description = "Add your description here" 5 | readme = "README.md" 6 | requires-python = ">=3.11" 7 | dependencies = [ 8 | "nitric ==1.2.3", 9 | "betterproto ==2.0.0b6", 10 | "debugpy>=1.8.13", 11 | ] 12 | 13 | [tool.uv] 14 | dev-dependencies = [ 15 | "watchdog>=5.0.3", 16 | ] 17 | -------------------------------------------------------------------------------- /v1/python-debugpy/python.dockerfile: -------------------------------------------------------------------------------- 1 | # The python version must match the version in .python-version 2 | FROM ghcr.io/astral-sh/uv:python3.11-bookworm-slim AS builder 3 | 4 | ARG HANDLER 5 | ENV HANDLER=${HANDLER} 6 | 7 | ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy PYTHONPATH=. 8 | WORKDIR /app 9 | COPY uv.lock pyproject.toml /app/ 10 | RUN --mount=type=cache,target=/root/.cache/uv \ 11 | uv sync --frozen --no-install-project --no-dev --no-python-downloads 12 | COPY . /app 13 | RUN --mount=type=cache,target=/root/.cache/uv \ 14 | uv sync --frozen --no-dev --no-python-downloads 15 | 16 | 17 | # Then, use a final image without uv 18 | FROM python:3.11-slim-bookworm 19 | 20 | ARG HANDLER 21 | ENV HANDLER=${HANDLER} PYTHONPATH=. 22 | 23 | # Copy the application from the builder 24 | COPY --from=builder /app /app 25 | WORKDIR /app 26 | 27 | # Place executables in the environment at the front of the path 28 | ENV PATH="/app/.venv/bin:$PATH" 29 | 30 | # Run the service using the path to the handler 31 | ENTRYPOINT python -u $HANDLER -------------------------------------------------------------------------------- /v1/python-debugpy/python.dockerfile.dockerignore: -------------------------------------------------------------------------------- 1 | .mypy_cache/ 2 | .nitric/ 3 | .venv/ 4 | nitric-spec.json 5 | nitric.yaml 6 | README.md -------------------------------------------------------------------------------- /v1/python-debugpy/services/one.py: -------------------------------------------------------------------------------- 1 | from nitric.resources import api 2 | from nitric.application import Nitric 3 | from nitric.context import HttpContext 4 | 5 | import debugpy 6 | 7 | host, port = debugpy.listen(("0.0.0.0", 52509)) # Static port for consistent debugging 8 | print(f"✅ Debugpy is listening on {host}:{port}", flush=True) 9 | 10 | api_one = api("one") 11 | 12 | @api_one.get("/one/:name") 13 | async def hello_world(ctx: HttpContext): 14 | name = ctx.req.params['name'] 15 | 16 | ctx.res.body = f"Hello from {name}" 17 | 18 | Nitric.run() 19 | -------------------------------------------------------------------------------- /v1/python-debugpy/services/two.py: -------------------------------------------------------------------------------- 1 | from nitric.resources import api 2 | from nitric.application import Nitric 3 | from nitric.context import HttpContext 4 | 5 | import debugpy 6 | 7 | host, port = debugpy.listen(("0.0.0.0", 52510)) # Static port for consistent debugging 8 | print(f"✅ Debugpy is listening on {host}:{port}", flush=True) 9 | 10 | api_two = api("two") 11 | 12 | @api_two.get("/two/:name") 13 | async def hello_world(ctx: HttpContext): 14 | name = ctx.req.params['name'] 15 | 16 | ctx.res.body = f"Hello {name}" 17 | 18 | Nitric.run() 19 | -------------------------------------------------------------------------------- /v1/python-prediction/.env: -------------------------------------------------------------------------------- 1 | PYTHONPATH=. -------------------------------------------------------------------------------- /v1/python-prediction/.gitignore: -------------------------------------------------------------------------------- 1 | .nitric/ 2 | .venv 3 | .idea/ 4 | __pycache__ 5 | tokenier.pickle 6 | model.keras -------------------------------------------------------------------------------- /v1/python-prediction/.python-version: -------------------------------------------------------------------------------- 1 | 3.11 -------------------------------------------------------------------------------- /v1/python-prediction/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: python-starter 2 | services: 3 | - match: services/*.py 4 | start: uv run watchmedo auto-restart -p *.py --no-restart-on-command-exit -R uv run $SERVICE_PATH 5 | runtime: python 6 | runtimes: 7 | python: 8 | dockerfile: "./python.dockerfile" 9 | -------------------------------------------------------------------------------- /v1/python-prediction/pyproject.toml: -------------------------------------------------------------------------------- 1 | 2 | [project] 3 | name = "python-prediction" 4 | version = "0.1.0" 5 | description = "Make text predictions with Nitric and Tensorflow" 6 | readme = "README.md" 7 | requires-python = ">=3.11" 8 | dependencies = [ 9 | "nitric ==1.2.3", 10 | "betterproto ==2.0.0b6", 11 | "numpy>=1.26.4", 12 | "num2words>=0.5.14", 13 | "keras>=2.15.0", 14 | "scikit-learn>=1.6.0", 15 | "pandas>=2.2.3", 16 | "tensorflow==2.15.1", 17 | ] 18 | 19 | [tool.uv] 20 | dev-dependencies = [ 21 | "watchdog>=5.0.3", 22 | ] 23 | -------------------------------------------------------------------------------- /v1/python-prediction/python.dockerfile.dockerignore: -------------------------------------------------------------------------------- 1 | .mypy_cache/ 2 | .nitric/ 3 | .venv/ 4 | nitric-spec.json 5 | nitric.yaml 6 | README.md -------------------------------------------------------------------------------- /v1/python-starter-pipenv/.gitignore: -------------------------------------------------------------------------------- 1 | .nitric/ -------------------------------------------------------------------------------- /v1/python-starter-pipenv/Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | url = "https://pypi.org/simple" 3 | verify_ssl = true 4 | name = "python starter" 5 | 6 | [requires] 7 | python_version = "3.12" 8 | 9 | [packages] 10 | nitric = "==1.2.3" 11 | 12 | [scripts] 13 | dev = "watchmedo auto-restart -p '*.py' -R python -- -u" 14 | 15 | [dev-packages] 16 | watchdog = "*" 17 | -------------------------------------------------------------------------------- /v1/python-starter-pipenv/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: python-starter 2 | services: 3 | - match: services/*.py 4 | start: pipenv run dev $SERVICE_PATH 5 | runtime: python 6 | runtimes: 7 | python: 8 | dockerfile: "./python.dockerfile" 9 | -------------------------------------------------------------------------------- /v1/python-starter-pipenv/python.dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.11-slim 2 | 3 | # Setup the var pointing to the current nitric service being built 4 | ARG HANDLER 5 | ENV HANDLER=${HANDLER} 6 | 7 | ENV PYTHONUNBUFFERED=TRUE 8 | ENV PYTHONPATH="." 9 | 10 | RUN apt-get update -y && \ 11 | apt-get install -y ca-certificates git && \ 12 | update-ca-certificates 13 | 14 | RUN pip install --no-cache-dir --upgrade pip pipenv 15 | 16 | COPY . . 17 | 18 | # Guarantee lock file if we have a Pipfile and no Pipfile.lock 19 | RUN (stat Pipfile && pipenv lock) || echo "No Pipfile found" 20 | 21 | # Output a requirements.txt file for final module install if there is a Pipfile.lock found 22 | RUN (stat Pipfile.lock && pipenv requirements > requirements.txt) || echo "No Pipfile.lock found" 23 | 24 | RUN pip install --no-cache-dir -r requirements.txt 25 | 26 | ENTRYPOINT python -u $HANDLER 27 | -------------------------------------------------------------------------------- /v1/python-starter-pipenv/python.dockerfile.dockerignore: -------------------------------------------------------------------------------- 1 | .mypy_cache/ 2 | .nitric/ 3 | .venv/ 4 | nitric-spec.json 5 | nitric.yaml 6 | README.md -------------------------------------------------------------------------------- /v1/python-starter-pipenv/services/hello.py: -------------------------------------------------------------------------------- 1 | from nitric.resources import api 2 | from nitric.application import Nitric 3 | from nitric.context import HttpContext 4 | 5 | main = api("main") 6 | 7 | @main.get("/hello/:name") 8 | async def hello_world(ctx: HttpContext): 9 | name = ctx.req.params['name'] 10 | 11 | ctx.res.body = f"Hello {name}" 12 | 13 | Nitric.run() 14 | -------------------------------------------------------------------------------- /v1/python-starter/.env: -------------------------------------------------------------------------------- 1 | PYTHONPATH=. -------------------------------------------------------------------------------- /v1/python-starter/.gitignore: -------------------------------------------------------------------------------- 1 | .nitric/ 2 | .venv/ 3 | nitric-spec.json -------------------------------------------------------------------------------- /v1/python-starter/.python-version: -------------------------------------------------------------------------------- 1 | 3.11 -------------------------------------------------------------------------------- /v1/python-starter/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: python-starter 2 | services: 3 | - match: services/*.py 4 | start: uv run watchmedo auto-restart -p *.py --no-restart-on-command-exit -R uv run $SERVICE_PATH 5 | runtime: python 6 | runtimes: 7 | python: 8 | dockerfile: "./python.dockerfile" 9 | -------------------------------------------------------------------------------- /v1/python-starter/pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "python-uv-starter" 3 | version = "0.1.0" 4 | description = "Add your description here" 5 | readme = "README.md" 6 | requires-python = ">=3.11" 7 | dependencies = ["nitric ==1.2.3", "betterproto ==2.0.0b6"] 8 | 9 | [tool.uv] 10 | dev-dependencies = [ 11 | "watchdog>=5.0.3", 12 | ] 13 | -------------------------------------------------------------------------------- /v1/python-starter/python.dockerfile.dockerignore: -------------------------------------------------------------------------------- 1 | .mypy_cache/ 2 | .nitric/ 3 | .venv/ 4 | nitric-spec.json 5 | nitric.yaml 6 | README.md -------------------------------------------------------------------------------- /v1/python-starter/services/api.py: -------------------------------------------------------------------------------- 1 | from nitric.resources import api 2 | from nitric.application import Nitric 3 | from nitric.context import HttpContext 4 | 5 | main = api("main") 6 | 7 | @main.get("/hello/:name") 8 | async def hello_world(ctx: HttpContext): 9 | name = ctx.req.params['name'] 10 | 11 | ctx.res.body = f"Hello {name}" 12 | 13 | Nitric.run() 14 | -------------------------------------------------------------------------------- /v1/scheduled-report/python/.env: -------------------------------------------------------------------------------- 1 | PYTHONPATH=. 2 | GOOGLE_APPLICATION_CREDENTIALS="./key.json" 3 | ADMIN_EMAIL="admin@domain.io" -------------------------------------------------------------------------------- /v1/scheduled-report/python/.gitignore: -------------------------------------------------------------------------------- 1 | .nitric/ 2 | .venv/ 3 | __pycache__ 4 | nitric-spec.json -------------------------------------------------------------------------------- /v1/scheduled-report/python/.python-version: -------------------------------------------------------------------------------- 1 | 3.11 -------------------------------------------------------------------------------- /v1/scheduled-report/python/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: python-starter 2 | services: 3 | - match: services/*.py 4 | start: uv run watchmedo auto-restart -p *.py --no-restart-on-command-exit -R uv run $SERVICE_PATH 5 | runtime: python 6 | runtimes: 7 | python: 8 | dockerfile: "./python.dockerfile" 9 | -------------------------------------------------------------------------------- /v1/scheduled-report/python/pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "scheduled-report" 3 | version = "0.1.0" 4 | description = "Schedule reports using Nitric and the Google Sheets client library" 5 | readme = "README.md" 6 | requires-python = ">=3.11" 7 | dependencies = [ 8 | "nitric ==1.2.3", 9 | "betterproto ==2.0.0b6", 10 | "google-auth>=2.37.0", 11 | "google-api-python-client>=2.156.0", 12 | ] 13 | 14 | [tool.uv] 15 | dev-dependencies = [ 16 | "watchdog>=5.0.3", 17 | ] 18 | -------------------------------------------------------------------------------- /v1/scheduled-report/python/python.dockerfile.dockerignore: -------------------------------------------------------------------------------- 1 | .mypy_cache/ 2 | .nitric/ 3 | .venv/ 4 | nitric-spec.json 5 | nitric.yaml 6 | README.md -------------------------------------------------------------------------------- /v1/scheduled-report/python/services/hello.py: -------------------------------------------------------------------------------- 1 | import os 2 | from nitric.resources import schedule 3 | from nitric.application import Nitric 4 | from nitric.context import IntervalContext 5 | 6 | from helpers.google import create_spreadsheet, generate_dummy_data, insert_data_into_spreadsheet, service_login, share_spreadsheet 7 | 8 | report_schedule = schedule('run-a-report') 9 | 10 | @report_schedule.every('1 days') 11 | async def process_transactions(ctx: IntervalContext): 12 | sheets_service, drive_service = service_login() 13 | 14 | spreadsheet_id = create_spreadsheet("Daily Report", sheets_service) 15 | 16 | dummy_data = generate_dummy_data(rows=20) 17 | insert_data_into_spreadsheet(spreadsheet_id, dummy_data, sheets_service) 18 | 19 | share_spreadsheet(spreadsheet_id, os.getenv('ADMIN_EMAIL'), drive_service) 20 | 21 | 22 | Nitric.run() -------------------------------------------------------------------------------- /v1/scheduled-report/python/services/helpers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitrictech/examples/865ca7e9ea7b95d171474e41b8b1b0b1f9bd99e2/v1/scheduled-report/python/services/helpers/__init__.py -------------------------------------------------------------------------------- /v1/scheduled-tasks/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ -------------------------------------------------------------------------------- /v1/scheduled-tasks/typescript/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: scheduled-tasks 2 | services: 3 | - match: services/*.ts 4 | start: npm run dev:services $SERVICE_PATH 5 | -------------------------------------------------------------------------------- /v1/scheduled-tasks/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "main": "index.js", 6 | "private": true, 7 | "dependencies": { 8 | "@nitric/sdk": "^1.2.2" 9 | }, 10 | "devDependencies": { 11 | "dotenv": "^16.4.4", 12 | "nodemon": "^3.1.4", 13 | "ts-node": "^10.9.2", 14 | "typescript": "^5.3.3" 15 | }, 16 | "scripts": { 17 | "dev:services": "nodemon -r dotenv/config" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /v1/scheduled-tasks/typescript/services/tidy.ts: -------------------------------------------------------------------------------- 1 | import { schedule, bucket } from "@nitric/sdk"; 2 | 3 | const assets = bucket("assets").allow("delete"); 4 | 5 | // A schedule that cleans up files in a bucket every 3 days 6 | schedule("tidy").every("3 days", async (ctx) => { 7 | const files = await assets.files(); 8 | await Promise.all(files.map(async (file) => await file.delete())); 9 | }); 10 | -------------------------------------------------------------------------------- /v1/scheduled-tasks/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/stripe-payments/typescript/.env.template: -------------------------------------------------------------------------------- 1 | STRIPE_SECRET_KEY= 2 | -------------------------------------------------------------------------------- /v1/stripe-payments/typescript/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: stripe-payments 2 | services: 3 | - match: services/*.ts 4 | start: npm run dev:services $SERVICE_PATH 5 | -------------------------------------------------------------------------------- /v1/stripe-payments/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "main": "index.js", 6 | "private": true, 7 | "dependencies": { 8 | "@nitric/sdk": "^1.2.2", 9 | "stripe": "^12.4.0" 10 | }, 11 | "devDependencies": { 12 | "dotenv": "^16.4.4", 13 | "nodemon": "^3.1.4", 14 | "ts-node": "^10.9.2", 15 | "typescript": "^5.3.3" 16 | }, 17 | "scripts": { 18 | "dev:services": "nodemon -r dotenv/config" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /v1/stripe-payments/typescript/services/payment.ts: -------------------------------------------------------------------------------- 1 | import { api } from "@nitric/sdk"; 2 | import Stripe from "stripe"; 3 | 4 | const YOUR_DOMAIN = "http://example.com"; 5 | 6 | const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { 7 | apiVersion: null, 8 | }); 9 | 10 | // API 11 | const mainApi = api("main"); 12 | 13 | // Create Checkout Session 14 | mainApi.get("/payment", async (ctx) => { 15 | const session = await stripe.checkout.sessions.create({ 16 | line_items: [ 17 | { 18 | price_data: { 19 | currency: "usd", 20 | product_data: { 21 | name: "T-shirt", 22 | }, 23 | unit_amount: 2000, 24 | }, 25 | quantity: 1, 26 | }, 27 | ], 28 | 29 | mode: "payment", 30 | success_url: `${YOUR_DOMAIN}/success.html`, 31 | cancel_url: `${YOUR_DOMAIN}/cancel.html`, 32 | }); 33 | 34 | ctx.res.status = 303; 35 | ctx.res.headers["Location"] = [session.url]; 36 | 37 | return ctx; 38 | }); 39 | -------------------------------------------------------------------------------- /v1/stripe-payments/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/surveys-auth0/src/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ 3 | .env 4 | -------------------------------------------------------------------------------- /v1/surveys-auth0/src/apis/receipts.ts: -------------------------------------------------------------------------------- 1 | import { api } from "@nitric/sdk"; 2 | import { addCors } from "../resources/middleware"; 3 | import { receiptFiles } from "../resources/buckets"; 4 | 5 | const receiptApi = api("receipts", { 6 | middleware: [addCors], 7 | }); 8 | 9 | receiptApi.get("/receipts/:submissionId", async (ctx) => { 10 | const { submissionId } = ctx.req.params; 11 | ctx.res.headers["Location"] = [ 12 | await receiptFiles.file(`${submissionId}.pdf`).getDownloadUrl(), 13 | ]; 14 | ctx.res.status = 303; 15 | }); 16 | -------------------------------------------------------------------------------- /v1/surveys-auth0/src/forms/form/index.ts: -------------------------------------------------------------------------------- 1 | export * from './schema'; -------------------------------------------------------------------------------- /v1/surveys-auth0/src/forms/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./form"; 2 | export * from "./submissions"; 3 | -------------------------------------------------------------------------------- /v1/surveys-auth0/src/forms/submissions.ts: -------------------------------------------------------------------------------- 1 | export interface Submission { 2 | submissionId: string; 3 | status: "saved" | "submitted"; 4 | data: T; 5 | } 6 | -------------------------------------------------------------------------------- /v1/surveys-auth0/src/handlers/deliver.ts: -------------------------------------------------------------------------------- 1 | import { submissionTopic } from "../resources"; 2 | 3 | submissionTopic.subscribe(({ req }) => { 4 | console.log(`Delivering submission ${req.json().submissionId}`); 5 | }); 6 | -------------------------------------------------------------------------------- /v1/surveys-auth0/src/handlers/pdfs.ts: -------------------------------------------------------------------------------- 1 | import { buildReceipt } from "../forms/form/receipt"; 2 | import { submissionTopic } from "../resources"; 3 | import { receiptFiles } from "../resources/buckets"; 4 | 5 | submissionTopic.subscribe(async (ctx) => { 6 | const submission = ctx.req.json(); 7 | 8 | const path = `${submission.submissionId}.pdf`; 9 | 10 | const pdfContent = await buildReceipt(submission.data); 11 | await receiptFiles.file(path).write(pdfContent); 12 | 13 | console.log(`PDF receipt written to ${path}`); 14 | }); 15 | -------------------------------------------------------------------------------- /v1/surveys-auth0/src/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: survey 2 | services: 3 | - match: ./apis/*.ts 4 | start: npm run dev:services $SERVICE_PATH 5 | - match: ./handlers/*.ts 6 | start: npm run dev:services $SERVICE_PATH 7 | -------------------------------------------------------------------------------- /v1/surveys-auth0/src/resources/buckets.ts: -------------------------------------------------------------------------------- 1 | import { bucket } from "@nitric/sdk"; 2 | 3 | export const receiptFiles = bucket("receipts").for( 4 | "writing", 5 | "reading", 6 | "deleting" 7 | ); 8 | -------------------------------------------------------------------------------- /v1/surveys-auth0/src/resources/index.ts: -------------------------------------------------------------------------------- 1 | export * from './topics'; 2 | export * from './store'; -------------------------------------------------------------------------------- /v1/surveys-auth0/src/resources/topics.ts: -------------------------------------------------------------------------------- 1 | import { topic } from "@nitric/sdk"; 2 | import { Submission, FormData } from "../forms"; 3 | 4 | export const submissionTopic = 5 | topic>("transaction-events"); 6 | -------------------------------------------------------------------------------- /v1/surveys-auth0/src/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node", 6 | "strict": true 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui-noauth/.env.local.template: -------------------------------------------------------------------------------- 1 | NEXT_PUBLIC_API_BASE_URL=http://localhost:4001 2 | NEXT_PUBLIC_API_RECEIPT_URL=http://localhost:4002 3 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui-noauth/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui-noauth/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui-noauth/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "@/*": ["src/*"] 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui-noauth/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui-noauth/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | experimental: { 5 | scrollRestoration: true, 6 | appDir: false, 7 | }, 8 | } 9 | 10 | module.exports = nextConfig 11 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui-noauth/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | 'postcss-focus-visible': { 5 | replaceWith: '[data-focus-visible-added]', 6 | }, 7 | autoprefixer: {}, 8 | }, 9 | } 10 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui-noauth/prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | singleQuote: true, 3 | semi: false, 4 | plugins: [require('prettier-plugin-tailwindcss')], 5 | } 6 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui-noauth/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitrictech/examples/865ca7e9ea7b95d171474e41b8b1b0b1f9bd99e2/v1/surveys-auth0/ui-noauth/public/favicon.ico -------------------------------------------------------------------------------- /v1/surveys-auth0/ui-noauth/public/fonts/Inter-italic.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitrictech/examples/865ca7e9ea7b95d171474e41b8b1b0b1f9bd99e2/v1/surveys-auth0/ui-noauth/public/fonts/Inter-italic.var.woff2 -------------------------------------------------------------------------------- /v1/surveys-auth0/ui-noauth/public/fonts/Inter-roman.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitrictech/examples/865ca7e9ea7b95d171474e41b8b1b0b1f9bd99e2/v1/surveys-auth0/ui-noauth/public/fonts/Inter-roman.var.woff2 -------------------------------------------------------------------------------- /v1/surveys-auth0/ui-noauth/public/images/office.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitrictech/examples/865ca7e9ea7b95d171474e41b8b1b0b1f9bd99e2/v1/surveys-auth0/ui-noauth/public/images/office.png -------------------------------------------------------------------------------- /v1/surveys-auth0/ui-noauth/src/components/Container.tsx: -------------------------------------------------------------------------------- 1 | import clsx from 'clsx' 2 | import { HTMLAttributes } from 'react' 3 | 4 | interface ContainerProps extends HTMLAttributes { 5 | className?: string 6 | } 7 | 8 | const Container: React.FC = ({ className, ...props }) => { 9 | return ( 10 | 14 | ) 15 | } 16 | 17 | export default Container 18 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui-noauth/src/components/Footer.tsx: -------------------------------------------------------------------------------- 1 | import Container from './Container' 2 | 3 | export default function Footer() { 4 | return ( 5 | 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui-noauth/src/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import '../styles/tailwind.css' 2 | 3 | import type { AppProps } from 'next/app' 4 | 5 | export default function App({ Component, pageProps }: AppProps) { 6 | return 7 | } 8 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui-noauth/src/pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import { Head, Html, Main, NextScript } from 'next/document' 2 | 3 | export default function Document() { 4 | return ( 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui-noauth/src/pages/survey.tsx: -------------------------------------------------------------------------------- 1 | import Form from '../components/Form' 2 | import Header from '../components/Header' 3 | import Footer from '../components/Footer' 4 | import Head from 'next/head' 5 | 6 | function SurveyForm() { 7 | return ( 8 | <> 9 | 10 | Survey Form. 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | > 23 | ) 24 | } 25 | export default SurveyForm 26 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui-noauth/src/services/apiClient.tsx: -------------------------------------------------------------------------------- 1 | export const callApi = async (serverUrl, options) => { 2 | try { 3 | const response = await fetch(serverUrl, { 4 | ...options, 5 | }) 6 | return response 7 | } catch (error) { 8 | return error.message 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui-noauth/src/styles/tailwind.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Inter'; 3 | font-weight: 100 900; 4 | font-display: block; 5 | font-style: normal; 6 | font-named-instance: 'Regular'; 7 | src: url('/fonts/Inter-roman.var.woff2') format('woff2'); 8 | } 9 | @font-face { 10 | font-family: 'Inter'; 11 | font-weight: 100 900; 12 | font-display: block; 13 | font-style: italic; 14 | font-named-instance: 'Italic'; 15 | src: url('/fonts/Inter-italic.var.woff2') format('woff2'); 16 | } 17 | 18 | @tailwind base; 19 | @tailwind components; 20 | @tailwind utilities; 21 | 22 | #__next { 23 | min-height: 100%; 24 | } 25 | 26 | p.error { 27 | color: #bf1650; 28 | } 29 | 30 | p.error::before { 31 | display: inline; 32 | content: "⚠ "; 33 | } -------------------------------------------------------------------------------- /v1/surveys-auth0/ui-noauth/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": [ 4 | "dom", 5 | "dom.iterable", 6 | "esnext" 7 | ], 8 | "allowJs": true, 9 | "skipLibCheck": true, 10 | "strict": false, 11 | "forceConsistentCasingInFileNames": true, 12 | "noEmit": true, 13 | "incremental": true, 14 | "esModuleInterop": true, 15 | "module": "esnext", 16 | "moduleResolution": "node", 17 | "resolveJsonModule": true, 18 | "isolatedModules": true, 19 | "jsx": "preserve" 20 | }, 21 | "include": [ 22 | "next-env.d.ts", 23 | "**/*.ts", 24 | "**/*.tsx" 25 | , "src/pages/_app.jsx", "src/components/Form.jsx" ], 26 | "exclude": [ 27 | "node_modules" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui/.env.local.template: -------------------------------------------------------------------------------- 1 | AUTH0_SECRET= 2 | AUTH0_BASE_URL= 3 | AUTH0_ISSUER_BASE_URL= 4 | AUTH0_CLIENT_ID= 5 | AUTH0_CLIENT_SECRET= 6 | 7 | NEXT_PUBLIC_API_BASE_URL=http://localhost:4001 8 | NEXT_PUBLIC_API_RECEIPT_URLhttp://localhost:4002 -------------------------------------------------------------------------------- /v1/surveys-auth0/ui/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "@/*": ["src/*"] 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | experimental: { 5 | scrollRestoration: true, 6 | appDir: false, 7 | }, 8 | } 9 | 10 | module.exports = nextConfig 11 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | 'postcss-focus-visible': { 5 | replaceWith: '[data-focus-visible-added]', 6 | }, 7 | autoprefixer: {}, 8 | }, 9 | } 10 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui/prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | singleQuote: true, 3 | semi: false, 4 | plugins: [require('prettier-plugin-tailwindcss')], 5 | } 6 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitrictech/examples/865ca7e9ea7b95d171474e41b8b1b0b1f9bd99e2/v1/surveys-auth0/ui/public/favicon.ico -------------------------------------------------------------------------------- /v1/surveys-auth0/ui/public/fonts/Inter-italic.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitrictech/examples/865ca7e9ea7b95d171474e41b8b1b0b1f9bd99e2/v1/surveys-auth0/ui/public/fonts/Inter-italic.var.woff2 -------------------------------------------------------------------------------- /v1/surveys-auth0/ui/public/fonts/Inter-roman.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitrictech/examples/865ca7e9ea7b95d171474e41b8b1b0b1f9bd99e2/v1/surveys-auth0/ui/public/fonts/Inter-roman.var.woff2 -------------------------------------------------------------------------------- /v1/surveys-auth0/ui/public/images/office.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitrictech/examples/865ca7e9ea7b95d171474e41b8b1b0b1f9bd99e2/v1/surveys-auth0/ui/public/images/office.png -------------------------------------------------------------------------------- /v1/surveys-auth0/ui/src/components/Container.tsx: -------------------------------------------------------------------------------- 1 | import clsx from 'clsx' 2 | import { HTMLAttributes } from 'react' 3 | 4 | interface ContainerProps extends HTMLAttributes { 5 | className?: string 6 | } 7 | 8 | const Container: React.FC = ({ className, ...props }) => { 9 | return ( 10 | 14 | ) 15 | } 16 | 17 | export default Container 18 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui/src/components/Footer.tsx: -------------------------------------------------------------------------------- 1 | import Container from './Container' 2 | 3 | export default function Footer() { 4 | return ( 5 | 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui/src/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import '../styles/tailwind.css' 2 | 3 | import type { AppProps } from 'next/app' 4 | import { UserProvider } from '@auth0/nextjs-auth0/client' 5 | 6 | export default function App({ Component, pageProps }: AppProps) { 7 | return ( 8 | 9 | 10 | 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui/src/pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import { Head, Html, Main, NextScript } from 'next/document' 2 | 3 | export default function Document() { 4 | return ( 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui/src/pages/api/auth/[...auth0].tsx: -------------------------------------------------------------------------------- 1 | import { handleAuth } from '@auth0/nextjs-auth0' 2 | export default handleAuth() 3 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui/src/pages/survey.tsx: -------------------------------------------------------------------------------- 1 | import Form from '../components/Form' 2 | import Header from '../components/Header' 3 | import Footer from '../components/Footer' 4 | import { withPageAuthRequired } from '@auth0/nextjs-auth0/client' 5 | import Head from 'next/head' 6 | 7 | function SurveyForm() { 8 | return ( 9 | <> 10 | 11 | Survey Form. 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | > 24 | ) 25 | } 26 | export default withPageAuthRequired(SurveyForm) 27 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui/src/services/apiClient.tsx: -------------------------------------------------------------------------------- 1 | export const callApi = async (serverUrl, options) => { 2 | try { 3 | const response = await fetch(serverUrl, { 4 | ...options, 5 | }) 6 | return response 7 | } catch (error) { 8 | return error.message 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /v1/surveys-auth0/ui/src/styles/tailwind.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Inter'; 3 | font-weight: 100 900; 4 | font-display: block; 5 | font-style: normal; 6 | font-named-instance: 'Regular'; 7 | src: url('/fonts/Inter-roman.var.woff2') format('woff2'); 8 | } 9 | @font-face { 10 | font-family: 'Inter'; 11 | font-weight: 100 900; 12 | font-display: block; 13 | font-style: italic; 14 | font-named-instance: 'Italic'; 15 | src: url('/fonts/Inter-italic.var.woff2') format('woff2'); 16 | } 17 | 18 | @tailwind base; 19 | @tailwind components; 20 | @tailwind utilities; 21 | 22 | #__next { 23 | min-height: 100%; 24 | } 25 | 26 | p.error { 27 | color: #bf1650; 28 | } 29 | 30 | p.error::before { 31 | display: inline; 32 | content: "⚠ "; 33 | } -------------------------------------------------------------------------------- /v1/surveys-auth0/ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": [ 4 | "dom", 5 | "dom.iterable", 6 | "esnext" 7 | ], 8 | "allowJs": true, 9 | "skipLibCheck": true, 10 | "strict": false, 11 | "forceConsistentCasingInFileNames": true, 12 | "noEmit": true, 13 | "incremental": true, 14 | "esModuleInterop": true, 15 | "module": "esnext", 16 | "moduleResolution": "node", 17 | "resolveJsonModule": true, 18 | "isolatedModules": true, 19 | "jsx": "preserve" 20 | }, 21 | "include": [ 22 | "next-env.d.ts", 23 | "**/*.ts", 24 | "**/*.tsx" 25 | , "src/pages/_app.jsx", "src/components/Form.jsx" ], 26 | "exclude": [ 27 | "node_modules" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /v1/typescript-starter-deno/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | .nitric/ 4 | .npmrc 5 | git.store -------------------------------------------------------------------------------- /v1/typescript-starter-deno/deno.dockerfile: -------------------------------------------------------------------------------- 1 | FROM denoland/deno:2.0.2 AS build 2 | 3 | ARG HANDLER 4 | 5 | WORKDIR /app 6 | 7 | # Set Deno install location to a directory we can cache 8 | ENV DENO_INSTALL_ROOT="/app/.deno" 9 | ENV PATH="$DENO_INSTALL_ROOT/bin:$PATH" 10 | 11 | RUN --mount=type=cache,target=/app/.deno \ 12 | --mount=type=bind,source=deno.lock,target=deno.lock \ 13 | --mount=type=bind,source=deno.json,target=deno.json \ 14 | deno install --allow-scripts 15 | 16 | COPY . . 17 | 18 | # Consider reducing permissions 19 | RUN deno compile -o /bin/main --allow-all ${HANDLER} 20 | 21 | FROM debian:bookworm-slim 22 | 23 | COPY --from=build /bin/main /bin/main 24 | 25 | RUN chmod +xr-w /bin/main 26 | 27 | RUN apt update && \ 28 | apt install -y tzdata ca-certificates && \ 29 | rm -rf /var/lib/apt/lists/* 30 | 31 | ENTRYPOINT ["/bin/main"] -------------------------------------------------------------------------------- /v1/typescript-starter-deno/deno.dockerfile.dockerignore: -------------------------------------------------------------------------------- 1 | .nitric/ 2 | node_modules/ 3 | nitric-spec.json 4 | nitric.yaml 5 | README.md -------------------------------------------------------------------------------- /v1/typescript-starter-deno/deno.json: -------------------------------------------------------------------------------- 1 | { 2 | "imports": { 3 | "@nitric/sdk": "npm:@nitric/sdk@^1.3.3" 4 | }, 5 | "nodeModulesDir": "auto" 6 | } 7 | -------------------------------------------------------------------------------- /v1/typescript-starter-deno/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: typescript-starter 2 | services: 3 | - match: services/*.ts 4 | start: deno run --watch --allow-all $SERVICE_PATH 5 | runtime: deno 6 | runtimes: 7 | deno: 8 | dockerfile: "./deno.dockerfile" 9 | -------------------------------------------------------------------------------- /v1/typescript-starter-deno/services/api.ts: -------------------------------------------------------------------------------- 1 | import { api } from "npm:@nitric/sdk"; 2 | 3 | const helloApi = api("main"); 4 | 5 | helloApi.get("/hello/:name", async (ctx) => { 6 | const { name } = ctx.req.params; 7 | 8 | ctx.res.body = `Hello ${name}`; 9 | 10 | return ctx; 11 | }); 12 | -------------------------------------------------------------------------------- /v1/typescript-starter/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ 3 | .npmrc 4 | git.store -------------------------------------------------------------------------------- /v1/typescript-starter/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: typescript-starter 2 | services: 3 | - match: services/*.ts 4 | start: npm run dev:services $SERVICE_PATH 5 | runtime: node 6 | 7 | runtimes: 8 | node: 9 | dockerfile: ./node.dockerfile 10 | args: {} -------------------------------------------------------------------------------- /v1/typescript-starter/node.dockerfile.dockerignore: -------------------------------------------------------------------------------- 1 | .nitric/ 2 | .git/ 3 | .idea/ 4 | .vscode/ 5 | .github/ 6 | *.dockerfile 7 | *.dockerignore 8 | node_modules/ 9 | README.md -------------------------------------------------------------------------------- /v1/typescript-starter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "private": true, 6 | "dependencies": { 7 | "@nitric/sdk": "^1.3.3" 8 | }, 9 | "devDependencies": { 10 | "@types/node": "^22.1.0", 11 | "dotenv": "^16.4.5", 12 | "nodemon": "^3.1.4", 13 | "ts-node": "^10.9.2", 14 | "typescript": "^5.5.4" 15 | }, 16 | "scripts": { 17 | "dev:services": "nodemon -r dotenv/config" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /v1/typescript-starter/services/api.ts: -------------------------------------------------------------------------------- 1 | import { api } from "@nitric/sdk"; 2 | 3 | const mainApi = api("main"); 4 | 5 | mainApi.get("/hello/:name", async (ctx) => { 6 | const { name } = ctx.req.params; 7 | 8 | ctx.res.body = `Hello ${name}`; 9 | 10 | return ctx; 11 | }); 12 | -------------------------------------------------------------------------------- /v1/typescript-starter/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/upload-secure-url/typescript/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "targets": { 7 | "node": "current" 8 | } 9 | } 10 | ] 11 | ] 12 | } -------------------------------------------------------------------------------- /v1/upload-secure-url/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ -------------------------------------------------------------------------------- /v1/upload-secure-url/typescript/common/handlers.ts: -------------------------------------------------------------------------------- 1 | import { imgBucket } from "./resources"; 2 | 3 | export const getUrl = async (ctx) => { 4 | try { 5 | const { id } = ctx.req.params; 6 | 7 | const img = imgBucket.file(`images/${id}/photo.png`); 8 | const url = ctx.req.path.endsWith("upload") 9 | ? await img.getUploadUrl() 10 | : await img.getDownloadUrl(); 11 | 12 | ctx.res.json({ 13 | url: url, 14 | }); 15 | } catch (err) { 16 | ctx.res.status = 500; 17 | ctx.res.message = "Error getting file URL"; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /v1/upload-secure-url/typescript/common/resources.ts: -------------------------------------------------------------------------------- 1 | import { api, bucket } from "@nitric/sdk"; 2 | 3 | export const fileApi = api("main"); 4 | 5 | export const imgBucket = bucket("images").allow("read", "write"); 6 | -------------------------------------------------------------------------------- /v1/upload-secure-url/typescript/nitric.aws.yaml: -------------------------------------------------------------------------------- 1 | provider: aws@1.0.2 2 | region: us-east-1 3 | -------------------------------------------------------------------------------- /v1/upload-secure-url/typescript/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: secure-bucket-access 2 | services: 3 | - match: services/*.ts 4 | start: npm run dev:services $SERVICE_PATH 5 | -------------------------------------------------------------------------------- /v1/upload-secure-url/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "main": "index.js", 6 | "private": true, 7 | "dependencies": { 8 | "@nitric/sdk": "^1.2.2", 9 | "@types/jest": "^29.5.1" 10 | }, 11 | "devDependencies": { 12 | "@babel/core": "^7.21.4", 13 | "@babel/preset-env": "^7.21.4", 14 | "@types/jest": "^29.5.1", 15 | "babel-jest": "^29.5.0", 16 | "jest": "^29.5.0", 17 | "dotenv": "^16.4.4", 18 | "nodemon": "^3.1.4", 19 | "ts-node": "^10.9.2", 20 | "typescript": "^5.3.3" 21 | }, 22 | "scripts": { 23 | "dev:services": "nodemon -r dotenv/config", 24 | "test": "jest" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /v1/upload-secure-url/typescript/services/images.ts: -------------------------------------------------------------------------------- 1 | import { getUrl } from "../common/handlers"; 2 | import { fileApi } from "../common/resources"; 3 | 4 | fileApi.get("/images/:id/upload", getUrl); 5 | 6 | fileApi.get("/images/:id/download", getUrl); 7 | -------------------------------------------------------------------------------- /v1/upload-secure-url/typescript/test/url.test.ts: -------------------------------------------------------------------------------- 1 | import { getUrl } from "../common/handlers"; 2 | 3 | describe("getUrl", () => { 4 | test("should return a signed URL for an image upload", async () => { 5 | const mockCtx = { 6 | req: { 7 | params: { id: "123" }, 8 | path: "/images/123/upload", 9 | }, 10 | res: { json: jest.fn() }, 11 | }; 12 | await getUrl(mockCtx); 13 | expect(mockCtx.res.json).toHaveBeenCalledWith({ 14 | url: expect.stringContaining("SignedHeaders"), 15 | }); 16 | }); 17 | 18 | test("should return a signed URL for an image download", async () => { 19 | const mockCtx = { 20 | req: { 21 | params: { id: "123" }, 22 | path: "/images/123/download", 23 | }, 24 | res: { json: jest.fn() }, 25 | }; 26 | await getUrl(mockCtx); 27 | expect(mockCtx.res.json).toHaveBeenCalledWith({ 28 | url: expect.stringContaining("SignedHeaders"), 29 | }); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /v1/upload-secure-url/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/uptime-monitoring/assets/arch-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitrictech/examples/865ca7e9ea7b95d171474e41b8b1b0b1f9bd99e2/v1/uptime-monitoring/assets/arch-diagram.png -------------------------------------------------------------------------------- /v1/uptime-monitoring/assets/frontend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitrictech/examples/865ca7e9ea7b95d171474e41b8b1b0b1f9bd99e2/v1/uptime-monitoring/assets/frontend.png -------------------------------------------------------------------------------- /v1/url-shortener-notify/go/.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # 'nitric run' log directory 15 | .nitric/ 16 | 17 | git.store -------------------------------------------------------------------------------- /v1/url-shortener-notify/go/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "go", 9 | "name": "Debug Nitric App", 10 | "request": "attach", 11 | "cwd": "${workspaceFolder}" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /v1/url-shortener-notify/go/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/nitrictech/templates/go-starter 2 | 3 | go 1.22.1 4 | 5 | toolchain go1.22.8 6 | 7 | require github.com/nitrictech/go-sdk v1.1.1 8 | 9 | require ( 10 | github.com/missionMeteora/toolkit v0.0.0-20170713173850-88364e3ef8cc // indirect 11 | github.com/nitrictech/nitric/core v0.0.0-20241003062412-76ea6275fb0b // indirect 12 | github.com/nitrictech/protoutils v0.0.0-20220321044654-02667a814cdf // indirect 13 | golang.org/x/net v0.33.0 // indirect 14 | golang.org/x/sys v0.28.0 // indirect 15 | golang.org/x/text v0.21.0 // indirect 16 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect 17 | google.golang.org/grpc v1.66.0 // indirect 18 | google.golang.org/protobuf v1.34.2 // indirect 19 | ) 20 | -------------------------------------------------------------------------------- /v1/url-shortener-notify/go/golang.dockerfile: -------------------------------------------------------------------------------- 1 | 2 | FROM golang:alpine as build 3 | 4 | ARG HANDLER 5 | 6 | WORKDIR /app/ 7 | 8 | COPY go.mod *.sum ./ 9 | 10 | RUN go mod download 11 | 12 | COPY . . 13 | 14 | # Build the Go App from the provided HANDLER (this will be based on matches in your nitric.yaml fle) 15 | RUN go build -o /bin/main ./${HANDLER}/... 16 | 17 | FROM alpine 18 | 19 | COPY --from=build /bin/main /bin/main 20 | 21 | RUN chmod +x-rw /bin/main 22 | RUN apk update && \ 23 | apk add --no-cache tzdata ca-certificates && \ 24 | update-ca-certificates 25 | 26 | ENTRYPOINT ["/bin/main"] -------------------------------------------------------------------------------- /v1/url-shortener-notify/go/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: url-shortner 2 | services: 3 | - basedir: "" 4 | match: services/* 5 | runtime: go 6 | start: go run ./$SERVICE_PATH/... 7 | batch-services: [] 8 | runtimes: 9 | go: 10 | dockerfile: ./golang.dockerfile 11 | context: "" 12 | args: {} 13 | -------------------------------------------------------------------------------- /v1/url-shortener-notify/go/resources/main.go: -------------------------------------------------------------------------------- 1 | package resources 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/nitrictech/go-sdk/nitric" 7 | "github.com/nitrictech/go-sdk/nitric/apis" 8 | "github.com/nitrictech/go-sdk/nitric/keyvalue" 9 | "github.com/nitrictech/go-sdk/nitric/topics" 10 | ) 11 | 12 | type Resource struct { 13 | MainApi apis.Api 14 | UrlKvStore keyvalue.KvStore 15 | NotifyTopic topics.SubscribableTopic 16 | } 17 | 18 | var ( 19 | resource *Resource 20 | resourceOnce sync.Once 21 | ) 22 | 23 | func Get() *Resource { 24 | resourceOnce.Do(func() { 25 | mainApi := nitric.NewApi("main") 26 | 27 | resource = &Resource{ 28 | MainApi: mainApi, 29 | UrlKvStore: nitric.NewKv("urls"), 30 | NotifyTopic: nitric.NewTopic("notify"), 31 | } 32 | }) 33 | 34 | return resource 35 | } 36 | -------------------------------------------------------------------------------- /v1/url-shortener-notify/go/services/notify/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/nitrictech/go-sdk/nitric" 7 | "github.com/nitrictech/go-sdk/nitric/topics" 8 | "github.com/nitrictech/templates/go-starter/resources" 9 | ) 10 | 11 | func main() { 12 | resources.Get().NotifyTopic.Subscribe(func(ctx *topics.Ctx) { 13 | fmt.Println("Received message: ", ctx.Request.Message()) 14 | // notify on discord or slack etc 15 | }) 16 | 17 | nitric.Run() 18 | 19 | fmt.Println("Notify service has started") 20 | } 21 | -------------------------------------------------------------------------------- /v1/url-shortener/go/.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # 'nitric run' log directory 15 | .nitric/ 16 | 17 | git.store -------------------------------------------------------------------------------- /v1/url-shortener/go/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "go", 9 | "name": "Debug Nitric App", 10 | "request": "attach", 11 | "cwd": "${workspaceFolder}" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /v1/url-shortener/go/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/nitrictech/templates/go-starter 2 | 3 | go 1.23.0 4 | 5 | toolchain go1.23.7 6 | 7 | require github.com/nitrictech/go-sdk v1.1.1 8 | 9 | require ( 10 | github.com/missionMeteora/toolkit v0.0.0-20170713173850-88364e3ef8cc // indirect 11 | github.com/nitrictech/nitric/core v0.0.0-20241003062412-76ea6275fb0b // indirect 12 | github.com/nitrictech/protoutils v0.0.0-20220321044654-02667a814cdf // indirect 13 | golang.org/x/net v0.36.0 // indirect 14 | golang.org/x/sys v0.30.0 // indirect 15 | golang.org/x/text v0.22.0 // indirect 16 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect 17 | google.golang.org/grpc v1.66.0 // indirect 18 | google.golang.org/protobuf v1.34.2 // indirect 19 | ) 20 | -------------------------------------------------------------------------------- /v1/url-shortener/go/golang.dockerfile: -------------------------------------------------------------------------------- 1 | 2 | FROM golang:alpine as build 3 | 4 | ARG HANDLER 5 | 6 | WORKDIR /app/ 7 | 8 | COPY go.mod *.sum ./ 9 | 10 | RUN go mod download 11 | 12 | COPY . . 13 | 14 | # Build the Go App from the provided HANDLER (this will be based on matches in your nitric.yaml fle) 15 | RUN go build -o /bin/main ./${HANDLER}/... 16 | 17 | FROM alpine 18 | 19 | COPY --from=build /bin/main /bin/main 20 | 21 | RUN chmod +x-rw /bin/main 22 | RUN apk update && \ 23 | apk add --no-cache tzdata ca-certificates && \ 24 | update-ca-certificates 25 | 26 | ENTRYPOINT ["/bin/main"] -------------------------------------------------------------------------------- /v1/url-shortener/go/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: url-shortner 2 | services: 3 | - basedir: "" 4 | match: services/* 5 | runtime: go 6 | start: go run ./$SERVICE_PATH/... 7 | batch-services: [] 8 | runtimes: 9 | go: 10 | dockerfile: ./golang.dockerfile 11 | context: "" 12 | args: {} 13 | -------------------------------------------------------------------------------- /v1/url-shortener/go/resources/main.go: -------------------------------------------------------------------------------- 1 | package resources 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/nitrictech/go-sdk/nitric" 7 | "github.com/nitrictech/go-sdk/nitric/apis" 8 | "github.com/nitrictech/go-sdk/nitric/keyvalue" 9 | ) 10 | 11 | type Resource struct { 12 | MainApi apis.Api 13 | UrlKvStore keyvalue.KvStore 14 | } 15 | 16 | var ( 17 | resource *Resource 18 | resourceOnce sync.Once 19 | ) 20 | 21 | func Get() *Resource { 22 | resourceOnce.Do(func() { 23 | mainApi := nitric.NewApi("main") 24 | 25 | resource = &Resource{ 26 | MainApi: mainApi, 27 | UrlKvStore: nitric.NewKv("urls"), 28 | } 29 | }) 30 | 31 | return resource 32 | } 33 | -------------------------------------------------------------------------------- /v1/user-onboarding/typescript/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "targets": { 7 | "node": "current" 8 | } 9 | } 10 | ] 11 | ] 12 | } -------------------------------------------------------------------------------- /v1/user-onboarding/typescript/.env.template: -------------------------------------------------------------------------------- 1 | AWS_SES_REGION="us-east-1" 2 | AWS_SES_ACCESS_KEY_ID="..." 3 | AWS_SES_SECRET_ACCESS_KEY="..." 4 | 5 | SENDER_EMAIL="email@email.com" -------------------------------------------------------------------------------- /v1/user-onboarding/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ 3 | .env -------------------------------------------------------------------------------- /v1/user-onboarding/typescript/arch_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nitrictech/examples/865ca7e9ea7b95d171474e41b8b1b0b1f9bd99e2/v1/user-onboarding/typescript/arch_diagram.png -------------------------------------------------------------------------------- /v1/user-onboarding/typescript/common/resources.ts: -------------------------------------------------------------------------------- 1 | import { api, kv, topic } from "@nitric/sdk"; 2 | 3 | // Stores 4 | export const custStore = kv("customers").allow("set"); 5 | // API 6 | export const custApi = api("public"); 7 | // Topics 8 | export const custCreatePub = topic("created").allow("publish"); 9 | export const custCreateSub = topic("created"); 10 | -------------------------------------------------------------------------------- /v1/user-onboarding/typescript/nitric.aws.yaml: -------------------------------------------------------------------------------- 1 | provider: aws@1.0.2 2 | region: us-east-1 3 | -------------------------------------------------------------------------------- /v1/user-onboarding/typescript/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: onboarding 2 | services: 3 | - match: services/*.ts 4 | start: npm run dev:services $SERVICE_PATH 5 | -------------------------------------------------------------------------------- /v1/user-onboarding/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "main": "index.js", 6 | "private": true, 7 | "dependencies": { 8 | "@aws-sdk/client-ses": "^3.201.0", 9 | "@nitric/sdk": "^1.2.2", 10 | "aws-sdk": "^2.1245.0", 11 | "jest": "^29.5.0", 12 | "uuidv4": "^6.2.13" 13 | }, 14 | "devDependencies": { 15 | "@babel/preset-env": "^7.21.4", 16 | "@babel/preset-typescript": "^7.21.4", 17 | "@types/jest": "^29.5.1", 18 | "babel-jest": "^29.5.0", 19 | "dotenv": "^16.4.4", 20 | "nodemon": "^3.1.4", 21 | "ts-node": "^10.9.2", 22 | "typescript": "^5.3.3" 23 | }, 24 | "scripts": { 25 | "dev:services": "nodemon -r dotenv/config", 26 | "test": "jest" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /v1/user-onboarding/typescript/services/notify.ts: -------------------------------------------------------------------------------- 1 | import { createEmailRequest, sendEmail } from "../common/email"; 2 | import { custCreateSub } from "../common/resources"; 3 | 4 | custCreateSub.subscribe(async (ctx) => { 5 | const { template, subject, recipient } = ctx.req.json(); 6 | // Send the email notification 7 | sendEmail( 8 | createEmailRequest({ 9 | sender: process.env.SENDER_EMAIL as string, 10 | recipient: [recipient], 11 | body: "", 12 | html: template, 13 | subject: subject, 14 | }) 15 | ); 16 | return ctx; 17 | }); 18 | -------------------------------------------------------------------------------- /v1/user-onboarding/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/website-status/typescript/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "targets": { 7 | "node": "current" 8 | } 9 | } 10 | ] 11 | ] 12 | } -------------------------------------------------------------------------------- /v1/website-status/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ -------------------------------------------------------------------------------- /v1/website-status/typescript/common/handlers.ts: -------------------------------------------------------------------------------- 1 | export const handlePing = async (ctx) => { 2 | const { url } = ctx.req.json(); 3 | const formattedUrl = 4 | url.startsWith("http:") || url.startsWith("https:") 5 | ? url 6 | : `https://${url}`; 7 | 8 | try { 9 | const response = await fetch(formattedUrl); 10 | ctx.res.body = { status: response.status < 400, url: formattedUrl }; 11 | } catch (error) { 12 | ctx.res.body = { status: false, url: formattedUrl }; 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /v1/website-status/typescript/common/resources.ts: -------------------------------------------------------------------------------- 1 | import { api } from "@nitric/sdk"; 2 | 3 | // Create a new Nitric API endpoint with the name "ping" 4 | export const myApis = api("ping"); 5 | -------------------------------------------------------------------------------- /v1/website-status/typescript/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: ping 2 | services: 3 | - match: services/*.ts 4 | start: npm run dev:services $SERVICE_PATH 5 | -------------------------------------------------------------------------------- /v1/website-status/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "main": "index.js", 6 | "private": true, 7 | "dependencies": { 8 | "@nitric/sdk": "^1.2.2" 9 | }, 10 | "devDependencies": { 11 | "@babel/core": "^7.21.4", 12 | "@babel/preset-env": "^7.21.4", 13 | "babel-jest": "^29.5.0", 14 | "jest": "^29.5.0", 15 | "@types/jest": "^29.5.1", 16 | "dotenv": "^16.4.4", 17 | "nodemon": "^3.1.4", 18 | "ts-node": "^10.9.2", 19 | "typescript": "^5.3.3" 20 | }, 21 | "scripts": { 22 | "dev:services": "nodemon -r dotenv/config", 23 | "test": "jest" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /v1/website-status/typescript/services/ping.ts: -------------------------------------------------------------------------------- 1 | import { handlePing } from "../common/handlers"; 2 | import { myApis } from "../common/resources"; 3 | 4 | myApis.post("/ping", handlePing); 5 | -------------------------------------------------------------------------------- /v1/website-status/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /v1/websocket-app/.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # 'nitric run' log directory 15 | .nitric/ 16 | 17 | git.store -------------------------------------------------------------------------------- /v1/websocket-app/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/nitrictech/templates/go-starter 2 | 3 | go 1.22.1 4 | 5 | toolchain go1.22.8 6 | 7 | require github.com/nitrictech/go-sdk v1.1.1 8 | 9 | require ( 10 | github.com/missionMeteora/toolkit v0.0.0-20170713173850-88364e3ef8cc // indirect 11 | github.com/nitrictech/nitric/core v0.0.0-20241003062412-76ea6275fb0b // indirect 12 | github.com/nitrictech/protoutils v0.0.0-20220321044654-02667a814cdf // indirect 13 | golang.org/x/net v0.28.0 // indirect 14 | golang.org/x/sys v0.25.0 // indirect 15 | golang.org/x/text v0.18.0 // indirect 16 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect 17 | google.golang.org/grpc v1.66.0 // indirect 18 | google.golang.org/protobuf v1.34.2 // indirect 19 | ) 20 | -------------------------------------------------------------------------------- /v1/websocket-app/golang.dockerfile: -------------------------------------------------------------------------------- 1 | 2 | FROM golang:alpine as build 3 | 4 | ARG HANDLER 5 | 6 | WORKDIR /app/ 7 | 8 | COPY go.mod *.sum ./ 9 | 10 | RUN go mod download 11 | 12 | COPY . . 13 | 14 | # Build the Go App from the provided HANDLER (this will be based on matches in your nitric.yaml fle) 15 | RUN go build -o /bin/main ./${HANDLER}/... 16 | 17 | FROM alpine 18 | 19 | COPY --from=build /bin/main /bin/main 20 | 21 | RUN chmod +x-rw /bin/main 22 | RUN apk update && \ 23 | apk add --no-cache tzdata ca-certificates && \ 24 | update-ca-certificates 25 | 26 | ENTRYPOINT ["/bin/main"] -------------------------------------------------------------------------------- /v1/websocket-app/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: websocket-app 2 | services: 3 | - match: services/* 4 | runtime: go 5 | type: "" 6 | start: go run ./$SERVICE_PATH/... 7 | runtimes: 8 | go: 9 | dockerfile: ./golang.dockerfile 10 | context: "" 11 | args: {} 12 | preview: 13 | - beta-providers 14 | -------------------------------------------------------------------------------- /v1/websockets/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nitric/ -------------------------------------------------------------------------------- /v1/websockets/nitric.yaml: -------------------------------------------------------------------------------- 1 | name: sockets 2 | services: 3 | - match: services/*.ts 4 | start: npm run dev:services $SERVICE_PATH 5 | preview-features: 6 | - websockets 7 | -------------------------------------------------------------------------------- /v1/websockets/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-starter", 3 | "version": "1.0.0", 4 | "description": "nitric typescript starter template", 5 | "main": "index.js", 6 | "private": true, 7 | "dependencies": { 8 | "@nitric/sdk": "^1.2.2" 9 | }, 10 | "devDependencies": { 11 | "dotenv": "^16.4.4", 12 | "nodemon": "^3.1.4", 13 | "ts-node": "^10.9.2", 14 | "typescript": "^5.3.3" 15 | }, 16 | "scripts": { 17 | "dev:services": "nodemon -r dotenv/config" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /v1/websockets/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "target": "ESNext", 5 | "moduleResolution": "node" 6 | } 7 | } 8 | --------------------------------------------------------------------------------