@lsts_tech/infra 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +158 -0
- package/dist/bin/init.d.ts +9 -0
- package/dist/bin/init.d.ts.map +1 -0
- package/dist/bin/init.js +315 -0
- package/dist/bin/init.js.map +1 -0
- package/dist/stacks/Dns.d.ts +69 -0
- package/dist/stacks/Dns.d.ts.map +1 -0
- package/dist/stacks/Dns.js +57 -0
- package/dist/stacks/Dns.js.map +1 -0
- package/dist/stacks/ExpoSite.d.ts +72 -0
- package/dist/stacks/ExpoSite.d.ts.map +1 -0
- package/dist/stacks/ExpoSite.js +49 -0
- package/dist/stacks/ExpoSite.js.map +1 -0
- package/dist/stacks/NextSite.d.ts +86 -0
- package/dist/stacks/NextSite.d.ts.map +1 -0
- package/dist/stacks/NextSite.js +60 -0
- package/dist/stacks/NextSite.js.map +1 -0
- package/dist/stacks/Pipeline.d.ts +128 -0
- package/dist/stacks/Pipeline.d.ts.map +1 -0
- package/dist/stacks/Pipeline.js +311 -0
- package/dist/stacks/Pipeline.js.map +1 -0
- package/dist/stacks/index.d.ts +41 -0
- package/dist/stacks/index.d.ts.map +1 -0
- package/dist/stacks/index.js +38 -0
- package/dist/stacks/index.js.map +1 -0
- package/docs/CLI.md +59 -0
- package/docs/CONFIGURATION.md +78 -0
- package/docs/EXAMPLES.md +9 -0
- package/examples/next-and-expo/infra.config.ts +104 -0
- package/examples/next-only/infra.config.ts +60 -0
- package/package.json +102 -0
- package/schemas/pipeline.schema.json +25 -0
- package/scripts/cleanup-orphan-lambdas.sh +102 -0
- package/scripts/delete-amplify-app.sh +50 -0
- package/scripts/ensure-pipelines.sh +144 -0
- package/scripts/ensure-secrets.sh +58 -0
- package/scripts/postdeploy-update-dns.sh +158 -0
- package/scripts/predeploy-checks.sh +192 -0
- package/scripts/pulumi-deploy.sh +29 -0
- package/scripts/sst-deploy.sh +79 -0
- package/templates/buildspec.yml +77 -0
- package/templates/ensure-pipelines.sh +117 -0
- package/templates/env.example +38 -0
- package/templates/infra.config.ts +199 -0
- package/templates/secrets.schema.json +20 -0
- package/templates/sst-env.d.ts +50 -0
- package/templates/sst.config.ts +28 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Ed Calderon
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# @lsts_tech/infra
|
|
2
|
+
|
|
3
|
+
Reusable, white-label SST v3 infrastructure primitives for AWS deployments from monorepos.
|
|
4
|
+
|
|
5
|
+
`@lsts_tech/infra` focuses on portability:
|
|
6
|
+
|
|
7
|
+
- No hardcoded project domains/repos in package code
|
|
8
|
+
- Environment-driven scaffolding for public repositories
|
|
9
|
+
- CLI bootstrap for consistent setup (`npx @lsts_tech/infra init`)
|
|
10
|
+
- Next.js (`sst.aws.Nextjs`) and Expo Web (`sst.aws.StaticSite`) support
|
|
11
|
+
- AWS CodePipeline + CodeBuild CI/CD helpers
|
|
12
|
+
|
|
13
|
+
## Version Scope
|
|
14
|
+
|
|
15
|
+
`v1.0.0` provider support: **AWS only**.
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @lsts_tech/infra
|
|
21
|
+
# or
|
|
22
|
+
pnpm add @lsts_tech/infra
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
### 1. Scaffold infra files
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npx @lsts_tech/infra init \
|
|
31
|
+
--project myapp \
|
|
32
|
+
--domain example.com \
|
|
33
|
+
--repo myorg/myrepo \
|
|
34
|
+
--pipelines production,dev
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Optional Expo support:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npx @lsts_tech/infra init \
|
|
41
|
+
--project myapp \
|
|
42
|
+
--domain example.com \
|
|
43
|
+
--repo myorg/myrepo \
|
|
44
|
+
--pipelines production,dev,mobile \
|
|
45
|
+
--with-expo
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 2. Review generated files
|
|
49
|
+
|
|
50
|
+
- `sst.config.ts`
|
|
51
|
+
- `sst-env.d.ts`
|
|
52
|
+
- `infra.config.ts`
|
|
53
|
+
- `.env.example`
|
|
54
|
+
- `buildspec.yml`
|
|
55
|
+
- `schemas/secrets.schema.json`
|
|
56
|
+
- `scripts/ensure-pipelines.sh`
|
|
57
|
+
|
|
58
|
+
### 3. Configure environment and secrets
|
|
59
|
+
|
|
60
|
+
Use `.env.example` as the variable contract for your CI/local environment.
|
|
61
|
+
|
|
62
|
+
Set minimum SST secrets:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx sst secrets set DatabaseUrl "postgresql://..." --stage dev
|
|
66
|
+
npx sst secrets set AuthSecret "replace-me" --stage dev
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 4. Deploy
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npx sst deploy --stage dev
|
|
73
|
+
npx sst deploy --stage production
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 5. Ensure pipelines
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
APPROVE=true bash scripts/ensure-pipelines.sh
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## CLI
|
|
83
|
+
|
|
84
|
+
### `init`
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npx @lsts_tech/infra init [options]
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
| Option | Description | Default |
|
|
91
|
+
|---|---|---|
|
|
92
|
+
| `--provider <name>` | Cloud provider (`aws`) | `aws` |
|
|
93
|
+
| `--project <slug>` | Project/app prefix | `myapp` |
|
|
94
|
+
| `--app-name <name>` | SST app name | `--project` |
|
|
95
|
+
| `--domain <domain>` | Root domain | `example.com` |
|
|
96
|
+
| `--repo <owner/repo>` | GitHub repo for pipeline source | `myorg/myrepo` |
|
|
97
|
+
| `--pipelines <list>` | `production,dev,mobile` CSV or `none` | `production,dev` |
|
|
98
|
+
| `--branch-prod <branch>` | Production branch | `main` |
|
|
99
|
+
| `--branch-dev <branch>` | Dev branch | `develop` |
|
|
100
|
+
| `--branch-mobile <branch>` | Mobile branch | `mobile` |
|
|
101
|
+
| `--with-expo` | Enable Expo scaffold defaults | `false` |
|
|
102
|
+
| `--infra-path <path>` | Infra path from monorepo root | `packages/infra` |
|
|
103
|
+
| `--target <path>` | Output directory | `.` |
|
|
104
|
+
| `--force` | Overwrite existing files | `false` |
|
|
105
|
+
|
|
106
|
+
Full CLI docs: [docs/CLI.md](./docs/CLI.md)
|
|
107
|
+
|
|
108
|
+
## API Reference
|
|
109
|
+
|
|
110
|
+
### `resolveDomain(config: DnsConfig): DomainResult`
|
|
111
|
+
|
|
112
|
+
Stage-aware domain resolution.
|
|
113
|
+
|
|
114
|
+
### `createNextSite(config: NextSiteConfig): { site, url }`
|
|
115
|
+
|
|
116
|
+
Creates an SST `aws.Nextjs` deployment.
|
|
117
|
+
|
|
118
|
+
### `createExpoSite(config: ExpoSiteConfig): { site, url }`
|
|
119
|
+
|
|
120
|
+
Creates an SST `aws.StaticSite` deployment for Expo web exports.
|
|
121
|
+
|
|
122
|
+
### `createPipeline(config: PipelineConfig): PipelineResult`
|
|
123
|
+
|
|
124
|
+
Creates an AWS CodePipeline + CodeBuild deployment pipeline.
|
|
125
|
+
|
|
126
|
+
## Scripts Included
|
|
127
|
+
|
|
128
|
+
| Script | Purpose |
|
|
129
|
+
|---|---|
|
|
130
|
+
| `scripts/predeploy-checks.sh` | DNS/CloudFront/ACM pre-deploy checks |
|
|
131
|
+
| `scripts/postdeploy-update-dns.sh` | Route53 alias synchronization |
|
|
132
|
+
| `scripts/ensure-secrets.sh` | SST secret provisioning from schema |
|
|
133
|
+
| `scripts/sst-deploy.sh` | CI-safe SST deploy wrapper |
|
|
134
|
+
| `scripts/ensure-pipelines.sh` | Ensure configured pipelines exist |
|
|
135
|
+
| `scripts/pulumi-deploy.sh` | CI-safe Pulumi deploy wrapper |
|
|
136
|
+
| `scripts/cleanup-orphan-lambdas.sh` | Cleanup stale Lambda functions |
|
|
137
|
+
| `scripts/delete-amplify-app.sh` | Remove legacy Amplify apps |
|
|
138
|
+
|
|
139
|
+
## Examples and Docs
|
|
140
|
+
|
|
141
|
+
- Configuration guide: [docs/CONFIGURATION.md](./docs/CONFIGURATION.md)
|
|
142
|
+
- CLI guide: [docs/CLI.md](./docs/CLI.md)
|
|
143
|
+
- Example index: [docs/EXAMPLES.md](./docs/EXAMPLES.md)
|
|
144
|
+
- Next-only example: [examples/next-only/infra.config.ts](./examples/next-only/infra.config.ts)
|
|
145
|
+
- Next + Expo example: [examples/next-and-expo/infra.config.ts](./examples/next-and-expo/infra.config.ts)
|
|
146
|
+
|
|
147
|
+
## Publish Checklist
|
|
148
|
+
|
|
149
|
+
Before publishing to npm:
|
|
150
|
+
|
|
151
|
+
1. `npm run build`
|
|
152
|
+
2. `npm run check-types`
|
|
153
|
+
3. `npm pack --dry-run`
|
|
154
|
+
4. Verify tarball has no project-private infra/state files
|
|
155
|
+
|
|
156
|
+
## License
|
|
157
|
+
|
|
158
|
+
MIT © LSTS Solutions
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../bin/init.ts"],"names":[],"mappings":";AAEA;;;;;GAKG"}
|
package/dist/bin/init.js
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @lsts_tech/infra — CLI Init Script
|
|
4
|
+
*
|
|
5
|
+
* Scaffolds project-specific configuration files for the infra package.
|
|
6
|
+
* Run with: npx @lsts_tech/infra init
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync, chmodSync } from "node:fs";
|
|
9
|
+
import { resolve, dirname, join } from "node:path";
|
|
10
|
+
import { fileURLToPath } from "node:url";
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = dirname(__filename);
|
|
13
|
+
const TEMPLATES_DIR = resolve(__dirname, "..", "..", "templates");
|
|
14
|
+
const PIPELINE_DEFS = {
|
|
15
|
+
production: { suffix: "prod", defaultBranch: "main" },
|
|
16
|
+
dev: { suffix: "dev", defaultBranch: "develop" },
|
|
17
|
+
mobile: { suffix: "mobile", defaultBranch: "mobile" },
|
|
18
|
+
};
|
|
19
|
+
const FILES_TO_SCAFFOLD = [
|
|
20
|
+
{
|
|
21
|
+
source: "sst.config.ts",
|
|
22
|
+
target: "sst.config.ts",
|
|
23
|
+
description: "SST app entrypoint",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
source: "sst-env.d.ts",
|
|
27
|
+
target: "sst-env.d.ts",
|
|
28
|
+
description: "SST type stubs",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
source: "infra.config.ts",
|
|
32
|
+
target: "infra.config.ts",
|
|
33
|
+
description: "Infrastructure configuration",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
source: "env.example",
|
|
37
|
+
target: ".env.example",
|
|
38
|
+
description: "Infrastructure environment template",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
source: "secrets.schema.json",
|
|
42
|
+
target: "schemas/secrets.schema.json",
|
|
43
|
+
description: "Secrets schema definition",
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
source: "ensure-pipelines.sh",
|
|
47
|
+
target: "scripts/ensure-pipelines.sh",
|
|
48
|
+
description: "Pipeline management script",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
source: "buildspec.yml",
|
|
52
|
+
target: "buildspec.yml",
|
|
53
|
+
description: "CodeBuild build specification",
|
|
54
|
+
},
|
|
55
|
+
];
|
|
56
|
+
function printHelp() {
|
|
57
|
+
console.log(`
|
|
58
|
+
@lsts_tech/infra — init
|
|
59
|
+
|
|
60
|
+
Usage:
|
|
61
|
+
npx @lsts_tech/infra init [options]
|
|
62
|
+
|
|
63
|
+
Options:
|
|
64
|
+
--provider <name> Cloud provider to target (v1.0.0 supports: aws)
|
|
65
|
+
--project <slug> Project/app prefix (default: myapp)
|
|
66
|
+
--app-name <name> SST app name (default: --project)
|
|
67
|
+
--domain <domain> Root domain (default: example.com)
|
|
68
|
+
--repo <owner/repo> GitHub repo for pipelines (default: myorg/myrepo)
|
|
69
|
+
--pipelines <list> Comma list: production,dev,mobile or 'none' (default: production,dev)
|
|
70
|
+
--with-expo Enable Expo web site defaults in scaffolded config
|
|
71
|
+
--infra-path <path> Infra path from monorepo root (default: packages/infra)
|
|
72
|
+
--target <path> Directory to scaffold into (default: current directory)
|
|
73
|
+
--force Overwrite existing files
|
|
74
|
+
--help Show this help
|
|
75
|
+
|
|
76
|
+
Examples:
|
|
77
|
+
npx @lsts_tech/infra init --project acme --domain acme.com --repo acme/web
|
|
78
|
+
npx @lsts_tech/infra init --project acme --pipelines production,dev,mobile --with-expo
|
|
79
|
+
npx @lsts_tech/infra init --target packages/infra --force
|
|
80
|
+
`);
|
|
81
|
+
}
|
|
82
|
+
function parseArgs(args) {
|
|
83
|
+
const result = { flags: {} };
|
|
84
|
+
if (args.length > 0 && !args[0].startsWith("--")) {
|
|
85
|
+
result.command = args[0];
|
|
86
|
+
args = args.slice(1);
|
|
87
|
+
}
|
|
88
|
+
for (let i = 0; i < args.length; i++) {
|
|
89
|
+
const token = args[i];
|
|
90
|
+
if (!token.startsWith("--")) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const trimmed = token.slice(2);
|
|
94
|
+
const eqIndex = trimmed.indexOf("=");
|
|
95
|
+
if (eqIndex !== -1) {
|
|
96
|
+
const key = trimmed.slice(0, eqIndex);
|
|
97
|
+
const value = trimmed.slice(eqIndex + 1);
|
|
98
|
+
result.flags[key] = value;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const next = args[i + 1];
|
|
102
|
+
if (!next || next.startsWith("--")) {
|
|
103
|
+
result.flags[trimmed] = true;
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
result.flags[trimmed] = next;
|
|
107
|
+
i++;
|
|
108
|
+
}
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
function readFlag(flags, key, fallback) {
|
|
112
|
+
const value = flags[key];
|
|
113
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
114
|
+
return value.trim();
|
|
115
|
+
}
|
|
116
|
+
return fallback;
|
|
117
|
+
}
|
|
118
|
+
function readBool(flags, key, fallback = false) {
|
|
119
|
+
const value = flags[key];
|
|
120
|
+
if (typeof value === "boolean") {
|
|
121
|
+
return value;
|
|
122
|
+
}
|
|
123
|
+
if (typeof value === "string") {
|
|
124
|
+
const normalized = value.trim().toLowerCase();
|
|
125
|
+
if (["1", "true", "yes", "y"].includes(normalized))
|
|
126
|
+
return true;
|
|
127
|
+
if (["0", "false", "no", "n"].includes(normalized))
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
return fallback;
|
|
131
|
+
}
|
|
132
|
+
function toSlug(value) {
|
|
133
|
+
const slug = value
|
|
134
|
+
.toLowerCase()
|
|
135
|
+
.replace(/[^a-z0-9-]/g, "-")
|
|
136
|
+
.replace(/-{2,}/g, "-")
|
|
137
|
+
.replace(/^-+|-+$/g, "");
|
|
138
|
+
return slug || "myapp";
|
|
139
|
+
}
|
|
140
|
+
function parsePipelines(raw) {
|
|
141
|
+
if (raw.trim().length === 0 || raw.trim().toLowerCase() === "none") {
|
|
142
|
+
return [];
|
|
143
|
+
}
|
|
144
|
+
const normalized = raw
|
|
145
|
+
.split(",")
|
|
146
|
+
.map((entry) => entry.trim().toLowerCase())
|
|
147
|
+
.filter(Boolean)
|
|
148
|
+
.map((entry) => {
|
|
149
|
+
if (entry === "prod")
|
|
150
|
+
return "production";
|
|
151
|
+
return entry;
|
|
152
|
+
});
|
|
153
|
+
const allowed = ["production", "dev", "mobile"];
|
|
154
|
+
const invalid = normalized.filter((entry) => !allowed.includes(entry));
|
|
155
|
+
if (invalid.length > 0) {
|
|
156
|
+
throw new Error(`Invalid pipeline stage(s): ${invalid.join(", ")}. Allowed: production,dev,mobile`);
|
|
157
|
+
}
|
|
158
|
+
const deduped = [];
|
|
159
|
+
for (const entry of normalized) {
|
|
160
|
+
if (!deduped.includes(entry)) {
|
|
161
|
+
deduped.push(entry);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return deduped;
|
|
165
|
+
}
|
|
166
|
+
function buildMapEntries(options, kind) {
|
|
167
|
+
if (options.pipelines.length === 0) {
|
|
168
|
+
return " # no pipelines configured";
|
|
169
|
+
}
|
|
170
|
+
return options.pipelines
|
|
171
|
+
.map((pipeline) => {
|
|
172
|
+
const def = PIPELINE_DEFS[pipeline];
|
|
173
|
+
const name = `${options.project}-${def.suffix}`;
|
|
174
|
+
if (kind === "stage") {
|
|
175
|
+
return ` ["${name}"]="${pipeline}"`;
|
|
176
|
+
}
|
|
177
|
+
if (kind === "repo") {
|
|
178
|
+
return ` ["${name}"]="${options.repo}"`;
|
|
179
|
+
}
|
|
180
|
+
const branchFlag = pipeline === "production"
|
|
181
|
+
? "branch-prod"
|
|
182
|
+
: pipeline === "dev"
|
|
183
|
+
? "branch-dev"
|
|
184
|
+
: "branch-mobile";
|
|
185
|
+
return ` ["${name}"]="__${branchFlag.toUpperCase().replace(/-/g, "_")}__"`;
|
|
186
|
+
})
|
|
187
|
+
.join("\n");
|
|
188
|
+
}
|
|
189
|
+
function applyTemplate(content, replacements) {
|
|
190
|
+
let output = content;
|
|
191
|
+
for (const [key, value] of Object.entries(replacements)) {
|
|
192
|
+
output = output.split(key).join(value);
|
|
193
|
+
}
|
|
194
|
+
return output;
|
|
195
|
+
}
|
|
196
|
+
function buildReplacements(options) {
|
|
197
|
+
return {
|
|
198
|
+
"__PROVIDER__": options.provider,
|
|
199
|
+
"__PROJECT_PREFIX__": options.project,
|
|
200
|
+
"__APP_NAME__": options.appName,
|
|
201
|
+
"__ROOT_DOMAIN__": options.domain,
|
|
202
|
+
"__PIPELINE_REPO__": options.repo,
|
|
203
|
+
"__PIPELINES_DEFAULT__": options.pipelines.join(","),
|
|
204
|
+
"__ENABLE_EXPO_SITE__": options.withExpo ? "true" : "false",
|
|
205
|
+
"__INFRA_PATH__": options.infraPath,
|
|
206
|
+
"__PIPELINE_STAGE_MAP__": buildMapEntries(options, "stage"),
|
|
207
|
+
"__PIPELINE_REPO_MAP__": buildMapEntries(options, "repo"),
|
|
208
|
+
"__PIPELINE_BRANCH_MAP__": buildMapEntries(options, "branch"),
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
function main() {
|
|
212
|
+
const parsed = parseArgs(process.argv.slice(2));
|
|
213
|
+
if (!parsed.command || parsed.command === "help" || parsed.flags.help) {
|
|
214
|
+
printHelp();
|
|
215
|
+
process.exit(0);
|
|
216
|
+
}
|
|
217
|
+
if (parsed.command !== "init") {
|
|
218
|
+
console.error(`Unknown command: ${parsed.command}`);
|
|
219
|
+
printHelp();
|
|
220
|
+
process.exit(1);
|
|
221
|
+
}
|
|
222
|
+
const providerRaw = readFlag(parsed.flags, "provider", "aws").toLowerCase();
|
|
223
|
+
if (providerRaw !== "aws") {
|
|
224
|
+
console.error(`Unsupported provider: ${providerRaw}. v1.0.0 currently supports only aws.`);
|
|
225
|
+
process.exit(1);
|
|
226
|
+
}
|
|
227
|
+
const project = toSlug(readFlag(parsed.flags, "project", "myapp"));
|
|
228
|
+
const appName = readFlag(parsed.flags, "app-name", project);
|
|
229
|
+
const domain = readFlag(parsed.flags, "domain", "example.com");
|
|
230
|
+
const repo = readFlag(parsed.flags, "repo", "myorg/myrepo");
|
|
231
|
+
const infraPath = readFlag(parsed.flags, "infra-path", "packages/infra");
|
|
232
|
+
const withExpo = readBool(parsed.flags, "with-expo", false);
|
|
233
|
+
const force = readBool(parsed.flags, "force", false);
|
|
234
|
+
const branchProd = readFlag(parsed.flags, "branch-prod", PIPELINE_DEFS.production.defaultBranch);
|
|
235
|
+
const branchDev = readFlag(parsed.flags, "branch-dev", PIPELINE_DEFS.dev.defaultBranch);
|
|
236
|
+
const branchMobile = readFlag(parsed.flags, "branch-mobile", PIPELINE_DEFS.mobile.defaultBranch);
|
|
237
|
+
const pipelinesRaw = readFlag(parsed.flags, "pipelines", "production,dev");
|
|
238
|
+
let pipelines;
|
|
239
|
+
try {
|
|
240
|
+
pipelines = parsePipelines(pipelinesRaw);
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
244
|
+
process.exit(1);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const targetRaw = readFlag(parsed.flags, "target", ".");
|
|
248
|
+
const targetDir = resolve(process.cwd(), targetRaw);
|
|
249
|
+
const options = {
|
|
250
|
+
provider: "aws",
|
|
251
|
+
project,
|
|
252
|
+
domain,
|
|
253
|
+
repo,
|
|
254
|
+
pipelines,
|
|
255
|
+
withExpo,
|
|
256
|
+
appName,
|
|
257
|
+
infraPath,
|
|
258
|
+
targetDir,
|
|
259
|
+
force,
|
|
260
|
+
};
|
|
261
|
+
const replacements = buildReplacements(options);
|
|
262
|
+
replacements["__BRANCH_PROD__"] = branchProd;
|
|
263
|
+
replacements["__BRANCH_DEV__"] = branchDev;
|
|
264
|
+
replacements["__BRANCH_MOBILE__"] = branchMobile;
|
|
265
|
+
console.log("\n🚀 @lsts_tech/infra — initializing white-label AWS scaffolding\n");
|
|
266
|
+
console.log(` provider : ${options.provider}`);
|
|
267
|
+
console.log(` targetDir : ${options.targetDir}`);
|
|
268
|
+
console.log(` project : ${options.project}`);
|
|
269
|
+
console.log(` appName : ${options.appName}`);
|
|
270
|
+
console.log(` domain : ${options.domain}`);
|
|
271
|
+
console.log(` repo : ${options.repo}`);
|
|
272
|
+
console.log(` pipelines : ${options.pipelines.join(",") || "none"}`);
|
|
273
|
+
console.log(` expo site : ${options.withExpo ? "enabled" : "disabled"}`);
|
|
274
|
+
console.log("");
|
|
275
|
+
let created = 0;
|
|
276
|
+
let overwritten = 0;
|
|
277
|
+
let skipped = 0;
|
|
278
|
+
for (const file of FILES_TO_SCAFFOLD) {
|
|
279
|
+
const sourcePath = join(TEMPLATES_DIR, file.source);
|
|
280
|
+
const targetPath = join(options.targetDir, file.target);
|
|
281
|
+
const exists = existsSync(targetPath);
|
|
282
|
+
if (exists && !options.force) {
|
|
283
|
+
console.log(` ⏭ ${file.target} — already exists (skipped)`);
|
|
284
|
+
skipped++;
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
const targetParent = dirname(targetPath);
|
|
288
|
+
if (!existsSync(targetParent)) {
|
|
289
|
+
mkdirSync(targetParent, { recursive: true });
|
|
290
|
+
}
|
|
291
|
+
const raw = readFileSync(sourcePath, "utf-8");
|
|
292
|
+
const content = applyTemplate(raw, replacements);
|
|
293
|
+
writeFileSync(targetPath, content, "utf-8");
|
|
294
|
+
if (file.target.endsWith(".sh")) {
|
|
295
|
+
chmodSync(targetPath, 0o755);
|
|
296
|
+
}
|
|
297
|
+
if (exists) {
|
|
298
|
+
console.log(` ♻️ ${file.target} — ${file.description} (overwritten)`);
|
|
299
|
+
overwritten++;
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
console.log(` ✅ ${file.target} — ${file.description}`);
|
|
303
|
+
created++;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
console.log(`\n📦 Done! Created ${created}, overwritten ${overwritten}, skipped ${skipped}.\n`);
|
|
307
|
+
console.log("Next steps:");
|
|
308
|
+
console.log(" 1. Review .env.example and copy values into your deployment environment");
|
|
309
|
+
console.log(" 2. Set your SST secrets (npx sst secrets set <Name> <value> --stage <stage>)");
|
|
310
|
+
console.log(" 3. Run your first deploy (npx sst deploy --stage dev)");
|
|
311
|
+
console.log(" 4. Optionally ensure pipelines (APPROVE=true bash scripts/ensure-pipelines.sh)");
|
|
312
|
+
console.log("");
|
|
313
|
+
}
|
|
314
|
+
main();
|
|
315
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../bin/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dns — Reusable DNS & Domain Configuration
|
|
3
|
+
*
|
|
4
|
+
* Provides stage-aware domain resolution for SST deployments.
|
|
5
|
+
* Maps deployment stages to subdomains and handles Route 53 + ACM configuration.
|
|
6
|
+
*
|
|
7
|
+
* Design:
|
|
8
|
+
* - SST v3's `sst.aws.Nextjs` handles ACM certificate provisioning automatically
|
|
9
|
+
* when a `domain` is provided — it creates the cert in us-east-1 for CloudFront.
|
|
10
|
+
* - Route 53 hosted zone must already exist for the root domain.
|
|
11
|
+
* - This module only resolves the correct domain string per stage.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const domain = resolveDomain({
|
|
16
|
+
* rootDomain: "example.com",
|
|
17
|
+
* stage: "dev",
|
|
18
|
+
* });
|
|
19
|
+
* // → "dev.example.com"
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export interface DnsConfig {
|
|
23
|
+
/**
|
|
24
|
+
* The root domain name managed in Route 53.
|
|
25
|
+
* @example "example.com"
|
|
26
|
+
*/
|
|
27
|
+
rootDomain: string;
|
|
28
|
+
/**
|
|
29
|
+
* The current SST stage name.
|
|
30
|
+
* @example "production" | "dev" | "staging"
|
|
31
|
+
*/
|
|
32
|
+
stage: string;
|
|
33
|
+
/**
|
|
34
|
+
* Optional stage-to-domain mapping overrides.
|
|
35
|
+
* If not provided, uses sensible defaults:
|
|
36
|
+
* - "production" → rootDomain (e.g., "example.com")
|
|
37
|
+
* - any other stage → "{stage}.{rootDomain}" (e.g., "dev.example.com")
|
|
38
|
+
*/
|
|
39
|
+
stageMap?: Record<string, string>;
|
|
40
|
+
/**
|
|
41
|
+
* Whether to add a www redirect for the production domain.
|
|
42
|
+
* @default true
|
|
43
|
+
*/
|
|
44
|
+
wwwRedirect?: boolean;
|
|
45
|
+
}
|
|
46
|
+
export interface DomainResult {
|
|
47
|
+
/**
|
|
48
|
+
* The resolved domain configuration for sst.aws.Nextjs.
|
|
49
|
+
* Can be passed directly to the `domain` prop.
|
|
50
|
+
*/
|
|
51
|
+
domain: {
|
|
52
|
+
name: string;
|
|
53
|
+
redirects?: string[];
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* The final domain name string for logging/reference.
|
|
57
|
+
*/
|
|
58
|
+
domainName: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Resolves the domain configuration for a given stage.
|
|
62
|
+
*
|
|
63
|
+
* Rules:
|
|
64
|
+
* 1. "production" stage → root domain + optional www redirect
|
|
65
|
+
* 2. Any other stage → {stage}.{rootDomain} as a subdomain
|
|
66
|
+
* 3. Custom stageMap overrides take priority
|
|
67
|
+
*/
|
|
68
|
+
export declare function resolveDomain(config: DnsConfig): DomainResult;
|
|
69
|
+
//# sourceMappingURL=Dns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dns.d.ts","sourceRoot":"","sources":["../../stacks/Dns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,WAAW,SAAS;IACxB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAElC;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;KACtB,CAAC;IAEF;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,YAAY,CAkC7D"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dns — Reusable DNS & Domain Configuration
|
|
3
|
+
*
|
|
4
|
+
* Provides stage-aware domain resolution for SST deployments.
|
|
5
|
+
* Maps deployment stages to subdomains and handles Route 53 + ACM configuration.
|
|
6
|
+
*
|
|
7
|
+
* Design:
|
|
8
|
+
* - SST v3's `sst.aws.Nextjs` handles ACM certificate provisioning automatically
|
|
9
|
+
* when a `domain` is provided — it creates the cert in us-east-1 for CloudFront.
|
|
10
|
+
* - Route 53 hosted zone must already exist for the root domain.
|
|
11
|
+
* - This module only resolves the correct domain string per stage.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const domain = resolveDomain({
|
|
16
|
+
* rootDomain: "example.com",
|
|
17
|
+
* stage: "dev",
|
|
18
|
+
* });
|
|
19
|
+
* // → "dev.example.com"
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Resolves the domain configuration for a given stage.
|
|
24
|
+
*
|
|
25
|
+
* Rules:
|
|
26
|
+
* 1. "production" stage → root domain + optional www redirect
|
|
27
|
+
* 2. Any other stage → {stage}.{rootDomain} as a subdomain
|
|
28
|
+
* 3. Custom stageMap overrides take priority
|
|
29
|
+
*/
|
|
30
|
+
export function resolveDomain(config) {
|
|
31
|
+
const { rootDomain, stage, stageMap = {}, wwwRedirect = true, } = config;
|
|
32
|
+
// Check for custom stage mapping first
|
|
33
|
+
if (stageMap[stage]) {
|
|
34
|
+
return {
|
|
35
|
+
domain: { name: stageMap[stage] },
|
|
36
|
+
domainName: stageMap[stage],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
// Production stage → root domain
|
|
40
|
+
if (stage === "production") {
|
|
41
|
+
const redirects = wwwRedirect ? [`www.${rootDomain}`] : undefined;
|
|
42
|
+
return {
|
|
43
|
+
domain: {
|
|
44
|
+
name: rootDomain,
|
|
45
|
+
redirects,
|
|
46
|
+
},
|
|
47
|
+
domainName: rootDomain,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
// All other stages → subdomain
|
|
51
|
+
const subDomain = `${stage}.${rootDomain}`;
|
|
52
|
+
return {
|
|
53
|
+
domain: { name: subDomain },
|
|
54
|
+
domainName: subDomain,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=Dns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dns.js","sourceRoot":"","sources":["../../stacks/Dns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AA8CH;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,MAAiB;IAC7C,MAAM,EACJ,UAAU,EACV,KAAK,EACL,QAAQ,GAAG,EAAE,EACb,WAAW,GAAG,IAAI,GACnB,GAAG,MAAM,CAAC;IAEX,uCAAuC;IACvC,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO;YACL,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE;YACjC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC;SAC5B,CAAC;IACJ,CAAC;IAED,iCAAiC;IACjC,IAAI,KAAK,KAAK,YAAY,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAClE,OAAO;YACL,MAAM,EAAE;gBACN,IAAI,EAAE,UAAU;gBAChB,SAAS;aACV;YACD,UAAU,EAAE,UAAU;SACvB,CAAC;IACJ,CAAC;IAED,+BAA+B;IAC/B,MAAM,SAAS,GAAG,GAAG,KAAK,IAAI,UAAU,EAAE,CAAC;IAC3C,OAAO;QACL,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;QAC3B,UAAU,EAAE,SAAS;KACtB,CAAC;AACJ,CAAC"}
|