From 496b3ddea1cdc02edc152e8908c8a007546ebbeb Mon Sep 17 00:00:00 2001 From: cdhaadmin <75491863+cdhaadmin@users.noreply.github.com> Date: Tue, 28 Jan 2025 13:56:43 -0500 Subject: [PATCH] Initial commit --- .gitignore | 18 +++++ LICENSE | 21 +++++ README.md | 81 ++++++++++++++++++++ infra/api.ts | 7 ++ infra/storage.ts | 1 + package.json | 15 ++++ packages/core/package.json | 20 +++++ packages/core/src/example/index.ts | 5 ++ packages/core/src/example/test/index.test.ts | 8 ++ packages/core/tsconfig.json | 7 ++ packages/functions/package.json | 12 +++ packages/functions/src/api.ts | 10 +++ packages/functions/tsconfig.json | 7 ++ packages/scripts/package.json | 16 ++++ packages/scripts/src/example.ts | 4 + packages/scripts/tsconfig.json | 7 ++ sst.config.ts | 20 +++++ tsconfig.json | 1 + 18 files changed, 260 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 infra/api.ts create mode 100644 infra/storage.ts create mode 100644 package.json create mode 100644 packages/core/package.json create mode 100644 packages/core/src/example/index.ts create mode 100644 packages/core/src/example/test/index.test.ts create mode 100644 packages/core/tsconfig.json create mode 100644 packages/functions/package.json create mode 100644 packages/functions/src/api.ts create mode 100644 packages/functions/tsconfig.json create mode 100644 packages/scripts/package.json create mode 100644 packages/scripts/src/example.ts create mode 100644 packages/scripts/tsconfig.json create mode 100644 sst.config.ts create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e2ead72 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +# dependencies +node_modules + +# sst +.sst + +# tmp files +.#* + +# env +.env*.local +.env + +# opennext +.open-next + +# misc +.DS_Store diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c6eca6e --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 SST + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..b081756 --- /dev/null +++ b/README.md @@ -0,0 +1,81 @@ +# Monorepo Template + +A template to create a monorepo SST v3 project. [Learn more](https://sst.dev/docs/set-up-a-monorepo). + +## Get started + +1. Use this template to [create your own repo](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template). + +2. Clone the new repo. + + ```bash + git clone MY_APP + cd MY_APP + ``` + +3. Rename the files in the project to the name of your app. + + ```bash + npx replace-in-file '/monorepo-template/g' 'MY_APP' '**/*.*' --verbose + ``` + +4. Deploy! + + ```bash + npm install + npx sst deploy + ``` + +5. Optionally, enable [_git push to deploy_](https://sst.dev/docs/console/#autodeploy). + +## Usage + +This template uses [npm Workspaces](https://docs.npmjs.com/cli/v8/using-npm/workspaces). It has 3 packages to start with and you can add more it. + +1. `core/` + + This is for any shared code. It's defined as modules. For example, there's the `Example` module. + + ```ts + export module Example { + export function hello() { + return "Hello, world!"; + } + } + ``` + + That you can use across other packages using. + + ```ts + import { Example } from "@aws-monorepo/core/example"; + + Example.hello(); + ``` + + We also have [Vitest](https://vitest.dev/) configured for testing this package with the `sst shell` CLI. + + ```bash + npm test + ``` + +2. `functions/` + + This is for your Lambda functions and it uses the `core` package as a local dependency. + +3. `scripts/` + + This is for any scripts that you can run on your SST app using the `sst shell` CLI and [`tsx`](https://www.npmjs.com/package/tsx). For example, you can run the example script using: + + ```bash + npm run shell src/example.ts + ``` + +### Infrastructure + +The `infra/` directory allows you to logically split the infrastructure of your app into separate files. This can be helpful as your app grows. + +In the template, we have an `api.ts`, and `storage.ts`. These export the created resources. And are imported in the `sst.config.ts`. + +--- + +**Join our community** [Discord](https://sst.dev/discord) | [YouTube](https://www.youtube.com/c/sst-dev) | [X.com](https://x.com/SST_dev) diff --git a/infra/api.ts b/infra/api.ts new file mode 100644 index 0000000..380751c --- /dev/null +++ b/infra/api.ts @@ -0,0 +1,7 @@ +import { bucket } from "./storage"; + +export const myApi = new sst.aws.Function("MyApi", { + url: true, + link: [bucket], + handler: "packages/functions/src/api.handler" +}); diff --git a/infra/storage.ts b/infra/storage.ts new file mode 100644 index 0000000..6aff03d --- /dev/null +++ b/infra/storage.ts @@ -0,0 +1 @@ +export const bucket = new sst.aws.Bucket("MyBucket"); diff --git a/package.json b/package.json new file mode 100644 index 0000000..0f48ddd --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "monorepo-template", + "version": "0.0.0", + "workspaces": [ + "packages/*" + ], + "scripts": {}, + "devDependencies": { + "@tsconfig/node22": "^22", + "typescript": "^5" + }, + "dependencies": { + "sst": "^3" + } +} diff --git a/packages/core/package.json b/packages/core/package.json new file mode 100644 index 0000000..e2f4306 --- /dev/null +++ b/packages/core/package.json @@ -0,0 +1,20 @@ +{ + "name": "@monorepo-template/core", + "type": "module", + "version": "0.0.0", + "scripts": { + "test": "sst shell vitest" + }, + "exports": { + "./*": [ + "./src/*/index.ts", + "./src/*.ts" + ] + }, + "dependencies": { + "sst": "*" + }, + "devDependencies": { + "vitest": "^2" + } +} diff --git a/packages/core/src/example/index.ts b/packages/core/src/example/index.ts new file mode 100644 index 0000000..53b1d6d --- /dev/null +++ b/packages/core/src/example/index.ts @@ -0,0 +1,5 @@ +export module Example { + export function hello() { + return "Hello, world!"; + } +} diff --git a/packages/core/src/example/test/index.test.ts b/packages/core/src/example/test/index.test.ts new file mode 100644 index 0000000..18d84d1 --- /dev/null +++ b/packages/core/src/example/test/index.test.ts @@ -0,0 +1,8 @@ +import { expect, test } from "vitest"; +import { Example } from "../"; + +test("Hello test", () => { + const expected = "Hello, world!"; + + expect(Example.hello()).toEqual(expected); +}); diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json new file mode 100644 index 0000000..be3c6ac --- /dev/null +++ b/packages/core/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "@tsconfig/node22/tsconfig.json", + "compilerOptions": { + "module": "ESNext", + "moduleResolution": "Bundler", + }, +} diff --git a/packages/functions/package.json b/packages/functions/package.json new file mode 100644 index 0000000..e9d7fcc --- /dev/null +++ b/packages/functions/package.json @@ -0,0 +1,12 @@ +{ + "name": "@monorepo-template/functions", + "version": "0.0.0", + "type": "module", + "dependencies": { + "@monorepo-template/core": "*", + "sst": "*" + }, + "devDependencies": { + "@types/aws-lambda": "^8" + } +} diff --git a/packages/functions/src/api.ts b/packages/functions/src/api.ts new file mode 100644 index 0000000..7220003 --- /dev/null +++ b/packages/functions/src/api.ts @@ -0,0 +1,10 @@ +import { Resource } from "sst"; +import { Handler } from "aws-lambda"; +import { Example } from "@monorepo-template/core/example"; + +export const handler: Handler = async (_event) => { + return { + statusCode: 200, + body: `${Example.hello()} Linked to ${Resource.MyBucket.name}.`, + }; +}; diff --git a/packages/functions/tsconfig.json b/packages/functions/tsconfig.json new file mode 100644 index 0000000..be3c6ac --- /dev/null +++ b/packages/functions/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "@tsconfig/node22/tsconfig.json", + "compilerOptions": { + "module": "ESNext", + "moduleResolution": "Bundler", + }, +} diff --git a/packages/scripts/package.json b/packages/scripts/package.json new file mode 100644 index 0000000..0d78487 --- /dev/null +++ b/packages/scripts/package.json @@ -0,0 +1,16 @@ +{ + "name": "@monorepo-template/scripts", + "version": "0.0.0", + "type": "module", + "dependencies": { + "@monorepo-template/core": "*", + "sst": "*" + }, + "scripts": { + "shell": "sst shell tsx" + }, + "devDependencies": { + "@types/node": "^22", + "tsx": "^4" + } +} diff --git a/packages/scripts/src/example.ts b/packages/scripts/src/example.ts new file mode 100644 index 0000000..3dd8a8c --- /dev/null +++ b/packages/scripts/src/example.ts @@ -0,0 +1,4 @@ +import { Resource } from "sst"; +import { Example } from "@monorepo-template/core/example"; + +console.log(`${Example.hello()} Linked to ${Resource.MyBucket.name}.`); diff --git a/packages/scripts/tsconfig.json b/packages/scripts/tsconfig.json new file mode 100644 index 0000000..be3c6ac --- /dev/null +++ b/packages/scripts/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "@tsconfig/node22/tsconfig.json", + "compilerOptions": { + "module": "ESNext", + "moduleResolution": "Bundler", + }, +} diff --git a/sst.config.ts b/sst.config.ts new file mode 100644 index 0000000..c55c70b --- /dev/null +++ b/sst.config.ts @@ -0,0 +1,20 @@ +/// + +export default $config({ + app(input) { + return { + name: "monorepo-template", + removal: input?.stage === "production" ? "retain" : "remove", + protect: ["production"].includes(input?.stage), + home: "aws", + }; + }, + async run() { + const storage = await import("./infra/storage"); + await import("./infra/api"); + + return { + MyBucket: storage.bucket.name, + }; + }, +}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1 @@ +{}