generatesaas 0.1.0 → 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.
Files changed (3) hide show
  1. package/README.md +89 -0
  2. package/dist/index.js +1 -1
  3. package/package.json +33 -34
package/README.md ADDED
@@ -0,0 +1,89 @@
1
+ # generatesaas
2
+
3
+ CLI for scaffolding and managing [GenerateSaaS](https://generatesaas.com) projects.
4
+
5
+ ## Requirements
6
+
7
+ - Node.js >= 22
8
+ - A valid GenerateSaaS API key
9
+
10
+ ## Quick Start
11
+
12
+ ```bash
13
+ npx generatesaas init
14
+ ```
15
+
16
+ Or install globally:
17
+
18
+ ```bash
19
+ npm i -g generatesaas
20
+ generatesaas init
21
+ ```
22
+
23
+ ## Commands
24
+
25
+ ### `generatesaas init`
26
+
27
+ Scaffold a new project. Prompts for configuration interactively, or pass flags for non-interactive use.
28
+
29
+ ```bash
30
+ # Interactive
31
+ generatesaas init
32
+
33
+ # Non-interactive with defaults
34
+ generatesaas init -n my-app --yes
35
+
36
+ # Fully customized
37
+ generatesaas init -n my-app --payment stripe --database neon --deploy cloudflare --yes
38
+ ```
39
+
40
+ **Flags:**
41
+
42
+ | Flag | Description |
43
+ |---|---|
44
+ | `-n, --name <name>` | Project name |
45
+ | `-l, --location <path>` | Project directory (default: `./{name}`) |
46
+ | `--architecture <type>` | `fullstack` or `separate` |
47
+ | `--payment <provider>` | `stripe`, `polar`, or `none` |
48
+ | `--email <provider>` | `smtp`, `ses`, or `resend` |
49
+ | `--org` / `--no-org` | Enable/disable multi-tenancy |
50
+ | `--billing-scope <scope>` | `user` or `organization` |
51
+ | `--blog` / `--no-blog` | Enable/disable blog |
52
+ | `--deploy <target>` | `node`, `cloudflare`, `vercel`, or `netlify` |
53
+ | `--database <provider>` | `postgres`, `neon`, or `supabase` |
54
+ | `--cache <provider>` | `redis` or `upstash` |
55
+ | `--docker <services>` | Comma-separated: `postgres`, `redis`, `inngest`, `mailpit` |
56
+ | `--ai-tools <tools>` | Comma-separated: `claude-code`, `cursor`, `codex`, `gemini-cli`, `windsurf` |
57
+ | `--currency <code>` | Default billing currency (`USD`, `EUR`, `GBP`, `CAD`, `AUD`, `BRL`, `JPY`) |
58
+ | `-y, --yes` | Accept defaults for all unspecified options |
59
+
60
+ ### `generatesaas update`
61
+
62
+ Check for template updates and refresh AI coding skill files.
63
+
64
+ ```bash
65
+ generatesaas update
66
+ ```
67
+
68
+ If a newer version is available, it stages the update for your AI assistant to apply.
69
+
70
+ ### `generatesaas status`
71
+
72
+ Show current project version and check for updates.
73
+
74
+ ```bash
75
+ generatesaas status
76
+ ```
77
+
78
+ ### `generatesaas verify`
79
+
80
+ Verify a deployed GenerateSaaS license.
81
+
82
+ ```bash
83
+ generatesaas verify https://example.com/api
84
+ generatesaas verify --file urls.txt
85
+ ```
86
+
87
+ ## License
88
+
89
+ Proprietary. See [generatesaas.com](https://generatesaas.com) for licensing details.
package/dist/index.js CHANGED
@@ -548,4 +548,4 @@ ${i}
548
548
  `)}finally{await Nr(S,{recursive:!0,force:!0})}o.stop("Baseline hashes computed.")}await p(W(r,$e),JSON.stringify({currentVersion:i.version,targetVersion:d.latest,changelog:G,stagedAt:new Date().toISOString()},null," ")+`
549
549
  `),w.log.info(`Update staged: ${ge.cyan(i.version)} \u2192 ${ge.cyan(d.latest)}`),w.log.info("Ask your AI assistant to "+ge.cyan("'update my GenerateSaaS project'")+".")}catch(a){o.stop("Failed."),w.cancel(`Update failed: ${E(a)}`),process.exit(1)}})}import*as v from"@clack/prompts";import B from"picocolors";import{readFile as Fr}from"fs/promises";import{join as Br,resolve as Gr}from"path";function wt(e){e.command("status").description("Show project status and check for updates").option("--cwd <path>","project directory (default: current directory)").action(async t=>{let r=Gr(t.cwd??process.cwd()),n=Br(r,z),i;try{i=JSON.parse(await Fr(n,"utf-8"))}catch{v.cancel(".generatesaas/manifest.json not found. Run this from a GenerateSaaS project."),process.exit(1)}v.log.info(`${B.bold("Project Status")}`),v.log.info(` Version: ${B.cyan(i.version)}`),v.log.info(` Frontend: ${B.cyan(i.frontend)}`);let o=v.spinner();o.start("Checking for updates...");try{let a=await q(),l=K(a),u=(await Y(l)).latest;i.version===u?(o.stop("Up to date."),v.log.success(`Already on the latest version (${B.green(u)})`)):(o.stop("Update available."),v.log.warning(`Update available: ${B.yellow(i.version)} \u2192 ${B.green(u)}`),v.log.info(`Run ${B.cyan("generatesaas update")} to update skill files, then ask your AI assistant to apply the update.`))}catch(a){o.stop("Check failed."),a instanceof R&&a.status===401?v.log.warning("Invalid API key. Check your key and try again."):v.log.warning(`Could not check for updates: ${E(a)}`)}})}import{readFile as Hr}from"fs/promises";import*as I from"@clack/prompts";import _ from"picocolors";function zr(e){let t=e.split(".");if(t.length!==3||!t[1])throw new Error("Invalid JWT format");let r=Buffer.from(t[1],"base64url").toString("utf-8");return JSON.parse(r)}function Pe(e){return typeof e!="number"?"unknown":new Date(e*1e3).toISOString().split("T")[0]}function It(e){I.note([`License ID: ${_.cyan(String(e.lid??"unknown"))}`,`Version: ${_.cyan(String(e.ver??"unknown"))}`,`Init version: ${String(e.iver??"unknown")}`,`Frontend: ${String(e.fe??"unknown")}`,`Created: ${Pe(e.pat)}`,`Last updated: ${Pe(e.uat)}`,`Expires: ${Pe(e.exp)}`,`Install ID: ${String(e.nid??"unknown")}`].join(`
550
550
  `),_.magenta("License Details"))}async function Et(e){let t=I.spinner(),r=e.replace(/\/+$/,"");t.start(`Checking ${r}/license...`);let n;try{let o=await fetch(`${r}/license`);if(!o.ok)return t.stop(`${_.red("Not found")} \u2014 ${r}/license returned ${o.status}`),!1;if(n=await o.text(),!n||n.split(".").length!==3)return t.stop(`${_.red("Invalid")} \u2014 response is not a JWT`),!1;t.stop(`${_.green("Found")} \u2014 license endpoint responded`)}catch(o){return t.stop(`${_.red("Failed")} \u2014 ${E(o)}`),!1}let i;try{i=zr(n)}catch{return I.log.error("Could not decode JWT payload."),!1}t.start("Verifying signature...");try{let o=process.env.GENERATESAAS_API_URL??ce,a=await Fe(o,n);if(a.valid)t.stop(`${_.green("Valid")} \u2014 signature verified`);else return t.stop(`${_.red("Invalid")} \u2014 ${a.reason}`),!1}catch{return t.stop(`${_.yellow("Skipped")} \u2014 could not reach verification service`),I.log.warn("Signature not verified. Displaying unverified claims:"),It(i),!1}return It(i),!0}function bt(e){e.command("verify").description("Verify a GenerateSaaS license on a deployed site").argument("[url]","URL of the site to verify (e.g. https://example.com/api)").option("--file <path>","file with URLs to check, one per line").action(async(t,r)=>{if(!t&&!r.file&&(I.cancel("Provide a URL or --file <path>."),process.exit(1)),r.file){let i=(await Hr(r.file,"utf-8")).split(`
551
- `).map(a=>a.trim()).filter(a=>a&&!a.startsWith("#"));i.length===0&&(I.cancel("No URLs found in file."),process.exit(1));let o=0;for(let a of i)await Et(a)&&o++,I.log.info("");I.log.success(`${o}/${i.length} sites verified.`)}else await Et(t)||process.exit(1)})}var X=new Kr().name("generatesaas").description("CLI for scaffolding and managing GenerateSaaS projects").version("0.1.0");vt(X);St(X);wt(X);bt(X);X.parseAsync().catch(e=>{At.cancel("An unexpected error occurred."),console.error(e),process.exit(1)});
551
+ `).map(a=>a.trim()).filter(a=>a&&!a.startsWith("#"));i.length===0&&(I.cancel("No URLs found in file."),process.exit(1));let o=0;for(let a of i)await Et(a)&&o++,I.log.info("");I.log.success(`${o}/${i.length} sites verified.`)}else await Et(t)||process.exit(1)})}var X=new Kr().name("generatesaas").description("CLI for scaffolding and managing GenerateSaaS projects").version("0.2.0");vt(X);St(X);wt(X);bt(X);X.parseAsync().catch(e=>{At.cancel("An unexpected error occurred."),console.error(e),process.exit(1)});
package/package.json CHANGED
@@ -1,35 +1,34 @@
1
1
  {
2
- "name": "generatesaas",
3
- "version": "0.1.0",
4
- "type": "module",
5
- "description": "CLI for scaffolding and managing GenerateSaaS projects",
6
- "bin": {
7
- "generatesaas": "./dist/index.js"
8
- },
9
- "files": [
10
- "dist"
11
- ],
12
- "scripts": {
13
- "build": "tsup",
14
- "postbuild": "rm -rf dist/skill/content && mkdir -p dist/skill && cp -r src/skill/content dist/skill/content",
15
- "dev": "tsup --watch",
16
- "check-types": "tsc --noEmit",
17
- "test": "vitest run",
18
- "prepublishOnly": "pnpm run build"
19
- },
20
- "dependencies": {
21
- "@clack/prompts": "^1.1.0",
22
- "commander": "^14.0.3",
23
- "picocolors": "^1.1.1",
24
- "tar": "^7.5.11"
25
- },
26
- "devDependencies": {
27
- "@repo/tsconfig": "workspace:*",
28
- "tsup": "^8.5.1",
29
- "typescript": "^5.9.3",
30
- "vitest": "^4.1.0"
31
- },
32
- "engines": {
33
- "node": ">=22"
34
- }
35
- }
2
+ "name": "generatesaas",
3
+ "version": "0.2.0",
4
+ "type": "module",
5
+ "description": "CLI for scaffolding and managing GenerateSaaS projects",
6
+ "bin": {
7
+ "generatesaas": "./dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "dependencies": {
13
+ "@clack/prompts": "^1.1.0",
14
+ "commander": "^14.0.3",
15
+ "picocolors": "^1.1.1",
16
+ "tar": "^7.5.11"
17
+ },
18
+ "devDependencies": {
19
+ "tsup": "^8.5.1",
20
+ "typescript": "^5.9.3",
21
+ "vitest": "^4.1.0",
22
+ "@repo/tsconfig": "1.0.0"
23
+ },
24
+ "engines": {
25
+ "node": ">=22"
26
+ },
27
+ "scripts": {
28
+ "build": "tsup",
29
+ "postbuild": "rm -rf dist/skill/content && mkdir -p dist/skill && cp -r src/skill/content dist/skill/content",
30
+ "dev": "tsup --watch",
31
+ "check-types": "tsc --noEmit",
32
+ "test": "vitest run"
33
+ }
34
+ }