create-step-func-emailer 0.2.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.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ /* eslint-disable no-console */
38
+ const fs = __importStar(require("node:fs"));
39
+ const path = __importStar(require("node:path"));
40
+ const node_child_process_1 = require("node:child_process");
41
+ const projectName = process.argv[2];
42
+ if (!projectName) {
43
+ console.error("Usage: npx create-step-func-emailer <project-name>");
44
+ process.exit(1);
45
+ }
46
+ const targetDir = path.resolve(process.cwd(), projectName);
47
+ if (fs.existsSync(targetDir)) {
48
+ console.error(`Directory ${projectName} already exists.`);
49
+ process.exit(1);
50
+ }
51
+ const templateDir = path.join(__dirname, "../template");
52
+ function copyDir(src, dest) {
53
+ fs.mkdirSync(dest, { recursive: true });
54
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
55
+ const srcPath = path.join(src, entry.name);
56
+ // Rename _gitignore → .gitignore (npm strips dotfiles)
57
+ const destName = entry.name === "_gitignore" ? ".gitignore" : entry.name;
58
+ const destPath = path.join(dest, destName);
59
+ if (entry.isDirectory()) {
60
+ copyDir(srcPath, destPath);
61
+ }
62
+ else {
63
+ fs.copyFileSync(srcPath, destPath);
64
+ }
65
+ }
66
+ }
67
+ console.log(`Creating ${projectName}...`);
68
+ copyDir(templateDir, targetDir);
69
+ // Install dependencies
70
+ console.log("\nInstalling dependencies...");
71
+ try {
72
+ (0, node_child_process_1.execSync)("pnpm install", { cwd: targetDir, stdio: "inherit" });
73
+ }
74
+ catch {
75
+ console.log("pnpm not found, trying npm...");
76
+ (0, node_child_process_1.execSync)("npm install", { cwd: targetDir, stdio: "inherit" });
77
+ }
78
+ // Git init + initial commit
79
+ console.log("\nInitializing git repository...");
80
+ (0, node_child_process_1.execSync)("git init", { cwd: targetDir, stdio: "inherit" });
81
+ (0, node_child_process_1.execSync)("git add -A", { cwd: targetDir, stdio: "inherit" });
82
+ (0, node_child_process_1.execSync)('git commit -m "Initial project scaffold"', {
83
+ cwd: targetDir,
84
+ stdio: "inherit",
85
+ });
86
+ console.log(`
87
+ Done! Created ${projectName}
88
+
89
+ Next steps:
90
+ cd ${projectName}
91
+ claude # Open Claude Code
92
+ /setup-env # Configure AWS environment
93
+ /create-sequence # Create your first email sequence
94
+ /deploy # Deploy to AWS
95
+ `);
96
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "create-step-func-emailer",
3
+ "version": "0.2.0",
4
+ "description": "Create a new step-func-emailer project",
5
+ "license": "MIT",
6
+ "type": "commonjs",
7
+ "bin": {
8
+ "create-step-func-emailer": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "template"
13
+ ],
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/mdwt/step-func-emailer.git",
20
+ "directory": "packages/create"
21
+ },
22
+ "devDependencies": {
23
+ "typescript": "^5.9.0"
24
+ },
25
+ "scripts": {
26
+ "build": "tsc",
27
+ "typecheck": "tsc --noEmit"
28
+ }
29
+ }
@@ -0,0 +1,15 @@
1
+ AWS_PROFILE=default
2
+ ACCOUNT=123456789012
3
+ REGION=us-east-1
4
+ STACK_NAME=StepFuncEmailer
5
+ TABLE_NAME=StepFuncEmailer
6
+ EVENTS_TABLE_NAME=StepFuncEmailer-events
7
+ TEMPLATE_BUCKET_NAME=step-func-emailer-templates-mycompany
8
+ EVENT_BUS_NAME=step-func-emailer-bus
9
+ SES_CONFIG_SET_NAME=step-func-emailer-config
10
+ SNS_TOPIC_NAME=step-func-emailer-ses-notifications
11
+ DEFAULT_FROM_EMAIL=hello@example.com
12
+ DEFAULT_FROM_NAME=MyCompany
13
+ REPLY_TO_EMAIL=support@example.com
14
+ UNSUBSCRIBE_SECRET=replace-with-a-real-secret
15
+ SSM_PREFIX=/step-func-emailer
@@ -0,0 +1,17 @@
1
+ # Email Sequences Project
2
+
3
+ Built with [step-func-emailer](https://github.com/mdwt/step-func-emailer).
4
+
5
+ ## Commands
6
+
7
+ - `pnpm build` — build all sequences
8
+ - `pnpm deploy` — deploy to AWS
9
+ - `/create-sequence` — create a new email sequence
10
+ - `/setup-env` — configure AWS environment
11
+ - `/deploy` — build and deploy
12
+
13
+ ## Structure
14
+
15
+ - `sequences/` — email sequences (auto-discovered by CDK)
16
+ - `bin/app.ts` — CDK entry point
17
+ - `.env` — AWS configuration
@@ -0,0 +1,10 @@
1
+ node_modules/
2
+ dist/
3
+ build/
4
+ cdk.out/
5
+ .env
6
+ *.js
7
+ *.d.ts
8
+ *.js.map
9
+ *.d.ts.map
10
+ !bin/app.ts
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env node
2
+ import "source-map-support/register";
3
+ import * as path from "node:path";
4
+ import * as fs from "node:fs";
5
+ import * as cdk from "aws-cdk-lib";
6
+ import type { StepFuncEmailerConfig } from "@step-func-emailer/shared";
7
+ import { StepFuncEmailerStack } from "@step-func-emailer/cdk";
8
+ import { loadSequenceConfigs } from "@step-func-emailer/cdk/load-sequences";
9
+
10
+ // Load .env from project root
11
+ const envPath = path.join(__dirname, "../.env");
12
+ if (fs.existsSync(envPath)) {
13
+ for (const line of fs.readFileSync(envPath, "utf-8").split("\n")) {
14
+ const trimmed = line.trim();
15
+ if (!trimmed || trimmed.startsWith("#")) continue;
16
+ const idx = trimmed.indexOf("=");
17
+ if (idx === -1) continue;
18
+ const key = trimmed.slice(0, idx);
19
+ const value = trimmed.slice(idx + 1);
20
+ if (!(key in process.env)) process.env[key] = value;
21
+ }
22
+ }
23
+
24
+ function required(name: string): string {
25
+ const val = process.env[name];
26
+ if (!val) throw new Error(`Missing env var ${name}. Run /setup-env in Claude Code.`);
27
+ return val;
28
+ }
29
+
30
+ const config: StepFuncEmailerConfig = {
31
+ account: required("ACCOUNT"),
32
+ region: required("REGION"),
33
+ stackName: required("STACK_NAME"),
34
+ tableName: required("TABLE_NAME"),
35
+ eventsTableName: required("EVENTS_TABLE_NAME"),
36
+ templateBucketName: required("TEMPLATE_BUCKET_NAME"),
37
+ eventBusName: required("EVENT_BUS_NAME"),
38
+ sesConfigSetName: required("SES_CONFIG_SET_NAME"),
39
+ snsTopicName: required("SNS_TOPIC_NAME"),
40
+ defaultFromEmail: required("DEFAULT_FROM_EMAIL"),
41
+ defaultFromName: required("DEFAULT_FROM_NAME"),
42
+ replyToEmail: process.env.REPLY_TO_EMAIL || undefined,
43
+ unsubscribeSecret: required("UNSUBSCRIBE_SECRET"),
44
+ ssmPrefix: required("SSM_PREFIX"),
45
+ };
46
+
47
+ const definitions = loadSequenceConfigs();
48
+ const app = new cdk.App();
49
+ new StepFuncEmailerStack(app, config.stackName, {
50
+ env: { account: config.account, region: config.region },
51
+ config,
52
+ definitions,
53
+ });
@@ -0,0 +1 @@
1
+ { "app": "npx tsx bin/app.ts" }
@@ -0,0 +1,19 @@
1
+ {
2
+ "private": true,
3
+ "scripts": {
4
+ "build": "pnpm -r build",
5
+ "synth": "npx cdk synth",
6
+ "deploy": "npx cdk deploy --require-approval never",
7
+ "typecheck": "pnpm -r typecheck"
8
+ },
9
+ "devDependencies": {
10
+ "@step-func-emailer/cdk": "^0.1.0",
11
+ "@step-func-emailer/shared": "^0.1.0",
12
+ "aws-cdk": "^2.1111.0",
13
+ "aws-cdk-lib": "^2.243.0",
14
+ "constructs": "^10.5.1",
15
+ "source-map-support": "^0.5.21",
16
+ "tsx": "^4.21.0",
17
+ "typescript": "^5.9.0"
18
+ }
19
+ }
@@ -0,0 +1,2 @@
1
+ packages:
2
+ - sequences/*
File without changes
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "Node16",
5
+ "moduleResolution": "Node16",
6
+ "lib": ["ES2022"],
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+ "skipLibCheck": true,
10
+ "forceConsistentCasingInFileNames": true,
11
+ "resolveJsonModule": true,
12
+ "declaration": true,
13
+ "declarationMap": true,
14
+ "sourceMap": true,
15
+ "outDir": "dist",
16
+ "rootDir": "src"
17
+ }
18
+ }