@revstackhq/cli 0.0.0-dev-20260226064743 → 0.0.0-dev-20260227092523
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/.turbo/turbo-build.log +42 -30
- package/CHANGELOG.md +6 -0
- package/README.md +58 -38
- package/dist/cli.js +298 -37
- package/dist/cli.js.map +1 -1
- package/dist/commands/init.js +266 -37
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/push.js +32 -0
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/templates/b2b-saas.d.ts +5 -0
- package/dist/commands/templates/b2b-saas.js +104 -0
- package/dist/commands/templates/b2b-saas.js.map +1 -0
- package/dist/commands/templates/index.d.ts +5 -0
- package/dist/commands/templates/index.js +264 -0
- package/dist/commands/templates/index.js.map +1 -0
- package/dist/commands/templates/starter.d.ts +10 -0
- package/dist/commands/templates/starter.js +88 -0
- package/dist/commands/templates/starter.js.map +1 -0
- package/dist/commands/templates/usage-based.d.ts +5 -0
- package/dist/commands/templates/usage-based.js +75 -0
- package/dist/commands/templates/usage-based.js.map +1 -0
- package/package.json +3 -2
- package/src/commands/init.ts +42 -74
- package/src/commands/push.ts +39 -1
- package/src/commands/templates/b2b-saas.ts +99 -0
- package/src/commands/templates/index.ts +12 -0
- package/src/commands/templates/starter.ts +89 -0
- package/src/commands/templates/usage-based.ts +70 -0
- package/tests/integration/init.test.ts +12 -2
- package/tests/integration/push.test.ts +20 -4
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,36 +1,48 @@
|
|
|
1
|
-
[?9001h[?1004h[?25l[2J[m[2;1H> @revstackhq/cli@0.0.0-dev-
|
|
2
|
-
> tsup[5;1H]0;C:\WINDOWS\system32\cmd.exe[?25h[34mCLI [mBuilding entry: src/cli.ts, src/commands/init.ts, src/commands/login.ts, src/commands/logout.ts, src/commands/pull.ts, src/commands/push.ts, src/utils/auth.ts, src/utils/config-loader.ts
|
|
1
|
+
[?9001h[?1004h[?25l[2J[m[2;1H> @revstackhq/cli@0.0.0-dev-20260227092523 build C:\Users\flava\OneDrive\Desktop\Work\revstack-os\packages\cli
|
|
2
|
+
> tsup[5;1H]0;C:\WINDOWS\system32\cmd.exe[?25h[34mCLI [mBuilding entry: src/cli.ts, src/commands/init.ts, src/commands/login.ts, src/commands/logout.ts, src/commands/pull.ts, src/commands/push.ts, src/utils/auth.ts, src/utils/config-loader.ts, src/commands/templates/b2b-saas.ts, src/commands/templates/index.ts, src/commands/templates/starter.ts, src/commands/templates/usage-based.ts
|
|
3
3
|
[34mCLI [mUsing tsconfig: tsconfig.json[34m
|
|
4
4
|
CLI [mtsup v8.5.1[34m
|
|
5
|
-
CLI [mUsing tsup config: C:\Users\flava\OneDrive\Desktop\Work\revstack-os\packages\cli\tsup.config.ts
|
|
6
|
-
|
|
5
|
+
CLI [mUsing tsup config: C:\Users\flava\OneDrive\Desktop\Work\revstack-os\packages\cli\tsup.config.ts
|
|
6
|
+
[34mCLI [mTarget: node18
|
|
7
7
|
[34mCLI [mCleaning output folder
|
|
8
8
|
[34mESM [mBuild start
|
|
9
|
-
[32mESM [m[1mdist\cli.js
|
|
10
|
-
[32mESM [m[1mdist\commands\
|
|
11
|
-
[32mESM [m[1mdist\commands\login.js
|
|
12
|
-
[32mESM [m[1mdist\commands\init.js
|
|
13
|
-
[32mESM [m[1mdist\
|
|
14
|
-
[32mESM [m[1mdist\
|
|
15
|
-
[32mESM [m[1mdist\
|
|
16
|
-
[32mESM [m[1mdist\
|
|
17
|
-
[32mESM [m[1mdist\
|
|
18
|
-
[32mESM [m[1mdist\commands\
|
|
19
|
-
[32mESM [m[1mdist\commands\
|
|
20
|
-
[32mESM [m[1mdist\commands\
|
|
21
|
-
[32mESM [m[1mdist\
|
|
22
|
-
[32mESM [m[1mdist\
|
|
23
|
-
[32mESM [m[1mdist\commands\
|
|
24
|
-
[32mESM [m[1mdist\
|
|
25
|
-
[32mESM [m
|
|
9
|
+
[32mESM [m[1mdist\cli.js [32m[22m25.74 KB
|
|
10
|
+
[32mESM [m[1mdist\commands\templates\b2b-saas.js [32m[22m2.85 KB
|
|
11
|
+
[32mESM [m[1mdist\commands\login.js [32m[22m1.42 KB[K
|
|
12
|
+
[32mESM [m[1mdist\commands\init.js [32m[22m11.53 KB[K
|
|
13
|
+
[32mESM [m[1mdist\utils\config-loader.js [32m[22m1.05 KB[K
|
|
14
|
+
[32mESM [m[1mdist\utils\auth.js [32m[22m971.00 B[K
|
|
15
|
+
[32mESM [m[1mdist\commands\logout.js [32m[22m1.17 KB[K
|
|
16
|
+
[32mESM [m[1mdist\commands\pull.js [32m[22m6.22 KB[K
|
|
17
|
+
[32mESM [m[1mdist\commands\push.js [32m[22m6.27 KB[K
|
|
18
|
+
[32mESM [m[1mdist\commands\templates\starter.js [32m[22m2.27 KB[K
|
|
19
|
+
[32mESM [m[1mdist\commands\templates\usage-based.js [32m[22m2.02 KB[K
|
|
20
|
+
[32mESM [m[1mdist\commands\templates\index.js [32m[22m7.09 KB[K
|
|
21
|
+
[32mESM [m[1mdist\cli.js.map [32m[22m50.88 KB[K
|
|
22
|
+
[32mESM [m[1mdist\commands\login.js.map [32m[22m3.70 KB[K
|
|
23
|
+
[32mESM [m[1mdist\commands\templates\b2b-saas.js.map [32m[22m3.84 KB[K
|
|
24
|
+
[32mESM [m[1mdist\commands\init.js.map [32m[22m19.25 KB[K
|
|
25
|
+
[32mESM [m[1mdist\utils\config-loader.js.map [32m[22m2.55 KB[K
|
|
26
|
+
[32mESM [m[1mdist\commands\logout.js.map [32m[22m3.03 KB[K
|
|
27
|
+
[32mESM [m[1mdist\utils\auth.js.map [32m[22m2.24 KB[K
|
|
28
|
+
[32mESM [m[1mdist\commands\pull.js.map [32m[22m14.06 KB[K
|
|
29
|
+
[32mESM [m[1mdist\commands\templates\usage-based.js.map [32m[22m2.75 KB[K
|
|
30
|
+
[32mESM [m[1mdist\commands\templates\starter.js.map [32m[22m3.21 KB[K
|
|
31
|
+
[32mESM [m[1mdist\commands\push.js.map [32m[22m14.83 KB[K
|
|
32
|
+
[32mESM [m[1mdist\commands\templates\index.js.map [32m[22m10.15 KB[K
|
|
33
|
+
[32mESM [m⚡️ Build success in 81ms[K
|
|
26
34
|
[34mDTS [mBuild start
|
|
27
|
-
[32mDTS [m⚡️ Build success in
|
|
28
|
-
[32mDTS [m[1mdist\cli.d.ts
|
|
29
|
-
[32mDTS [m[1mdist\commands\init.d.ts
|
|
30
|
-
[32mDTS [m[1mdist\commands\login.d.ts
|
|
31
|
-
[32mDTS [m[1mdist\commands\logout.d.ts
|
|
32
|
-
[32mDTS [m[1mdist\commands\pull.d.ts
|
|
33
|
-
[32mDTS [m[1mdist\commands\push.d.ts
|
|
34
|
-
[32mDTS [m[1mdist\utils\auth.d.ts
|
|
35
|
-
[32mDTS [m[1mdist\utils\config-loader.d.ts
|
|
35
|
+
[32mDTS [m⚡️ Build success in 7779ms
|
|
36
|
+
[32mDTS [m[1mdist\cli.d.ts [32m[22m13.00 B
|
|
37
|
+
[32mDTS [m[1mdist\commands\init.d.ts [32m[22m353.00 B[K
|
|
38
|
+
[32mDTS [m[1mdist\commands\login.d.ts [32m[22m288.00 B[K
|
|
39
|
+
[32mDTS [m[1mdist\commands\logout.d.ts [32m[22m192.00 B[K
|
|
40
|
+
[32mDTS [m[1mdist\commands\pull.d.ts [32m[22m334.00 B[K
|
|
41
|
+
[32mDTS [m[1mdist\commands\push.d.ts [32m[22m328.00 B[K
|
|
42
|
+
[32mDTS [m[1mdist\utils\auth.d.ts [32m[22m637.00 B[K
|
|
43
|
+
[32mDTS [m[1mdist\utils\config-loader.d.ts [32m[22m566.00 B[K
|
|
44
|
+
[32mDTS [m[1mdist\commands\templates\b2b-saas.d.ts [32m[22m108.00 B[K
|
|
45
|
+
[32mDTS [m[1mdist\commands\templates\index.d.ts [32m[22m144.00 B[K
|
|
46
|
+
[32mDTS [m[1mdist\commands\templates\usage-based.d.ts [32m[22m114.00 B[K
|
|
47
|
+
[32mDTS [m[1mdist\commands\templates\starter.d.ts [32m[22m208.00 B[K
|
|
36
48
|
[?9001l[?1004l
|
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -32,12 +32,14 @@ Scaffold a new `revstack.config.ts` in your project root:
|
|
|
32
32
|
revstack init
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
This creates a starter config with example plans and features using
|
|
35
|
+
This creates a `revstack/` directory and a `revstack.config.ts` file in your project root, scaffolding a starter config with example plans and features using type-safe helpers from `@revstackhq/core`:
|
|
36
|
+
|
|
37
|
+
**`revstack/features.ts`**
|
|
36
38
|
|
|
37
39
|
```typescript
|
|
38
|
-
import {
|
|
40
|
+
import { defineFeature } from "@revstackhq/core";
|
|
39
41
|
|
|
40
|
-
const features = {
|
|
42
|
+
export const features = {
|
|
41
43
|
seats: defineFeature({
|
|
42
44
|
name: "Seats",
|
|
43
45
|
type: "static",
|
|
@@ -49,44 +51,62 @@ const features = {
|
|
|
49
51
|
unit_type: "count",
|
|
50
52
|
}),
|
|
51
53
|
};
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**`revstack/plans.ts`**
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { definePlan } from "@revstackhq/core";
|
|
60
|
+
import { features } from "./features";
|
|
61
|
+
|
|
62
|
+
export const plans = {
|
|
63
|
+
// DO NOT DELETE: Automatically created default plan for guests.
|
|
64
|
+
default: definePlan<typeof features>({
|
|
65
|
+
name: "Default",
|
|
66
|
+
description: "Automatically created default plan for guests.",
|
|
67
|
+
is_default: true,
|
|
68
|
+
is_public: false,
|
|
69
|
+
type: "free",
|
|
70
|
+
features: {},
|
|
71
|
+
}),
|
|
72
|
+
pro: definePlan<typeof features>({
|
|
73
|
+
name: "Pro",
|
|
74
|
+
description: "For professional teams.",
|
|
75
|
+
is_default: false,
|
|
76
|
+
is_public: true,
|
|
77
|
+
type: "paid",
|
|
78
|
+
prices: [
|
|
79
|
+
{
|
|
80
|
+
amount: 2900,
|
|
81
|
+
currency: "USD",
|
|
82
|
+
billing_interval: "monthly",
|
|
83
|
+
trial_period_days: 14,
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
amount: 29000,
|
|
87
|
+
currency: "USD",
|
|
88
|
+
billing_interval: "yearly",
|
|
89
|
+
trial_period_days: 14,
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
features: {
|
|
93
|
+
seats: { value_limit: 5, is_hard_limit: true },
|
|
94
|
+
ai_tokens: { value_limit: 1000, reset_period: "monthly" },
|
|
95
|
+
},
|
|
96
|
+
}),
|
|
97
|
+
};
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**`revstack.config.ts`**
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
import { defineConfig } from "@revstackhq/core";
|
|
104
|
+
import { features } from "./revstack/features";
|
|
105
|
+
import { plans } from "./revstack/plans";
|
|
52
106
|
|
|
53
107
|
export default defineConfig({
|
|
54
108
|
features,
|
|
55
|
-
plans
|
|
56
|
-
default: definePlan<typeof features>({
|
|
57
|
-
name: "Default",
|
|
58
|
-
description: "Automatically created default plan for guests.",
|
|
59
|
-
is_default: true,
|
|
60
|
-
is_public: false,
|
|
61
|
-
type: "free",
|
|
62
|
-
features: {},
|
|
63
|
-
}),
|
|
64
|
-
pro: definePlan<typeof features>({
|
|
65
|
-
name: "Pro",
|
|
66
|
-
description: "For professional teams.",
|
|
67
|
-
is_default: false,
|
|
68
|
-
is_public: true,
|
|
69
|
-
type: "paid",
|
|
70
|
-
prices: [
|
|
71
|
-
{
|
|
72
|
-
amount: 2900,
|
|
73
|
-
currency: "USD",
|
|
74
|
-
billing_interval: "monthly",
|
|
75
|
-
trial_period_days: 14,
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
amount: 29000,
|
|
79
|
-
currency: "USD",
|
|
80
|
-
billing_interval: "yearly",
|
|
81
|
-
trial_period_days: 14,
|
|
82
|
-
},
|
|
83
|
-
],
|
|
84
|
-
features: {
|
|
85
|
-
seats: { value_limit: 5, is_hard_limit: true },
|
|
86
|
-
ai_tokens: { value_limit: 1000, reset_period: "monthly" },
|
|
87
|
-
},
|
|
88
|
-
}),
|
|
89
|
-
},
|
|
109
|
+
plans,
|
|
90
110
|
});
|
|
91
111
|
```
|
|
92
112
|
|
package/dist/cli.js
CHANGED
|
@@ -89,22 +89,45 @@ import path2 from "path";
|
|
|
89
89
|
import { spawnSync } from "child_process";
|
|
90
90
|
import { fileURLToPath } from "url";
|
|
91
91
|
import ora from "ora";
|
|
92
|
-
|
|
92
|
+
|
|
93
|
+
// src/commands/templates/starter.ts
|
|
94
|
+
var starter = {
|
|
95
|
+
features: `import { defineFeature } from "@revstackhq/core";
|
|
93
96
|
|
|
94
97
|
export const features = {
|
|
95
|
-
seats: defineFeature({
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
98
|
+
seats: defineFeature({ name: "Seats", type: "static", unit_type: "count" }),
|
|
99
|
+
priority_support: defineFeature({ name: "Priority Support", type: "boolean", unit_type: "custom" }),
|
|
100
|
+
};
|
|
101
|
+
`,
|
|
102
|
+
addons: `import { defineAddon } from "@revstackhq/core";
|
|
103
|
+
import { features } from "./features";
|
|
104
|
+
|
|
105
|
+
export const addons = {
|
|
106
|
+
extra_seats: defineAddon<typeof features>({
|
|
107
|
+
name: "5 Extra Seats",
|
|
108
|
+
description: "Add 5 more team members to your workspace.",
|
|
109
|
+
type: "recurring",
|
|
110
|
+
prices: [
|
|
111
|
+
{ amount: 1500, currency: "USD", billing_interval: "monthly" }
|
|
112
|
+
],
|
|
113
|
+
features: {
|
|
114
|
+
seats: { value_limit: 5, type: "increment", is_hard_limit: false },
|
|
115
|
+
}
|
|
104
116
|
}),
|
|
117
|
+
vip_support: defineAddon<typeof features>({
|
|
118
|
+
name: "Priority Support",
|
|
119
|
+
description: "24/7 Slack channel support.",
|
|
120
|
+
type: "recurring",
|
|
121
|
+
prices: [
|
|
122
|
+
{ amount: 9900, currency: "USD", billing_interval: "monthly" }
|
|
123
|
+
],
|
|
124
|
+
features: {
|
|
125
|
+
priority_support: { has_access: true },
|
|
126
|
+
}
|
|
127
|
+
})
|
|
105
128
|
};
|
|
106
|
-
|
|
107
|
-
|
|
129
|
+
`,
|
|
130
|
+
plans: `import { definePlan } from "@revstackhq/core";
|
|
108
131
|
import { features } from "./features";
|
|
109
132
|
|
|
110
133
|
export const plans = {
|
|
@@ -123,54 +146,260 @@ export const plans = {
|
|
|
123
146
|
is_default: false,
|
|
124
147
|
is_public: true,
|
|
125
148
|
type: "paid",
|
|
149
|
+
available_addons: ["extra_seats", "vip_support"],
|
|
126
150
|
prices: [
|
|
127
|
-
{
|
|
128
|
-
amount: 2900,
|
|
129
|
-
currency: "USD",
|
|
130
|
-
billing_interval: "monthly",
|
|
131
|
-
trial_period_days: 14,
|
|
132
|
-
},
|
|
133
|
-
{
|
|
134
|
-
amount: 29000,
|
|
135
|
-
currency: "USD",
|
|
136
|
-
billing_interval: "yearly",
|
|
137
|
-
trial_period_days: 14,
|
|
138
|
-
}
|
|
151
|
+
{ amount: 2900, currency: "USD", billing_interval: "monthly", trial_period_days: 14 }
|
|
139
152
|
],
|
|
140
153
|
features: {
|
|
141
154
|
seats: { value_limit: 5, is_hard_limit: true },
|
|
142
|
-
ai_tokens: { value_limit: 1000, reset_period: "monthly" },
|
|
143
155
|
},
|
|
144
156
|
}),
|
|
145
157
|
};
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
import { features } from "./
|
|
149
|
-
import {
|
|
158
|
+
`,
|
|
159
|
+
index: `import { defineConfig } from "@revstackhq/core";
|
|
160
|
+
import { features } from "./features";
|
|
161
|
+
import { addons } from "./addons";
|
|
162
|
+
import { plans } from "./plans";
|
|
150
163
|
|
|
151
164
|
export default defineConfig({
|
|
152
165
|
features,
|
|
166
|
+
addons,
|
|
153
167
|
plans,
|
|
154
168
|
});
|
|
155
|
-
|
|
156
|
-
|
|
169
|
+
`,
|
|
170
|
+
root: `import config from "./revstack";
|
|
171
|
+
|
|
172
|
+
export default config;
|
|
173
|
+
`
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
// src/commands/templates/b2b-saas.ts
|
|
177
|
+
var b2bSaas = {
|
|
178
|
+
features: `import { defineFeature } from "@revstackhq/core";
|
|
179
|
+
|
|
180
|
+
export const features = {
|
|
181
|
+
active_users: defineFeature({ name: "Active Users", type: "static", unit_type: "count" }),
|
|
182
|
+
api_access: defineFeature({ name: "API Access", type: "boolean", unit_type: "custom" }),
|
|
183
|
+
custom_domain: defineFeature({ name: "Custom Domain", type: "boolean", unit_type: "custom" }),
|
|
184
|
+
};
|
|
185
|
+
`,
|
|
186
|
+
addons: `import { defineAddon } from "@revstackhq/core";
|
|
187
|
+
import { features } from "./features";
|
|
188
|
+
|
|
189
|
+
export const addons = {
|
|
190
|
+
extra_users: defineAddon<typeof features>({
|
|
191
|
+
name: "10 Extra Users",
|
|
192
|
+
description: "Add 10 more active users to your workspace.",
|
|
193
|
+
type: "recurring",
|
|
194
|
+
prices: [
|
|
195
|
+
{ amount: 5000, currency: "USD", billing_interval: "monthly" }
|
|
196
|
+
],
|
|
197
|
+
features: {
|
|
198
|
+
active_users: { value_limit: 10, type: "increment", is_hard_limit: true },
|
|
199
|
+
}
|
|
200
|
+
}),
|
|
201
|
+
dedicated_support: defineAddon<typeof features>({
|
|
202
|
+
name: "Dedicated Support",
|
|
203
|
+
description: "Enterprise SLA with 1-hour response time.",
|
|
204
|
+
type: "recurring",
|
|
205
|
+
prices: [
|
|
206
|
+
{ amount: 49900, currency: "USD", billing_interval: "monthly" }
|
|
207
|
+
],
|
|
208
|
+
features: {}
|
|
209
|
+
})
|
|
210
|
+
};
|
|
211
|
+
`,
|
|
212
|
+
plans: `import { definePlan } from "@revstackhq/core";
|
|
213
|
+
import { features } from "./features";
|
|
214
|
+
|
|
215
|
+
export const plans = {
|
|
216
|
+
default: definePlan<typeof features>({
|
|
217
|
+
name: "Default",
|
|
218
|
+
description: "Automatically created default plan for guests.",
|
|
219
|
+
is_default: true,
|
|
220
|
+
is_public: false,
|
|
221
|
+
type: "free",
|
|
222
|
+
features: {},
|
|
223
|
+
}),
|
|
224
|
+
startup: definePlan<typeof features>({
|
|
225
|
+
name: "Startup",
|
|
226
|
+
description: "For small teams getting started.",
|
|
227
|
+
is_default: false,
|
|
228
|
+
is_public: true,
|
|
229
|
+
type: "paid",
|
|
230
|
+
available_addons: ["extra_users"],
|
|
231
|
+
prices: [
|
|
232
|
+
{ amount: 9900, currency: "USD", billing_interval: "monthly" }
|
|
233
|
+
],
|
|
234
|
+
features: {
|
|
235
|
+
active_users: { value_limit: 10, is_hard_limit: true },
|
|
236
|
+
api_access: { value_bool: false },
|
|
237
|
+
custom_domain: { value_bool: false },
|
|
238
|
+
},
|
|
239
|
+
}),
|
|
240
|
+
enterprise: definePlan<typeof features>({
|
|
241
|
+
name: "Enterprise",
|
|
242
|
+
description: "Advanced features for scale.",
|
|
243
|
+
is_default: false,
|
|
244
|
+
is_public: true,
|
|
245
|
+
type: "paid",
|
|
246
|
+
available_addons: ["extra_users", "dedicated_support"],
|
|
247
|
+
prices: [
|
|
248
|
+
{ amount: 49900, currency: "USD", billing_interval: "monthly" }
|
|
249
|
+
],
|
|
250
|
+
features: {
|
|
251
|
+
active_users: { value_limit: 100, is_hard_limit: false },
|
|
252
|
+
api_access: { value_bool: true },
|
|
253
|
+
custom_domain: { value_bool: true },
|
|
254
|
+
},
|
|
255
|
+
}),
|
|
256
|
+
};
|
|
257
|
+
`,
|
|
258
|
+
index: `import { defineConfig } from "@revstackhq/core";
|
|
259
|
+
import { features } from "./features";
|
|
260
|
+
import { addons } from "./addons";
|
|
261
|
+
import { plans } from "./plans";
|
|
262
|
+
|
|
263
|
+
export default defineConfig({
|
|
264
|
+
features,
|
|
265
|
+
addons,
|
|
266
|
+
plans,
|
|
267
|
+
});
|
|
268
|
+
`,
|
|
269
|
+
root: `import config from "./revstack";
|
|
270
|
+
|
|
271
|
+
export default config;
|
|
272
|
+
`
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
// src/commands/templates/usage-based.ts
|
|
276
|
+
var usageBased = {
|
|
277
|
+
features: `import { defineFeature } from "@revstackhq/core";
|
|
278
|
+
|
|
279
|
+
export const features = {
|
|
280
|
+
api_requests: defineFeature({ name: "API Requests", type: "metered", unit_type: "requests" }),
|
|
281
|
+
storage_gb: defineFeature({ name: "Storage (GB)", type: "metered", unit_type: "custom" }),
|
|
282
|
+
};
|
|
283
|
+
`,
|
|
284
|
+
addons: `import { defineAddon } from "@revstackhq/core";
|
|
285
|
+
import { features } from "./features";
|
|
286
|
+
|
|
287
|
+
export const addons = {
|
|
288
|
+
premium_support: defineAddon<typeof features>({
|
|
289
|
+
name: "Premium Support",
|
|
290
|
+
description: "24/7 dedicated support.",
|
|
291
|
+
type: "recurring",
|
|
292
|
+
prices: [
|
|
293
|
+
{ amount: 20000, currency: "USD", billing_interval: "monthly" }
|
|
294
|
+
],
|
|
295
|
+
features: {}
|
|
296
|
+
})
|
|
297
|
+
};
|
|
298
|
+
`,
|
|
299
|
+
plans: `import { definePlan } from "@revstackhq/core";
|
|
300
|
+
import { features } from "./features";
|
|
301
|
+
|
|
302
|
+
export const plans = {
|
|
303
|
+
default: definePlan<typeof features>({
|
|
304
|
+
name: "Default",
|
|
305
|
+
description: "Automatically created default plan for guests.",
|
|
306
|
+
is_default: true,
|
|
307
|
+
is_public: false,
|
|
308
|
+
type: "free",
|
|
309
|
+
features: {},
|
|
310
|
+
}),
|
|
311
|
+
pay_as_you_go: definePlan<typeof features>({
|
|
312
|
+
name: "Pay As You Go",
|
|
313
|
+
description: "Flexible usage-based pricing.",
|
|
314
|
+
is_default: false,
|
|
315
|
+
is_public: true,
|
|
316
|
+
type: "paid",
|
|
317
|
+
available_addons: ["premium_support"],
|
|
318
|
+
prices: [
|
|
319
|
+
{ amount: 0, currency: "USD", billing_interval: "monthly" } // Base platform fee
|
|
320
|
+
],
|
|
321
|
+
features: {
|
|
322
|
+
api_requests: { value_limit: 10000, is_hard_limit: false, reset_period: "monthly" }, // 10k free requests per month
|
|
323
|
+
storage_gb: { value_limit: 5, is_hard_limit: false, reset_period: "never" }, // 5GB free storage lifetime
|
|
324
|
+
},
|
|
325
|
+
}),
|
|
326
|
+
};
|
|
327
|
+
`,
|
|
328
|
+
index: `import { defineConfig } from "@revstackhq/core";
|
|
329
|
+
import { features } from "./features";
|
|
330
|
+
import { addons } from "./addons";
|
|
331
|
+
import { plans } from "./plans";
|
|
332
|
+
|
|
333
|
+
export default defineConfig({
|
|
334
|
+
features,
|
|
335
|
+
addons,
|
|
336
|
+
plans,
|
|
337
|
+
});
|
|
338
|
+
`,
|
|
339
|
+
root: `import config from "./revstack";
|
|
340
|
+
|
|
341
|
+
export default config;
|
|
342
|
+
`
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
// src/commands/templates/index.ts
|
|
346
|
+
var TEMPLATES = {
|
|
347
|
+
starter,
|
|
348
|
+
"b2b-saas": b2bSaas,
|
|
349
|
+
"usage-based": usageBased
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
// src/commands/init.ts
|
|
353
|
+
var initCommand = new Command3("init").description("Scaffold a new revstack.config.ts in the current directory").option(
|
|
354
|
+
"-t, --template <name>",
|
|
355
|
+
"Choose a starting template (starter, b2b-saas, usage-based)",
|
|
356
|
+
"starter"
|
|
357
|
+
).action(async (options) => {
|
|
358
|
+
const templateName = options.template || "starter";
|
|
359
|
+
const template = TEMPLATES[templateName];
|
|
360
|
+
if (!template) {
|
|
361
|
+
console.log(
|
|
362
|
+
chalk3.red(
|
|
363
|
+
`
|
|
364
|
+
\u2716 Unknown template "${templateName}". Available templates: ${Object.keys(TEMPLATES).join(", ")}
|
|
365
|
+
`
|
|
366
|
+
)
|
|
367
|
+
);
|
|
368
|
+
process.exit(1);
|
|
369
|
+
}
|
|
157
370
|
const cwd = process.cwd();
|
|
158
371
|
const configPath = path2.resolve(cwd, "revstack.config.ts");
|
|
159
|
-
const revstackDir = path2.resolve(cwd, "revstack");
|
|
160
|
-
const featuresPath = path2.resolve(revstackDir, "features.ts");
|
|
161
|
-
const plansPath = path2.resolve(revstackDir, "plans.ts");
|
|
162
372
|
if (fs2.existsSync(configPath)) {
|
|
163
373
|
console.log(
|
|
164
374
|
"\n" + chalk3.yellow(" \u26A0 revstack.config.ts already exists.\n") + chalk3.dim(" Delete it first if you want to start fresh.\n")
|
|
165
375
|
);
|
|
166
376
|
process.exit(1);
|
|
167
377
|
}
|
|
378
|
+
const revstackDir = path2.resolve(cwd, "revstack");
|
|
168
379
|
if (!fs2.existsSync(revstackDir)) {
|
|
169
380
|
fs2.mkdirSync(revstackDir, { recursive: true });
|
|
170
381
|
}
|
|
171
|
-
fs2.writeFileSync(
|
|
172
|
-
|
|
173
|
-
|
|
382
|
+
fs2.writeFileSync(
|
|
383
|
+
path2.resolve(revstackDir, "features.ts"),
|
|
384
|
+
template.features,
|
|
385
|
+
"utf-8"
|
|
386
|
+
);
|
|
387
|
+
fs2.writeFileSync(
|
|
388
|
+
path2.resolve(revstackDir, "addons.ts"),
|
|
389
|
+
template.addons,
|
|
390
|
+
"utf-8"
|
|
391
|
+
);
|
|
392
|
+
fs2.writeFileSync(
|
|
393
|
+
path2.resolve(revstackDir, "plans.ts"),
|
|
394
|
+
template.plans,
|
|
395
|
+
"utf-8"
|
|
396
|
+
);
|
|
397
|
+
fs2.writeFileSync(
|
|
398
|
+
path2.resolve(revstackDir, "index.ts"),
|
|
399
|
+
template.index,
|
|
400
|
+
"utf-8"
|
|
401
|
+
);
|
|
402
|
+
fs2.writeFileSync(configPath, template.root, "utf-8");
|
|
174
403
|
let packageManager = "npm";
|
|
175
404
|
if (fs2.existsSync(path2.resolve(cwd, "pnpm-lock.yaml"))) {
|
|
176
405
|
packageManager = "pnpm";
|
|
@@ -268,6 +497,7 @@ async function loadLocalConfig(cwd) {
|
|
|
268
497
|
}
|
|
269
498
|
|
|
270
499
|
// src/commands/push.ts
|
|
500
|
+
import { validateConfig, RevstackValidationError } from "@revstackhq/core";
|
|
271
501
|
var API_BASE = "https://app.revstack.dev";
|
|
272
502
|
var DIFF_ICONS = {
|
|
273
503
|
added: chalk5.green(" + "),
|
|
@@ -310,6 +540,37 @@ function requireAuth() {
|
|
|
310
540
|
var pushCommand = new Command4("push").description("Push your local billing config to Revstack Cloud").option("-e, --env <environment>", "Target environment", "test").action(async (options) => {
|
|
311
541
|
const apiKey = requireAuth();
|
|
312
542
|
const config = await loadLocalConfig(process.cwd());
|
|
543
|
+
const validationSpinner = ora2({
|
|
544
|
+
text: "Validating billing configuration...",
|
|
545
|
+
prefixText: " "
|
|
546
|
+
}).start();
|
|
547
|
+
try {
|
|
548
|
+
validateConfig(config);
|
|
549
|
+
validationSpinner.succeed("Configuration validated");
|
|
550
|
+
} catch (error) {
|
|
551
|
+
if (error instanceof RevstackValidationError || error?.name === "RevstackValidationError") {
|
|
552
|
+
validationSpinner.fail("Configuration invalid");
|
|
553
|
+
console.error(
|
|
554
|
+
chalk5.red(
|
|
555
|
+
"\n \u2716 The billing configuration contains business logic errors:\n"
|
|
556
|
+
)
|
|
557
|
+
);
|
|
558
|
+
for (const err of error.errors || []) {
|
|
559
|
+
console.error(chalk5.red(` \u2022 ${err}`));
|
|
560
|
+
}
|
|
561
|
+
console.log();
|
|
562
|
+
process.exit(1);
|
|
563
|
+
}
|
|
564
|
+
validationSpinner.fail("Validation failed");
|
|
565
|
+
console.error(
|
|
566
|
+
chalk5.red(
|
|
567
|
+
`
|
|
568
|
+
An unexpected error occurred during validation: ${error?.message || String(error)}
|
|
569
|
+
`
|
|
570
|
+
)
|
|
571
|
+
);
|
|
572
|
+
process.exit(1);
|
|
573
|
+
}
|
|
313
574
|
const spinner = ora2({
|
|
314
575
|
text: "Calculating diff...",
|
|
315
576
|
prefixText: " "
|