anhedral 0.1.1 → 0.1.4

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/dist/index.js CHANGED
@@ -1,137 +1,7 @@
1
1
  #!/usr/bin/env tsx
2
- import path from 'node:path';
3
- import { argv, env, exit } from 'node:process';
4
- import { STACK_IDS, scaffoldProject } from './scaffold.js';
5
- import { TOOLCHAIN_CHANNELS, resolveToolchainChannel } from './toolchain.js';
6
- const USAGE = `
7
- anhedral init <next|next-fullstack|expo-fullstack|backend> [--toolchain <latest|stable>]
8
-
9
- Commands:
10
- anhedral init next
11
- Next.js App Router, shadcn/ui, Tailwind CSS, TypeScript, Drizzle ORM, Neon Postgres, Clerk Auth, Stripe, Cloudflare R2
12
-
13
- anhedral init next-fullstack
14
- Next.js App Router, shadcn/ui, Tailwind CSS, TypeScript, Fastify, Drizzle ORM, Neon Postgres, Clerk Auth, Stripe, Cloudflare R2
15
-
16
- anhedral init expo-fullstack
17
- Expo, NativeWind/Tailwind CSS, TypeScript, Fastify, Drizzle ORM, Neon Postgres, Clerk Auth, RevenueCat + Stripe, Cloudflare R2
18
-
19
- anhedral init backend
20
- Fastify, TypeScript, Drizzle ORM, Neon Postgres, Clerk Auth or Better Auth, Stripe-ready integrations, Cloudflare R2
21
- `;
22
- function parseCli(args) {
23
- const flags = {};
24
- for (let index = 0; index < args.length; index += 1) {
25
- const token = args[index];
26
- if (!token.startsWith('--')) {
27
- if (flags.stack != null) {
28
- throw new Error(`Unknown flag: ${token}`);
29
- }
30
- flags.stack = token;
31
- continue;
32
- }
33
- if (token === '--toolchain') {
34
- const value = args[index + 1];
35
- if (!value || value.startsWith('--')) {
36
- throw new Error('Missing value for --toolchain');
37
- }
38
- flags.toolchain = value;
39
- index += 1;
40
- continue;
41
- }
42
- throw new Error(`Unknown flag: ${token}`);
43
- }
44
- if (!flags.stack) {
45
- throw new Error(`Missing stack. Choose one of: ${STACK_IDS.join(', ')}`);
46
- }
47
- return flags;
48
- }
49
- function resolveMode(flags) {
50
- if (!STACK_IDS.includes(flags.stack)) {
51
- throw new Error(`Unknown stack: ${flags.stack}. Choose one of: ${STACK_IDS.join(', ')}`);
52
- }
53
- return flags.stack;
54
- }
55
- function deriveProjectName(cwd) {
56
- const base = path.basename(cwd);
57
- const sanitized = base
58
- .trim()
59
- .toLowerCase()
60
- .replace(/[^a-z0-9_-]+/g, '-')
61
- .replace(/^-+|-+$/g, '');
62
- return sanitized || 'anhedral-app';
63
- }
64
- function deriveDisplayName(cwd) {
65
- const base = path.basename(cwd).trim();
66
- return base || 'Anhedral App';
67
- }
68
- function buildOptions(flags) {
69
- const cwd = process.cwd();
70
- const mode = resolveMode(flags);
71
- const projectName = deriveProjectName(cwd);
72
- const displayName = deriveDisplayName(cwd);
73
- if (flags.toolchain != null && !TOOLCHAIN_CHANNELS.includes(flags.toolchain)) {
74
- throw new Error(`--toolchain must be one of: ${TOOLCHAIN_CHANNELS.join(', ')}`);
75
- }
76
- switch (mode) {
77
- case 'next':
78
- return {
79
- mode,
80
- projectName,
81
- displayName,
82
- auth: 'clerk',
83
- payments: 'stripe',
84
- db: 'neon',
85
- orm: 'drizzle',
86
- storage: 'r2',
87
- api: null,
88
- monorepo: false,
89
- toolchainChannel: resolveToolchainChannel(flags.toolchain ?? env.ANHEDRAL_TOOLCHAIN),
90
- };
91
- case 'next-fullstack':
92
- return {
93
- mode,
94
- projectName,
95
- displayName,
96
- auth: 'clerk',
97
- payments: 'stripe',
98
- db: 'neon',
99
- orm: 'drizzle',
100
- storage: 'r2',
101
- api: 'fastify',
102
- monorepo: true,
103
- toolchainChannel: resolveToolchainChannel(flags.toolchain ?? env.ANHEDRAL_TOOLCHAIN),
104
- };
105
- case 'expo-fullstack':
106
- return {
107
- mode,
108
- projectName,
109
- displayName,
110
- auth: 'clerk',
111
- payments: 'revenuecat',
112
- db: 'neon',
113
- orm: 'drizzle',
114
- storage: 'r2',
115
- api: 'fastify',
116
- monorepo: true,
117
- toolchainChannel: resolveToolchainChannel(flags.toolchain ?? env.ANHEDRAL_TOOLCHAIN),
118
- };
119
- case 'backend':
120
- return {
121
- mode,
122
- projectName,
123
- displayName,
124
- auth: 'betterauth',
125
- payments: 'none',
126
- db: 'neon',
127
- orm: 'drizzle',
128
- storage: 'r2',
129
- api: 'fastify',
130
- monorepo: false,
131
- toolchainChannel: resolveToolchainChannel(flags.toolchain ?? env.ANHEDRAL_TOOLCHAIN),
132
- };
133
- }
134
- }
2
+ import { argv, exit } from 'node:process';
3
+ import { buildOptions, parseCli, USAGE } from './cli.js';
4
+ import { scaffoldProject } from './scaffold.js';
135
5
  async function main() {
136
6
  const args = argv.slice(2);
137
7
  const command = args[0];
@@ -144,8 +14,12 @@ async function main() {
144
14
  console.log(USAGE);
145
15
  exit(1);
146
16
  }
17
+ const rawArgs = args.slice(1);
18
+ if (rawArgs.includes('--help') || rawArgs.includes('-h')) {
19
+ console.log(USAGE);
20
+ exit(0);
21
+ }
147
22
  try {
148
- const rawArgs = args.slice(1);
149
23
  const options = buildOptions(parseCli(rawArgs));
150
24
  await scaffoldProject(options);
151
25
  }
@@ -0,0 +1,8 @@
1
+ export declare const anhedralPrint: {
2
+ banner(message: string): void;
3
+ section(message: string): void;
4
+ step(message: string): void;
5
+ done(message: string): void;
6
+ info(message: string): void;
7
+ fail(message: string): void;
8
+ };
package/dist/print.js ADDED
@@ -0,0 +1,33 @@
1
+ import { stdout } from 'node:process';
2
+ const USE_COLOR = Boolean(stdout.isTTY) && process.env.NO_COLOR == null;
3
+ function paint(code, message) {
4
+ if (!USE_COLOR)
5
+ return message;
6
+ return `\x1b[${code}m${message}\x1b[0m`;
7
+ }
8
+ const dim = (value) => paint('2', value);
9
+ const bold = (value) => paint('1', value);
10
+ const cyan = (value) => paint('36', value);
11
+ const green = (value) => paint('32', value);
12
+ const red = (value) => paint('31', value);
13
+ const magenta = (value) => paint('35', value);
14
+ export const anhedralPrint = {
15
+ banner(message) {
16
+ console.log(`${bold(magenta('>'))} ${bold(message)}\n`);
17
+ },
18
+ section(message) {
19
+ console.log(`\n${cyan('==')} ${bold(message)}`);
20
+ },
21
+ step(message) {
22
+ console.log(` ${cyan('>')} ${message}`);
23
+ },
24
+ done(message) {
25
+ console.log(` ${green('ok')} ${message}`);
26
+ },
27
+ info(message) {
28
+ console.log(` ${dim(message)}`);
29
+ },
30
+ fail(message) {
31
+ console.log(` ${red('x')} ${message}`);
32
+ },
33
+ };
@@ -1,10 +1,8 @@
1
1
  import { type ToolchainChannel } from './toolchain.js';
2
- export declare const STACK_IDS: readonly ["next", "next-fullstack", "expo-fullstack", "backend"];
3
- export type InitMode = (typeof STACK_IDS)[number];
4
- export type AuthMode = 'clerk' | 'betterauth';
5
- export type PaymentsMode = 'none' | 'stripe' | 'revenuecat';
2
+ export type FrontendMode = 'expo';
3
+ export type AuthMode = 'clerk';
4
+ export type PaymentsMode = 'revenuecat_stripe';
6
5
  export interface InitOptions {
7
- mode: InitMode;
8
6
  projectName: string;
9
7
  displayName: string;
10
8
  auth: AuthMode;
@@ -12,8 +10,8 @@ export interface InitOptions {
12
10
  db: 'neon';
13
11
  orm: 'drizzle';
14
12
  storage: 'r2';
15
- api: 'fastify' | null;
16
- monorepo: boolean;
13
+ api: 'fastify';
14
+ skipInstall: boolean;
17
15
  toolchainChannel: ToolchainChannel;
18
16
  }
19
17
  export interface ProjectOptions {
@@ -21,5 +19,6 @@ export interface ProjectOptions {
21
19
  displayName: string;
22
20
  githubOrg: string | null;
23
21
  frontendUrl?: string;
22
+ skipInstall?: boolean;
24
23
  }
25
24
  export declare function scaffoldProject(options: InitOptions): Promise<void>;