blimu 0.6.3 → 1.1.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # blimu
2
2
 
3
- Blimu - Authorization as a Service. This package provides the Blimu CLI tool for managing your authorization configuration.
3
+ Blimu - Authorization as a Service. This package provides the Blimu CLI tool for managing your authorization configuration and generating type-safe TypeScript types.
4
4
 
5
5
  ## Installation
6
6
 
@@ -12,23 +12,87 @@ yarn add blimu
12
12
  pnpm add blimu
13
13
  ```
14
14
 
15
- After installation, the Blimu CLI binary will be automatically downloaded and made available via the `blimu` command.
16
-
17
15
  ## Usage
18
16
 
19
- Once installed, you can use the Blimu CLI to manage your authorization configuration:
17
+ ### Codegen Command
18
+
19
+ Generate type augmentation files from your Blimu configuration:
20
20
 
21
21
  ```bash
22
- # Validate your Blimu configuration
23
- blimu validate ./blimu/
22
+ # Generate type augmentation with defaults
23
+ # Looks for .blimu/config.mjs or .blimu/config.ts in current directory
24
+ # Outputs to .blimu/blimu-types.d.ts
25
+ blimu codegen
26
+
27
+ # With custom config path
28
+ blimu codegen --config ./custom/path/config.mjs
29
+
30
+ # With custom output path
31
+ blimu codegen --output ./types/blimu-types.d.ts
32
+
33
+ # With custom SDK package
34
+ blimu codegen --sdk-package @blimu/custom-backend
35
+
36
+ # All options together
37
+ blimu codegen --config .blimu/config.mjs --output .blimu/blimu-types.d.ts --sdk-package @blimu/backend
38
+ ```
24
39
 
25
- # Push configuration to an environment
26
- blimu push ./blimu/ --workspace-id <workspace-id> --environment-id <environment-id>
40
+ #### Command Options
27
41
 
28
- # Pull configuration from an environment
29
- blimu pull ./blimu/ --workspace-id <workspace-id> --environment-id <environment-id>
42
+ - `--config <path>`: Optional path to Blimu config file. If not provided, the CLI will look for `.blimu/config.mjs` or `.blimu/config.ts` in the current directory.
43
+ - `--output <path>`: Optional output path for the generated type augmentation file. Defaults to `.blimu/blimu-types.d.ts`.
44
+ - `--sdk-package <name>`: Optional SDK package name. Defaults to `@blimu/backend`.
45
+
46
+ #### Config File Format
47
+
48
+ The CLI looks for a Blimu configuration file in the `.blimu/` directory. The config file should export a default object with the following structure:
49
+
50
+ ```javascript
51
+ // .blimu/config.mjs
52
+ export default {
53
+ resources: {
54
+ workspace: {},
55
+ environment: {},
56
+ },
57
+ entitlements: {
58
+ 'workspace:read': {},
59
+ 'workspace:create': {},
60
+ },
61
+ plans: {
62
+ free: {
63
+ name: 'Free Plan',
64
+ resource_limits: {
65
+ workspace_count: 1,
66
+ },
67
+ },
68
+ pro: {
69
+ name: 'Pro Plan',
70
+ resource_limits: {
71
+ workspace_count: 10,
72
+ },
73
+ },
74
+ },
75
+ };
30
76
  ```
31
77
 
78
+ The config file can be:
79
+
80
+ - `.mjs` (ES Module JavaScript)
81
+ - `.js` (JavaScript)
82
+ - `.ts` (TypeScript - requires tsx or ts-node)
83
+
84
+ #### Generated Type Augmentation
85
+
86
+ The `codegen` command generates a TypeScript declaration file that augments the `@blimu/backend` SDK with union types based on your configuration:
87
+
88
+ - `ResourceType`: Union of all resource types from your config
89
+ - `EntitlementType`: Union of all entitlement types from your config
90
+ - `PlanType`: Union of all plan types from your config
91
+ - `LimitType`: Union of all resource limit types from your plans
92
+ - `UsageLimitType`: Union of all usage-based limit types from your plans
93
+
94
+ This provides full type safety and autocomplete when using the Blimu SDK in your application.
95
+
32
96
  ## SDK Packages
33
97
 
34
98
  For programmatic access to the Blimu API, use the following SDK packages:
@@ -45,6 +109,24 @@ npm install @blimu/client
45
109
  npm install @blimu/nestjs
46
110
  ```
47
111
 
112
+ ## Development
113
+
114
+ To build the CLI from source:
115
+
116
+ ```bash
117
+ yarn build
118
+ # or
119
+ npm run build
120
+ ```
121
+
122
+ To run the CLI in development mode:
123
+
124
+ ```bash
125
+ yarn dev
126
+ # or
127
+ npm run dev
128
+ ```
129
+
48
130
  ## Learn More
49
131
 
50
132
  Visit [https://blimu.com](https://blimu.com) for documentation and more information.
@@ -0,0 +1,285 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const ResourceDefinitionSchema: z.ZodObject<{
4
+ is_tenant: z.ZodOptional<z.ZodBoolean>;
5
+ roles: z.ZodArray<z.ZodString, "many">;
6
+ parents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
7
+ required: z.ZodBoolean;
8
+ }, "strip", z.ZodTypeAny, {
9
+ required: boolean;
10
+ }, {
11
+ required: boolean;
12
+ }>>>;
13
+ roles_inheritance: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
14
+ }, "strip", z.ZodTypeAny, {
15
+ roles: string[];
16
+ is_tenant?: boolean | undefined;
17
+ parents?: Record<string, {
18
+ required: boolean;
19
+ }> | undefined;
20
+ roles_inheritance?: Record<string, string[]> | undefined;
21
+ }, {
22
+ roles: string[];
23
+ is_tenant?: boolean | undefined;
24
+ parents?: Record<string, {
25
+ required: boolean;
26
+ }> | undefined;
27
+ roles_inheritance?: Record<string, string[]> | undefined;
28
+ }>;
29
+ declare const EntitlementDefinitionSchema: z.ZodObject<{
30
+ roles: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
31
+ plans: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
32
+ limit: z.ZodOptional<z.ZodString>;
33
+ }, "strip", z.ZodTypeAny, {
34
+ roles?: string[] | undefined;
35
+ plans?: string[] | undefined;
36
+ limit?: string | undefined;
37
+ }, {
38
+ roles?: string[] | undefined;
39
+ plans?: string[] | undefined;
40
+ limit?: string | undefined;
41
+ }>;
42
+ declare const FeatureDefinitionSchema: z.ZodObject<{
43
+ name: z.ZodString;
44
+ summary: z.ZodOptional<z.ZodString>;
45
+ entitlements: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
46
+ plans: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
47
+ default_enabled: z.ZodOptional<z.ZodBoolean>;
48
+ }, "strip", z.ZodTypeAny, {
49
+ name: string;
50
+ plans?: string[] | undefined;
51
+ summary?: string | undefined;
52
+ entitlements?: string[] | undefined;
53
+ default_enabled?: boolean | undefined;
54
+ }, {
55
+ name: string;
56
+ plans?: string[] | undefined;
57
+ summary?: string | undefined;
58
+ entitlements?: string[] | undefined;
59
+ default_enabled?: boolean | undefined;
60
+ }>;
61
+ declare const PlanDefinitionSchema: z.ZodObject<{
62
+ name: z.ZodString;
63
+ summary: z.ZodOptional<z.ZodString>;
64
+ description: z.ZodOptional<z.ZodString>;
65
+ resource_limits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
66
+ usage_based_limits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
67
+ value: z.ZodNumber;
68
+ period: z.ZodEnum<["monthly", "yearly", "lifetime"]>;
69
+ }, "strip", z.ZodTypeAny, {
70
+ value: number;
71
+ period: "monthly" | "yearly" | "lifetime";
72
+ }, {
73
+ value: number;
74
+ period: "monthly" | "yearly" | "lifetime";
75
+ }>>>;
76
+ }, "strip", z.ZodTypeAny, {
77
+ name: string;
78
+ summary?: string | undefined;
79
+ description?: string | undefined;
80
+ resource_limits?: Record<string, number> | undefined;
81
+ usage_based_limits?: Record<string, {
82
+ value: number;
83
+ period: "monthly" | "yearly" | "lifetime";
84
+ }> | undefined;
85
+ }, {
86
+ name: string;
87
+ summary?: string | undefined;
88
+ description?: string | undefined;
89
+ resource_limits?: Record<string, number> | undefined;
90
+ usage_based_limits?: Record<string, {
91
+ value: number;
92
+ period: "monthly" | "yearly" | "lifetime";
93
+ }> | undefined;
94
+ }>;
95
+ declare const BlimuConfigSchema: z.ZodObject<{
96
+ resources: z.ZodRecord<z.ZodString, z.ZodObject<{
97
+ is_tenant: z.ZodOptional<z.ZodBoolean>;
98
+ roles: z.ZodArray<z.ZodString, "many">;
99
+ parents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
100
+ required: z.ZodBoolean;
101
+ }, "strip", z.ZodTypeAny, {
102
+ required: boolean;
103
+ }, {
104
+ required: boolean;
105
+ }>>>;
106
+ roles_inheritance: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
107
+ }, "strip", z.ZodTypeAny, {
108
+ roles: string[];
109
+ is_tenant?: boolean | undefined;
110
+ parents?: Record<string, {
111
+ required: boolean;
112
+ }> | undefined;
113
+ roles_inheritance?: Record<string, string[]> | undefined;
114
+ }, {
115
+ roles: string[];
116
+ is_tenant?: boolean | undefined;
117
+ parents?: Record<string, {
118
+ required: boolean;
119
+ }> | undefined;
120
+ roles_inheritance?: Record<string, string[]> | undefined;
121
+ }>>;
122
+ entitlements: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
123
+ roles: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
124
+ plans: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
125
+ limit: z.ZodOptional<z.ZodString>;
126
+ }, "strip", z.ZodTypeAny, {
127
+ roles?: string[] | undefined;
128
+ plans?: string[] | undefined;
129
+ limit?: string | undefined;
130
+ }, {
131
+ roles?: string[] | undefined;
132
+ plans?: string[] | undefined;
133
+ limit?: string | undefined;
134
+ }>>>;
135
+ features: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
136
+ name: z.ZodString;
137
+ summary: z.ZodOptional<z.ZodString>;
138
+ entitlements: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
139
+ plans: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
140
+ default_enabled: z.ZodOptional<z.ZodBoolean>;
141
+ }, "strip", z.ZodTypeAny, {
142
+ name: string;
143
+ plans?: string[] | undefined;
144
+ summary?: string | undefined;
145
+ entitlements?: string[] | undefined;
146
+ default_enabled?: boolean | undefined;
147
+ }, {
148
+ name: string;
149
+ plans?: string[] | undefined;
150
+ summary?: string | undefined;
151
+ entitlements?: string[] | undefined;
152
+ default_enabled?: boolean | undefined;
153
+ }>>>;
154
+ plans: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
155
+ name: z.ZodString;
156
+ summary: z.ZodOptional<z.ZodString>;
157
+ description: z.ZodOptional<z.ZodString>;
158
+ resource_limits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
159
+ usage_based_limits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
160
+ value: z.ZodNumber;
161
+ period: z.ZodEnum<["monthly", "yearly", "lifetime"]>;
162
+ }, "strip", z.ZodTypeAny, {
163
+ value: number;
164
+ period: "monthly" | "yearly" | "lifetime";
165
+ }, {
166
+ value: number;
167
+ period: "monthly" | "yearly" | "lifetime";
168
+ }>>>;
169
+ }, "strip", z.ZodTypeAny, {
170
+ name: string;
171
+ summary?: string | undefined;
172
+ description?: string | undefined;
173
+ resource_limits?: Record<string, number> | undefined;
174
+ usage_based_limits?: Record<string, {
175
+ value: number;
176
+ period: "monthly" | "yearly" | "lifetime";
177
+ }> | undefined;
178
+ }, {
179
+ name: string;
180
+ summary?: string | undefined;
181
+ description?: string | undefined;
182
+ resource_limits?: Record<string, number> | undefined;
183
+ usage_based_limits?: Record<string, {
184
+ value: number;
185
+ period: "monthly" | "yearly" | "lifetime";
186
+ }> | undefined;
187
+ }>>>;
188
+ }, "strip", z.ZodTypeAny, {
189
+ resources: Record<string, {
190
+ roles: string[];
191
+ is_tenant?: boolean | undefined;
192
+ parents?: Record<string, {
193
+ required: boolean;
194
+ }> | undefined;
195
+ roles_inheritance?: Record<string, string[]> | undefined;
196
+ }>;
197
+ plans?: Record<string, {
198
+ name: string;
199
+ summary?: string | undefined;
200
+ description?: string | undefined;
201
+ resource_limits?: Record<string, number> | undefined;
202
+ usage_based_limits?: Record<string, {
203
+ value: number;
204
+ period: "monthly" | "yearly" | "lifetime";
205
+ }> | undefined;
206
+ }> | undefined;
207
+ entitlements?: Record<string, {
208
+ roles?: string[] | undefined;
209
+ plans?: string[] | undefined;
210
+ limit?: string | undefined;
211
+ }> | undefined;
212
+ features?: Record<string, {
213
+ name: string;
214
+ plans?: string[] | undefined;
215
+ summary?: string | undefined;
216
+ entitlements?: string[] | undefined;
217
+ default_enabled?: boolean | undefined;
218
+ }> | undefined;
219
+ }, {
220
+ resources: Record<string, {
221
+ roles: string[];
222
+ is_tenant?: boolean | undefined;
223
+ parents?: Record<string, {
224
+ required: boolean;
225
+ }> | undefined;
226
+ roles_inheritance?: Record<string, string[]> | undefined;
227
+ }>;
228
+ plans?: Record<string, {
229
+ name: string;
230
+ summary?: string | undefined;
231
+ description?: string | undefined;
232
+ resource_limits?: Record<string, number> | undefined;
233
+ usage_based_limits?: Record<string, {
234
+ value: number;
235
+ period: "monthly" | "yearly" | "lifetime";
236
+ }> | undefined;
237
+ }> | undefined;
238
+ entitlements?: Record<string, {
239
+ roles?: string[] | undefined;
240
+ plans?: string[] | undefined;
241
+ limit?: string | undefined;
242
+ }> | undefined;
243
+ features?: Record<string, {
244
+ name: string;
245
+ plans?: string[] | undefined;
246
+ summary?: string | undefined;
247
+ entitlements?: string[] | undefined;
248
+ default_enabled?: boolean | undefined;
249
+ }> | undefined;
250
+ }>;
251
+ type ResourceDefinition = z.infer<typeof ResourceDefinitionSchema>;
252
+ type EntitlementDefinition = z.infer<typeof EntitlementDefinitionSchema>;
253
+ type FeatureDefinition = z.infer<typeof FeatureDefinitionSchema>;
254
+ type PlanDefinition = z.infer<typeof PlanDefinitionSchema>;
255
+ type BlimuConfig = z.infer<typeof BlimuConfigSchema>;
256
+
257
+ type BlimuConfigInput = {
258
+ resources: Record<string, ResourceDefinition>;
259
+ entitlements?: Record<string, EntitlementDefinition>;
260
+ features?: Record<string, FeatureDefinition>;
261
+ plans?: Record<string, PlanDefinition>;
262
+ };
263
+ declare function defineConfig<T extends BlimuConfigInput>(config: T): T;
264
+
265
+ type InferResourceTypes<T> = T extends {
266
+ resources: infer R;
267
+ } ? R extends Record<string, any> ? keyof R : never : never;
268
+ type InferEntitlementTypes<T> = T extends {
269
+ entitlements: infer E;
270
+ } ? E extends Record<string, any> ? keyof E : never : never;
271
+ type InferPlanTypes<T> = T extends {
272
+ plans: infer P;
273
+ } ? P extends Record<string, any> ? keyof P : never : never;
274
+ type InferLimitTypes<T> = T extends {
275
+ plans: infer P;
276
+ } ? P extends Record<string, any> ? P[keyof P] extends {
277
+ resource_limits?: infer RL;
278
+ } ? RL extends Record<string, any> ? keyof RL : never : never : never : never;
279
+ type InferUsageLimitTypes<T> = T extends {
280
+ plans: infer P;
281
+ } ? P extends Record<string, any> ? P[keyof P] extends {
282
+ usage_based_limits?: infer UL;
283
+ } ? UL extends Record<string, any> ? keyof UL : never : never : never : never;
284
+
285
+ export { type BlimuConfig, BlimuConfigSchema, type EntitlementDefinition, EntitlementDefinitionSchema, type FeatureDefinition, FeatureDefinitionSchema, type InferEntitlementTypes, type InferLimitTypes, type InferPlanTypes, type InferResourceTypes, type InferUsageLimitTypes, type PlanDefinition, PlanDefinitionSchema, type ResourceDefinition, ResourceDefinitionSchema, defineConfig };
@@ -0,0 +1,285 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const ResourceDefinitionSchema: z.ZodObject<{
4
+ is_tenant: z.ZodOptional<z.ZodBoolean>;
5
+ roles: z.ZodArray<z.ZodString, "many">;
6
+ parents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
7
+ required: z.ZodBoolean;
8
+ }, "strip", z.ZodTypeAny, {
9
+ required: boolean;
10
+ }, {
11
+ required: boolean;
12
+ }>>>;
13
+ roles_inheritance: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
14
+ }, "strip", z.ZodTypeAny, {
15
+ roles: string[];
16
+ is_tenant?: boolean | undefined;
17
+ parents?: Record<string, {
18
+ required: boolean;
19
+ }> | undefined;
20
+ roles_inheritance?: Record<string, string[]> | undefined;
21
+ }, {
22
+ roles: string[];
23
+ is_tenant?: boolean | undefined;
24
+ parents?: Record<string, {
25
+ required: boolean;
26
+ }> | undefined;
27
+ roles_inheritance?: Record<string, string[]> | undefined;
28
+ }>;
29
+ declare const EntitlementDefinitionSchema: z.ZodObject<{
30
+ roles: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
31
+ plans: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
32
+ limit: z.ZodOptional<z.ZodString>;
33
+ }, "strip", z.ZodTypeAny, {
34
+ roles?: string[] | undefined;
35
+ plans?: string[] | undefined;
36
+ limit?: string | undefined;
37
+ }, {
38
+ roles?: string[] | undefined;
39
+ plans?: string[] | undefined;
40
+ limit?: string | undefined;
41
+ }>;
42
+ declare const FeatureDefinitionSchema: z.ZodObject<{
43
+ name: z.ZodString;
44
+ summary: z.ZodOptional<z.ZodString>;
45
+ entitlements: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
46
+ plans: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
47
+ default_enabled: z.ZodOptional<z.ZodBoolean>;
48
+ }, "strip", z.ZodTypeAny, {
49
+ name: string;
50
+ plans?: string[] | undefined;
51
+ summary?: string | undefined;
52
+ entitlements?: string[] | undefined;
53
+ default_enabled?: boolean | undefined;
54
+ }, {
55
+ name: string;
56
+ plans?: string[] | undefined;
57
+ summary?: string | undefined;
58
+ entitlements?: string[] | undefined;
59
+ default_enabled?: boolean | undefined;
60
+ }>;
61
+ declare const PlanDefinitionSchema: z.ZodObject<{
62
+ name: z.ZodString;
63
+ summary: z.ZodOptional<z.ZodString>;
64
+ description: z.ZodOptional<z.ZodString>;
65
+ resource_limits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
66
+ usage_based_limits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
67
+ value: z.ZodNumber;
68
+ period: z.ZodEnum<["monthly", "yearly", "lifetime"]>;
69
+ }, "strip", z.ZodTypeAny, {
70
+ value: number;
71
+ period: "monthly" | "yearly" | "lifetime";
72
+ }, {
73
+ value: number;
74
+ period: "monthly" | "yearly" | "lifetime";
75
+ }>>>;
76
+ }, "strip", z.ZodTypeAny, {
77
+ name: string;
78
+ summary?: string | undefined;
79
+ description?: string | undefined;
80
+ resource_limits?: Record<string, number> | undefined;
81
+ usage_based_limits?: Record<string, {
82
+ value: number;
83
+ period: "monthly" | "yearly" | "lifetime";
84
+ }> | undefined;
85
+ }, {
86
+ name: string;
87
+ summary?: string | undefined;
88
+ description?: string | undefined;
89
+ resource_limits?: Record<string, number> | undefined;
90
+ usage_based_limits?: Record<string, {
91
+ value: number;
92
+ period: "monthly" | "yearly" | "lifetime";
93
+ }> | undefined;
94
+ }>;
95
+ declare const BlimuConfigSchema: z.ZodObject<{
96
+ resources: z.ZodRecord<z.ZodString, z.ZodObject<{
97
+ is_tenant: z.ZodOptional<z.ZodBoolean>;
98
+ roles: z.ZodArray<z.ZodString, "many">;
99
+ parents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
100
+ required: z.ZodBoolean;
101
+ }, "strip", z.ZodTypeAny, {
102
+ required: boolean;
103
+ }, {
104
+ required: boolean;
105
+ }>>>;
106
+ roles_inheritance: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
107
+ }, "strip", z.ZodTypeAny, {
108
+ roles: string[];
109
+ is_tenant?: boolean | undefined;
110
+ parents?: Record<string, {
111
+ required: boolean;
112
+ }> | undefined;
113
+ roles_inheritance?: Record<string, string[]> | undefined;
114
+ }, {
115
+ roles: string[];
116
+ is_tenant?: boolean | undefined;
117
+ parents?: Record<string, {
118
+ required: boolean;
119
+ }> | undefined;
120
+ roles_inheritance?: Record<string, string[]> | undefined;
121
+ }>>;
122
+ entitlements: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
123
+ roles: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
124
+ plans: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
125
+ limit: z.ZodOptional<z.ZodString>;
126
+ }, "strip", z.ZodTypeAny, {
127
+ roles?: string[] | undefined;
128
+ plans?: string[] | undefined;
129
+ limit?: string | undefined;
130
+ }, {
131
+ roles?: string[] | undefined;
132
+ plans?: string[] | undefined;
133
+ limit?: string | undefined;
134
+ }>>>;
135
+ features: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
136
+ name: z.ZodString;
137
+ summary: z.ZodOptional<z.ZodString>;
138
+ entitlements: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
139
+ plans: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
140
+ default_enabled: z.ZodOptional<z.ZodBoolean>;
141
+ }, "strip", z.ZodTypeAny, {
142
+ name: string;
143
+ plans?: string[] | undefined;
144
+ summary?: string | undefined;
145
+ entitlements?: string[] | undefined;
146
+ default_enabled?: boolean | undefined;
147
+ }, {
148
+ name: string;
149
+ plans?: string[] | undefined;
150
+ summary?: string | undefined;
151
+ entitlements?: string[] | undefined;
152
+ default_enabled?: boolean | undefined;
153
+ }>>>;
154
+ plans: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
155
+ name: z.ZodString;
156
+ summary: z.ZodOptional<z.ZodString>;
157
+ description: z.ZodOptional<z.ZodString>;
158
+ resource_limits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
159
+ usage_based_limits: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
160
+ value: z.ZodNumber;
161
+ period: z.ZodEnum<["monthly", "yearly", "lifetime"]>;
162
+ }, "strip", z.ZodTypeAny, {
163
+ value: number;
164
+ period: "monthly" | "yearly" | "lifetime";
165
+ }, {
166
+ value: number;
167
+ period: "monthly" | "yearly" | "lifetime";
168
+ }>>>;
169
+ }, "strip", z.ZodTypeAny, {
170
+ name: string;
171
+ summary?: string | undefined;
172
+ description?: string | undefined;
173
+ resource_limits?: Record<string, number> | undefined;
174
+ usage_based_limits?: Record<string, {
175
+ value: number;
176
+ period: "monthly" | "yearly" | "lifetime";
177
+ }> | undefined;
178
+ }, {
179
+ name: string;
180
+ summary?: string | undefined;
181
+ description?: string | undefined;
182
+ resource_limits?: Record<string, number> | undefined;
183
+ usage_based_limits?: Record<string, {
184
+ value: number;
185
+ period: "monthly" | "yearly" | "lifetime";
186
+ }> | undefined;
187
+ }>>>;
188
+ }, "strip", z.ZodTypeAny, {
189
+ resources: Record<string, {
190
+ roles: string[];
191
+ is_tenant?: boolean | undefined;
192
+ parents?: Record<string, {
193
+ required: boolean;
194
+ }> | undefined;
195
+ roles_inheritance?: Record<string, string[]> | undefined;
196
+ }>;
197
+ plans?: Record<string, {
198
+ name: string;
199
+ summary?: string | undefined;
200
+ description?: string | undefined;
201
+ resource_limits?: Record<string, number> | undefined;
202
+ usage_based_limits?: Record<string, {
203
+ value: number;
204
+ period: "monthly" | "yearly" | "lifetime";
205
+ }> | undefined;
206
+ }> | undefined;
207
+ entitlements?: Record<string, {
208
+ roles?: string[] | undefined;
209
+ plans?: string[] | undefined;
210
+ limit?: string | undefined;
211
+ }> | undefined;
212
+ features?: Record<string, {
213
+ name: string;
214
+ plans?: string[] | undefined;
215
+ summary?: string | undefined;
216
+ entitlements?: string[] | undefined;
217
+ default_enabled?: boolean | undefined;
218
+ }> | undefined;
219
+ }, {
220
+ resources: Record<string, {
221
+ roles: string[];
222
+ is_tenant?: boolean | undefined;
223
+ parents?: Record<string, {
224
+ required: boolean;
225
+ }> | undefined;
226
+ roles_inheritance?: Record<string, string[]> | undefined;
227
+ }>;
228
+ plans?: Record<string, {
229
+ name: string;
230
+ summary?: string | undefined;
231
+ description?: string | undefined;
232
+ resource_limits?: Record<string, number> | undefined;
233
+ usage_based_limits?: Record<string, {
234
+ value: number;
235
+ period: "monthly" | "yearly" | "lifetime";
236
+ }> | undefined;
237
+ }> | undefined;
238
+ entitlements?: Record<string, {
239
+ roles?: string[] | undefined;
240
+ plans?: string[] | undefined;
241
+ limit?: string | undefined;
242
+ }> | undefined;
243
+ features?: Record<string, {
244
+ name: string;
245
+ plans?: string[] | undefined;
246
+ summary?: string | undefined;
247
+ entitlements?: string[] | undefined;
248
+ default_enabled?: boolean | undefined;
249
+ }> | undefined;
250
+ }>;
251
+ type ResourceDefinition = z.infer<typeof ResourceDefinitionSchema>;
252
+ type EntitlementDefinition = z.infer<typeof EntitlementDefinitionSchema>;
253
+ type FeatureDefinition = z.infer<typeof FeatureDefinitionSchema>;
254
+ type PlanDefinition = z.infer<typeof PlanDefinitionSchema>;
255
+ type BlimuConfig = z.infer<typeof BlimuConfigSchema>;
256
+
257
+ type BlimuConfigInput = {
258
+ resources: Record<string, ResourceDefinition>;
259
+ entitlements?: Record<string, EntitlementDefinition>;
260
+ features?: Record<string, FeatureDefinition>;
261
+ plans?: Record<string, PlanDefinition>;
262
+ };
263
+ declare function defineConfig<T extends BlimuConfigInput>(config: T): T;
264
+
265
+ type InferResourceTypes<T> = T extends {
266
+ resources: infer R;
267
+ } ? R extends Record<string, any> ? keyof R : never : never;
268
+ type InferEntitlementTypes<T> = T extends {
269
+ entitlements: infer E;
270
+ } ? E extends Record<string, any> ? keyof E : never : never;
271
+ type InferPlanTypes<T> = T extends {
272
+ plans: infer P;
273
+ } ? P extends Record<string, any> ? keyof P : never : never;
274
+ type InferLimitTypes<T> = T extends {
275
+ plans: infer P;
276
+ } ? P extends Record<string, any> ? P[keyof P] extends {
277
+ resource_limits?: infer RL;
278
+ } ? RL extends Record<string, any> ? keyof RL : never : never : never : never;
279
+ type InferUsageLimitTypes<T> = T extends {
280
+ plans: infer P;
281
+ } ? P extends Record<string, any> ? P[keyof P] extends {
282
+ usage_based_limits?: infer UL;
283
+ } ? UL extends Record<string, any> ? keyof UL : never : never : never : never;
284
+
285
+ export { type BlimuConfig, BlimuConfigSchema, type EntitlementDefinition, EntitlementDefinitionSchema, type FeatureDefinition, FeatureDefinitionSchema, type InferEntitlementTypes, type InferLimitTypes, type InferPlanTypes, type InferResourceTypes, type InferUsageLimitTypes, type PlanDefinition, PlanDefinitionSchema, type ResourceDefinition, ResourceDefinitionSchema, defineConfig };
package/dist/index.js ADDED
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ BlimuConfigSchema: () => BlimuConfigSchema,
24
+ EntitlementDefinitionSchema: () => EntitlementDefinitionSchema,
25
+ FeatureDefinitionSchema: () => FeatureDefinitionSchema,
26
+ PlanDefinitionSchema: () => PlanDefinitionSchema,
27
+ ResourceDefinitionSchema: () => ResourceDefinitionSchema,
28
+ defineConfig: () => defineConfig
29
+ });
30
+ module.exports = __toCommonJS(index_exports);
31
+
32
+ // src/config/schema.ts
33
+ var import_zod = require("zod");
34
+ var ResourceDefinitionSchema = import_zod.z.object({
35
+ is_tenant: import_zod.z.boolean().optional(),
36
+ roles: import_zod.z.array(import_zod.z.string()).min(1, "At least one role must be defined"),
37
+ parents: import_zod.z.record(import_zod.z.string(), import_zod.z.object({ required: import_zod.z.boolean() })).optional(),
38
+ roles_inheritance: import_zod.z.record(
39
+ import_zod.z.string().min(1),
40
+ // local role
41
+ // Allow tokens containing letters, numbers, underscores or dashes
42
+ // Examples: parent->editor, organization->admin, workspace_v2->viewer
43
+ import_zod.z.array(import_zod.z.string().regex(/^([a-z0-9_-]+->)*[a-z0-9_-]+$/i)).min(1)
44
+ ).optional()
45
+ });
46
+ var EntitlementDefinitionSchema = import_zod.z.object({
47
+ roles: import_zod.z.array(import_zod.z.string()).min(1).optional(),
48
+ plans: import_zod.z.array(import_zod.z.string()).optional(),
49
+ limit: import_zod.z.string().optional()
50
+ // Reference to usage-based limit
51
+ });
52
+ var FeatureDefinitionSchema = import_zod.z.object({
53
+ name: import_zod.z.string(),
54
+ summary: import_zod.z.string().optional(),
55
+ entitlements: import_zod.z.array(import_zod.z.string()).optional(),
56
+ plans: import_zod.z.array(import_zod.z.string()).optional(),
57
+ default_enabled: import_zod.z.boolean().optional()
58
+ });
59
+ var PlanDefinitionSchema = import_zod.z.object({
60
+ name: import_zod.z.string().min(1, "Plan name is required"),
61
+ summary: import_zod.z.string().optional(),
62
+ description: import_zod.z.string().min(1, "Plan description is required").optional(),
63
+ resource_limits: import_zod.z.record(import_zod.z.string(), import_zod.z.number().int().min(0)).optional(),
64
+ usage_based_limits: import_zod.z.record(
65
+ import_zod.z.string(),
66
+ import_zod.z.object({
67
+ value: import_zod.z.number().int().min(0),
68
+ period: import_zod.z.enum(["monthly", "yearly", "lifetime"])
69
+ })
70
+ ).optional()
71
+ });
72
+ var BlimuConfigSchema = import_zod.z.object({
73
+ resources: import_zod.z.record(import_zod.z.string().min(1), ResourceDefinitionSchema),
74
+ entitlements: import_zod.z.record(import_zod.z.string().min(1), EntitlementDefinitionSchema).optional(),
75
+ features: import_zod.z.record(import_zod.z.string().min(1), FeatureDefinitionSchema).optional(),
76
+ plans: import_zod.z.record(import_zod.z.string().min(1), PlanDefinitionSchema).optional()
77
+ });
78
+
79
+ // src/config/define-config.ts
80
+ function defineConfig(config) {
81
+ const validated = BlimuConfigSchema.parse(config);
82
+ return config;
83
+ }
84
+ // Annotate the CommonJS export names for ESM import in node:
85
+ 0 && (module.exports = {
86
+ BlimuConfigSchema,
87
+ EntitlementDefinitionSchema,
88
+ FeatureDefinitionSchema,
89
+ PlanDefinitionSchema,
90
+ ResourceDefinitionSchema,
91
+ defineConfig
92
+ });
93
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/config/schema.ts","../src/config/define-config.ts"],"sourcesContent":["// Library exports for programmatic usage\n\n/**\n * Configuration utilities\n */\nexport { defineConfig } from './config/define-config';\nexport type {\n BlimuConfig,\n ResourceDefinition,\n EntitlementDefinition,\n FeatureDefinition,\n PlanDefinition,\n} from './config/schema';\nexport {\n BlimuConfigSchema,\n ResourceDefinitionSchema,\n EntitlementDefinitionSchema,\n FeatureDefinitionSchema,\n PlanDefinitionSchema,\n} from './config/schema';\n\n/**\n * Type inference utilities\n */\nexport type {\n InferResourceTypes,\n InferEntitlementTypes,\n InferPlanTypes,\n InferLimitTypes,\n InferUsageLimitTypes,\n} from './types/infer';\n","import { z } from 'zod';\n\n/**\n * Zod schema for resource definition\n */\nexport const ResourceDefinitionSchema = z.object({\n is_tenant: z.boolean().optional(),\n roles: z.array(z.string()).min(1, 'At least one role must be defined'),\n parents: z.record(z.string(), z.object({ required: z.boolean() })).optional(),\n roles_inheritance: z\n .record(\n z.string().min(1), // local role\n // Allow tokens containing letters, numbers, underscores or dashes\n // Examples: parent->editor, organization->admin, workspace_v2->viewer\n z.array(z.string().regex(/^([a-z0-9_-]+->)*[a-z0-9_-]+$/i)).min(1),\n )\n .optional(),\n});\n\n/**\n * Zod schema for entitlement definition\n */\nexport const EntitlementDefinitionSchema = z.object({\n roles: z.array(z.string()).min(1).optional(),\n plans: z.array(z.string()).optional(),\n limit: z.string().optional(), // Reference to usage-based limit\n});\n\n/**\n * Zod schema for feature definition\n */\nexport const FeatureDefinitionSchema = z.object({\n name: z.string(),\n summary: z.string().optional(),\n entitlements: z.array(z.string()).optional(),\n plans: z.array(z.string()).optional(),\n default_enabled: z.boolean().optional(),\n});\n\n/**\n * Zod schema for plan definition\n */\nexport const PlanDefinitionSchema = z.object({\n name: z.string().min(1, 'Plan name is required'),\n summary: z.string().optional(),\n description: z.string().min(1, 'Plan description is required').optional(),\n resource_limits: z.record(z.string(), z.number().int().min(0)).optional(),\n usage_based_limits: z\n .record(\n z.string(),\n z.object({\n value: z.number().int().min(0),\n period: z.enum(['monthly', 'yearly', 'lifetime']),\n }),\n )\n .optional(),\n});\n\n/**\n * Zod schema for complete Blimu configuration\n */\nexport const BlimuConfigSchema = z.object({\n resources: z.record(z.string().min(1), ResourceDefinitionSchema),\n entitlements: z.record(z.string().min(1), EntitlementDefinitionSchema).optional(),\n features: z.record(z.string().min(1), FeatureDefinitionSchema).optional(),\n plans: z.record(z.string().min(1), PlanDefinitionSchema).optional(),\n});\n\n/**\n * Type inference from schemas\n */\nexport type ResourceDefinition = z.infer<typeof ResourceDefinitionSchema>;\nexport type EntitlementDefinition = z.infer<typeof EntitlementDefinitionSchema>;\nexport type FeatureDefinition = z.infer<typeof FeatureDefinitionSchema>;\nexport type PlanDefinition = z.infer<typeof PlanDefinitionSchema>;\nexport type BlimuConfig = z.infer<typeof BlimuConfigSchema>;\n","import {\n BlimuConfigSchema,\n type BlimuConfig,\n type ResourceDefinition,\n type EntitlementDefinition,\n type FeatureDefinition,\n type PlanDefinition,\n} from './schema';\n\n/**\n * Input type for defineConfig (allows partial config during definition)\n * Uses proper types inferred from Zod schemas for full type safety\n */\nexport type BlimuConfigInput = {\n resources: Record<string, ResourceDefinition>;\n entitlements?: Record<string, EntitlementDefinition>;\n features?: Record<string, FeatureDefinition>;\n plans?: Record<string, PlanDefinition>;\n};\n\n/**\n * Defines and validates a Blimu configuration.\n *\n * This function validates the config using Zod schemas and returns\n * a type-safe, validated configuration object.\n *\n * @param config - The Blimu configuration object\n * @returns The validated configuration\n * @throws {z.ZodError} If the configuration is invalid\n *\n * @example\n * ```typescript\n * import { defineConfig } from 'blimu';\n *\n * export default defineConfig({\n * resources: {\n * workspace: {\n * roles: ['admin', 'editor', 'viewer'],\n * is_tenant: true,\n * },\n * },\n * entitlements: {\n * 'workspace:read': {\n * roles: ['admin', 'editor', 'viewer'],\n * },\n * },\n * });\n * ```\n */\nexport function defineConfig<T extends BlimuConfigInput>(config: T): T {\n // Validate the config using Zod schema\n const validated = BlimuConfigSchema.parse(config);\n\n // Return the original config (with proper typing) after validation\n // This preserves the exact structure and types from the input\n return config as T & BlimuConfig;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,iBAAkB;AAKX,IAAM,2BAA2B,aAAE,OAAO;AAAA,EAC/C,WAAW,aAAE,QAAQ,EAAE,SAAS;AAAA,EAChC,OAAO,aAAE,MAAM,aAAE,OAAO,CAAC,EAAE,IAAI,GAAG,mCAAmC;AAAA,EACrE,SAAS,aAAE,OAAO,aAAE,OAAO,GAAG,aAAE,OAAO,EAAE,UAAU,aAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,SAAS;AAAA,EAC5E,mBAAmB,aAChB;AAAA,IACC,aAAE,OAAO,EAAE,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,IAGhB,aAAE,MAAM,aAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC,EAAE,IAAI,CAAC;AAAA,EACnE,EACC,SAAS;AACd,CAAC;AAKM,IAAM,8BAA8B,aAAE,OAAO;AAAA,EAClD,OAAO,aAAE,MAAM,aAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EAC3C,OAAO,aAAE,MAAM,aAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACpC,OAAO,aAAE,OAAO,EAAE,SAAS;AAAA;AAC7B,CAAC;AAKM,IAAM,0BAA0B,aAAE,OAAO;AAAA,EAC9C,MAAM,aAAE,OAAO;AAAA,EACf,SAAS,aAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,cAAc,aAAE,MAAM,aAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EAC3C,OAAO,aAAE,MAAM,aAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACpC,iBAAiB,aAAE,QAAQ,EAAE,SAAS;AACxC,CAAC;AAKM,IAAM,uBAAuB,aAAE,OAAO;AAAA,EAC3C,MAAM,aAAE,OAAO,EAAE,IAAI,GAAG,uBAAuB;AAAA,EAC/C,SAAS,aAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,aAAa,aAAE,OAAO,EAAE,IAAI,GAAG,8BAA8B,EAAE,SAAS;AAAA,EACxE,iBAAiB,aAAE,OAAO,aAAE,OAAO,GAAG,aAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,SAAS;AAAA,EACxE,oBAAoB,aACjB;AAAA,IACC,aAAE,OAAO;AAAA,IACT,aAAE,OAAO;AAAA,MACP,OAAO,aAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC;AAAA,MAC7B,QAAQ,aAAE,KAAK,CAAC,WAAW,UAAU,UAAU,CAAC;AAAA,IAClD,CAAC;AAAA,EACH,EACC,SAAS;AACd,CAAC;AAKM,IAAM,oBAAoB,aAAE,OAAO;AAAA,EACxC,WAAW,aAAE,OAAO,aAAE,OAAO,EAAE,IAAI,CAAC,GAAG,wBAAwB;AAAA,EAC/D,cAAc,aAAE,OAAO,aAAE,OAAO,EAAE,IAAI,CAAC,GAAG,2BAA2B,EAAE,SAAS;AAAA,EAChF,UAAU,aAAE,OAAO,aAAE,OAAO,EAAE,IAAI,CAAC,GAAG,uBAAuB,EAAE,SAAS;AAAA,EACxE,OAAO,aAAE,OAAO,aAAE,OAAO,EAAE,IAAI,CAAC,GAAG,oBAAoB,EAAE,SAAS;AACpE,CAAC;;;ACjBM,SAAS,aAAyC,QAAc;AAErE,QAAM,YAAY,kBAAkB,MAAM,MAAM;AAIhD,SAAO;AACT;","names":[]}
package/dist/index.mjs ADDED
@@ -0,0 +1,61 @@
1
+ // src/config/schema.ts
2
+ import { z } from "zod";
3
+ var ResourceDefinitionSchema = z.object({
4
+ is_tenant: z.boolean().optional(),
5
+ roles: z.array(z.string()).min(1, "At least one role must be defined"),
6
+ parents: z.record(z.string(), z.object({ required: z.boolean() })).optional(),
7
+ roles_inheritance: z.record(
8
+ z.string().min(1),
9
+ // local role
10
+ // Allow tokens containing letters, numbers, underscores or dashes
11
+ // Examples: parent->editor, organization->admin, workspace_v2->viewer
12
+ z.array(z.string().regex(/^([a-z0-9_-]+->)*[a-z0-9_-]+$/i)).min(1)
13
+ ).optional()
14
+ });
15
+ var EntitlementDefinitionSchema = z.object({
16
+ roles: z.array(z.string()).min(1).optional(),
17
+ plans: z.array(z.string()).optional(),
18
+ limit: z.string().optional()
19
+ // Reference to usage-based limit
20
+ });
21
+ var FeatureDefinitionSchema = z.object({
22
+ name: z.string(),
23
+ summary: z.string().optional(),
24
+ entitlements: z.array(z.string()).optional(),
25
+ plans: z.array(z.string()).optional(),
26
+ default_enabled: z.boolean().optional()
27
+ });
28
+ var PlanDefinitionSchema = z.object({
29
+ name: z.string().min(1, "Plan name is required"),
30
+ summary: z.string().optional(),
31
+ description: z.string().min(1, "Plan description is required").optional(),
32
+ resource_limits: z.record(z.string(), z.number().int().min(0)).optional(),
33
+ usage_based_limits: z.record(
34
+ z.string(),
35
+ z.object({
36
+ value: z.number().int().min(0),
37
+ period: z.enum(["monthly", "yearly", "lifetime"])
38
+ })
39
+ ).optional()
40
+ });
41
+ var BlimuConfigSchema = z.object({
42
+ resources: z.record(z.string().min(1), ResourceDefinitionSchema),
43
+ entitlements: z.record(z.string().min(1), EntitlementDefinitionSchema).optional(),
44
+ features: z.record(z.string().min(1), FeatureDefinitionSchema).optional(),
45
+ plans: z.record(z.string().min(1), PlanDefinitionSchema).optional()
46
+ });
47
+
48
+ // src/config/define-config.ts
49
+ function defineConfig(config) {
50
+ const validated = BlimuConfigSchema.parse(config);
51
+ return config;
52
+ }
53
+ export {
54
+ BlimuConfigSchema,
55
+ EntitlementDefinitionSchema,
56
+ FeatureDefinitionSchema,
57
+ PlanDefinitionSchema,
58
+ ResourceDefinitionSchema,
59
+ defineConfig
60
+ };
61
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config/schema.ts","../src/config/define-config.ts"],"sourcesContent":["import { z } from 'zod';\n\n/**\n * Zod schema for resource definition\n */\nexport const ResourceDefinitionSchema = z.object({\n is_tenant: z.boolean().optional(),\n roles: z.array(z.string()).min(1, 'At least one role must be defined'),\n parents: z.record(z.string(), z.object({ required: z.boolean() })).optional(),\n roles_inheritance: z\n .record(\n z.string().min(1), // local role\n // Allow tokens containing letters, numbers, underscores or dashes\n // Examples: parent->editor, organization->admin, workspace_v2->viewer\n z.array(z.string().regex(/^([a-z0-9_-]+->)*[a-z0-9_-]+$/i)).min(1),\n )\n .optional(),\n});\n\n/**\n * Zod schema for entitlement definition\n */\nexport const EntitlementDefinitionSchema = z.object({\n roles: z.array(z.string()).min(1).optional(),\n plans: z.array(z.string()).optional(),\n limit: z.string().optional(), // Reference to usage-based limit\n});\n\n/**\n * Zod schema for feature definition\n */\nexport const FeatureDefinitionSchema = z.object({\n name: z.string(),\n summary: z.string().optional(),\n entitlements: z.array(z.string()).optional(),\n plans: z.array(z.string()).optional(),\n default_enabled: z.boolean().optional(),\n});\n\n/**\n * Zod schema for plan definition\n */\nexport const PlanDefinitionSchema = z.object({\n name: z.string().min(1, 'Plan name is required'),\n summary: z.string().optional(),\n description: z.string().min(1, 'Plan description is required').optional(),\n resource_limits: z.record(z.string(), z.number().int().min(0)).optional(),\n usage_based_limits: z\n .record(\n z.string(),\n z.object({\n value: z.number().int().min(0),\n period: z.enum(['monthly', 'yearly', 'lifetime']),\n }),\n )\n .optional(),\n});\n\n/**\n * Zod schema for complete Blimu configuration\n */\nexport const BlimuConfigSchema = z.object({\n resources: z.record(z.string().min(1), ResourceDefinitionSchema),\n entitlements: z.record(z.string().min(1), EntitlementDefinitionSchema).optional(),\n features: z.record(z.string().min(1), FeatureDefinitionSchema).optional(),\n plans: z.record(z.string().min(1), PlanDefinitionSchema).optional(),\n});\n\n/**\n * Type inference from schemas\n */\nexport type ResourceDefinition = z.infer<typeof ResourceDefinitionSchema>;\nexport type EntitlementDefinition = z.infer<typeof EntitlementDefinitionSchema>;\nexport type FeatureDefinition = z.infer<typeof FeatureDefinitionSchema>;\nexport type PlanDefinition = z.infer<typeof PlanDefinitionSchema>;\nexport type BlimuConfig = z.infer<typeof BlimuConfigSchema>;\n","import {\n BlimuConfigSchema,\n type BlimuConfig,\n type ResourceDefinition,\n type EntitlementDefinition,\n type FeatureDefinition,\n type PlanDefinition,\n} from './schema';\n\n/**\n * Input type for defineConfig (allows partial config during definition)\n * Uses proper types inferred from Zod schemas for full type safety\n */\nexport type BlimuConfigInput = {\n resources: Record<string, ResourceDefinition>;\n entitlements?: Record<string, EntitlementDefinition>;\n features?: Record<string, FeatureDefinition>;\n plans?: Record<string, PlanDefinition>;\n};\n\n/**\n * Defines and validates a Blimu configuration.\n *\n * This function validates the config using Zod schemas and returns\n * a type-safe, validated configuration object.\n *\n * @param config - The Blimu configuration object\n * @returns The validated configuration\n * @throws {z.ZodError} If the configuration is invalid\n *\n * @example\n * ```typescript\n * import { defineConfig } from 'blimu';\n *\n * export default defineConfig({\n * resources: {\n * workspace: {\n * roles: ['admin', 'editor', 'viewer'],\n * is_tenant: true,\n * },\n * },\n * entitlements: {\n * 'workspace:read': {\n * roles: ['admin', 'editor', 'viewer'],\n * },\n * },\n * });\n * ```\n */\nexport function defineConfig<T extends BlimuConfigInput>(config: T): T {\n // Validate the config using Zod schema\n const validated = BlimuConfigSchema.parse(config);\n\n // Return the original config (with proper typing) after validation\n // This preserves the exact structure and types from the input\n return config as T & BlimuConfig;\n}\n"],"mappings":";AAAA,SAAS,SAAS;AAKX,IAAM,2BAA2B,EAAE,OAAO;AAAA,EAC/C,WAAW,EAAE,QAAQ,EAAE,SAAS;AAAA,EAChC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,GAAG,mCAAmC;AAAA,EACrE,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,SAAS;AAAA,EAC5E,mBAAmB,EAChB;AAAA,IACC,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,IAGhB,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC,EAAE,IAAI,CAAC;AAAA,EACnE,EACC,SAAS;AACd,CAAC;AAKM,IAAM,8BAA8B,EAAE,OAAO;AAAA,EAClD,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EAC3C,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACpC,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA;AAC7B,CAAC;AAKM,IAAM,0BAA0B,EAAE,OAAO;AAAA,EAC9C,MAAM,EAAE,OAAO;AAAA,EACf,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EAC3C,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACpC,iBAAiB,EAAE,QAAQ,EAAE,SAAS;AACxC,CAAC;AAKM,IAAM,uBAAuB,EAAE,OAAO;AAAA,EAC3C,MAAM,EAAE,OAAO,EAAE,IAAI,GAAG,uBAAuB;AAAA,EAC/C,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,aAAa,EAAE,OAAO,EAAE,IAAI,GAAG,8BAA8B,EAAE,SAAS;AAAA,EACxE,iBAAiB,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,SAAS;AAAA,EACxE,oBAAoB,EACjB;AAAA,IACC,EAAE,OAAO;AAAA,IACT,EAAE,OAAO;AAAA,MACP,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC;AAAA,MAC7B,QAAQ,EAAE,KAAK,CAAC,WAAW,UAAU,UAAU,CAAC;AAAA,IAClD,CAAC;AAAA,EACH,EACC,SAAS;AACd,CAAC;AAKM,IAAM,oBAAoB,EAAE,OAAO;AAAA,EACxC,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,wBAAwB;AAAA,EAC/D,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,2BAA2B,EAAE,SAAS;AAAA,EAChF,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,uBAAuB,EAAE,SAAS;AAAA,EACxE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,oBAAoB,EAAE,SAAS;AACpE,CAAC;;;ACjBM,SAAS,aAAyC,QAAc;AAErE,QAAM,YAAY,kBAAkB,MAAM,MAAM;AAIhD,SAAO;AACT;","names":[]}
package/dist/main.js ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ "use strict";var b=Object.create;var y=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames;var C=Object.getPrototypeOf,I=Object.prototype.hasOwnProperty;var $=(i,t,s,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of w(t))!I.call(i,e)&&e!==s&&y(i,e,{get:()=>t[e],enumerable:!(o=j(t,e))||o.enumerable});return i};var f=(i,t,s)=>(s=i!=null?b(C(i)):{},$(t||!i||!i.__esModule?y(s,"default",{value:i,enumerable:!0}):s,i));var T=require("commander");var n=f(require("path")),h=f(require("fs")),r=f(require("@clack/prompts"));var c=f(require("fs")),p=f(require("path"));function d(i){let{configPath:t,outputPath:s,typesPackages:o=["@blimu/types","@blimu/backend"]}=i,e=[],a=o.join(" and ");e.push("/**"),e.push(` * Type Augmentation for ${a}`),e.push(" *"),e.push(` * This file augments the ${a} packages with union types`),e.push(" * specific to your environment configuration."),e.push(" *"),e.push(" * Types are automatically inferred from your blimu.config.ts file."),e.push(" * No regeneration needed when you update your config!"),e.push(" *"),e.push(" * Make sure to include this file in your tsconfig.json:"),e.push(" * {"),e.push(' * "include": ["blimu-types.d.ts"]'),e.push(" * }"),e.push(" */"),e.push("");let u=p.dirname(s),l=p.isAbsolute(t)?p.resolve(t):p.resolve(u,t),m=p.relative(u,l).replace(/\.(ts|mjs|js)$/,""),k=m.startsWith(".")?m:`./${m}`;e.push(`import type config from '${k}';`),e.push("import type {"),e.push(" InferResourceTypes,"),e.push(" InferEntitlementTypes,"),e.push(" InferPlanTypes,"),e.push(" InferLimitTypes,"),e.push(" InferUsageLimitTypes,"),e.push("} from 'blimu';"),e.push("");for(let v of o)e.push(`declare module '${v}' {`),e.push(" /**"),e.push(" * Resource types inferred from your Blimu configuration."),e.push(" */"),e.push(" type ResourceType = InferResourceTypes<typeof config>;"),e.push(""),e.push(" /**"),e.push(" * Entitlement types inferred from your Blimu configuration."),e.push(" */"),e.push(" type EntitlementType = InferEntitlementTypes<typeof config>;"),e.push(""),e.push(" /**"),e.push(" * Plan types inferred from your Blimu configuration."),e.push(" */"),e.push(" type PlanType = InferPlanTypes<typeof config>;"),e.push(""),e.push(" /**"),e.push(" * Limit types inferred from your Blimu configuration."),e.push(" */"),e.push(" type LimitType = InferLimitTypes<typeof config>;"),e.push(""),e.push(" /**"),e.push(" * Usage limit types inferred from your Blimu configuration."),e.push(" */"),e.push(" type UsageLimitType = InferUsageLimitTypes<typeof config>;"),e.push("}"),e.push("");c.existsSync(u)||c.mkdirSync(u,{recursive:!0}),c.writeFileSync(s,e.join(`
3
+ `),"utf-8")}function x(){let i=[n.join(process.cwd(),"blimu.config.ts"),n.join(process.cwd(),"blimu.config.mjs"),n.join(process.cwd(),"blimu.config.js")];for(let t of i)if(h.existsSync(t))return t;return null}function A(i,t){let o=n.relative(i,t).replace(/\.(ts|mjs|js)$/,"");return o.startsWith(".")?o:`./${o}`}function P(i){i.command("codegen").description("Generate type augmentation file from Blimu config").option("--config <path>","Path to Blimu config file (defaults to blimu.config.ts in project root)").option("--output <path>","Output path for generated type augmentation file (defaults to blimu-types.d.ts in project root)").action(async t=>{let s=r.spinner();try{let o=t.config||x();o||(r.cancel("No config file found. Please provide --config or ensure blimu.config.ts exists in project root."),process.exit(1));let e=n.isAbsolute(o)?o:n.resolve(process.cwd(),o);h.existsSync(e)||(r.cancel(`Config file not found: ${e}`),process.exit(1)),r.log.step(`Using config file: ${e}`);let a=t.output?n.isAbsolute(t.output)?t.output:n.resolve(process.cwd(),t.output):n.join(process.cwd(),"blimu-types.d.ts");r.log.step(`Output: ${a}`);let u=n.dirname(a),l=A(u,e);s.start("Generating type augmentation file with type inference..."),d({configPath:l,outputPath:a}),s.stop("\u26A1\uFE0F Successfully generated type augmentation file"),r.log.success(`Generated at: ${a}`),r.log.info("\u{1F4A1} Tip: Types are automatically inferred from your config."),r.log.info(" No regeneration needed when you update blimu.config.ts!")}catch(o){s.stop("\u274C Failed to generate type augmentation"),r.log.error(`Failed to generate type augmentation: ${o instanceof Error?o.message:String(o)}`),o instanceof Error&&o.stack&&r.log.error(o.stack),process.exit(1)}})}var g=new T.Command;g.name("blimu").description("Blimu - Authorization as a Service CLI").version(process.env.npm_package_version||"0.7.0");P(g);g.parse();
4
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/main.ts","../src/commands/codegen.ts","../src/utils/type-augmentation-generator.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { codegenCommand } from './commands/codegen';\n\nconst program = new Command();\n\nprogram\n .name('blimu')\n .description('Blimu - Authorization as a Service CLI')\n .version(process.env.npm_package_version || '0.7.0');\n\n// Register commands\ncodegenCommand(program);\n\n// Parse arguments\nprogram.parse();\n","import { Command } from 'commander';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport * as clack from '@clack/prompts';\nimport { generateTypeAugmentationFile } from '../utils/type-augmentation-generator';\n\n/**\n * Find default config file in project root\n */\nfunction findDefaultConfig(): string | null {\n const possiblePaths = [\n path.join(process.cwd(), 'blimu.config.ts'),\n path.join(process.cwd(), 'blimu.config.mjs'),\n path.join(process.cwd(), 'blimu.config.js'),\n ];\n\n for (const configPath of possiblePaths) {\n if (fs.existsSync(configPath)) {\n return configPath;\n }\n }\n\n return null;\n}\n\n/**\n * Get relative import path from output directory to config file\n * Handles both relative paths and ensures proper extension handling\n */\nfunction getRelativeImportPath(fromDir: string, toFile: string): string {\n const relative = path.relative(fromDir, toFile);\n // Remove .ts/.mjs/.js extension for import\n const withoutExt = relative.replace(/\\.(ts|mjs|js)$/, '');\n // Ensure it starts with ./ or ../\n if (!withoutExt.startsWith('.')) {\n return `./${withoutExt}`;\n }\n return withoutExt;\n}\n\n/**\n * Register the codegen command\n */\nexport function codegenCommand(program: Command): void {\n program\n .command('codegen')\n .description('Generate type augmentation file from Blimu config')\n .option(\n '--config <path>',\n 'Path to Blimu config file (defaults to blimu.config.ts in project root)',\n )\n .option(\n '--output <path>',\n 'Output path for generated type augmentation file (defaults to blimu-types.d.ts in project root)',\n )\n .action(async (options) => {\n const spinner = clack.spinner();\n\n try {\n // Find config file\n const configPath = options.config || findDefaultConfig();\n if (!configPath) {\n clack.cancel(\n 'No config file found. Please provide --config or ensure blimu.config.ts exists in project root.',\n );\n process.exit(1);\n }\n\n // Resolve to absolute path\n const absoluteConfigPath = path.isAbsolute(configPath)\n ? configPath\n : path.resolve(process.cwd(), configPath);\n\n if (!fs.existsSync(absoluteConfigPath)) {\n clack.cancel(`Config file not found: ${absoluteConfigPath}`);\n process.exit(1);\n }\n\n clack.log.step(`Using config file: ${absoluteConfigPath}`);\n\n // Determine output path\n const outputPath = options.output\n ? path.isAbsolute(options.output)\n ? options.output\n : path.resolve(process.cwd(), options.output)\n : path.join(process.cwd(), 'blimu-types.d.ts');\n\n clack.log.step(`Output: ${outputPath}`);\n\n // Calculate relative path from output to config for import statement\n const outputDir = path.dirname(outputPath);\n const relativeConfigPath = getRelativeImportPath(outputDir, absoluteConfigPath);\n\n // Generate type augmentation file\n spinner.start('Generating type augmentation file with type inference...');\n\n generateTypeAugmentationFile({\n configPath: relativeConfigPath,\n outputPath,\n // Always augment both @blimu/types and @blimu/backend\n // This is an internal implementation detail, not user-configurable\n });\n\n spinner.stop('⚡️ Successfully generated type augmentation file');\n\n clack.log.success(`Generated at: ${outputPath}`);\n clack.log.info('💡 Tip: Types are automatically inferred from your config.');\n clack.log.info(' No regeneration needed when you update blimu.config.ts!');\n } catch (error) {\n spinner.stop('❌ Failed to generate type augmentation');\n clack.log.error(\n `Failed to generate type augmentation: ${error instanceof Error ? error.message : String(error)}`,\n );\n if (error instanceof Error && error.stack) {\n clack.log.error(error.stack);\n }\n process.exit(1);\n }\n });\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\n\n/**\n * Options for generating type augmentation file\n */\nexport interface GenerateTypeAugmentationOptions {\n /** Path to the config file (relative to output directory or absolute) */\n configPath: string;\n /** Output path for the generated type augmentation file */\n outputPath: string;\n /** Types package names to augment (defaults to ['@blimu/types', '@blimu/backend']) */\n typesPackages?: string[];\n}\n\n/**\n * Generate type augmentation file for @blimu/types and @blimu/backend using type inference utilities.\n *\n * This generates a .d.ts file that imports the config and uses type inference\n * utilities to automatically extract types from the config structure.\n *\n * @param options - Generation options\n */\nexport function generateTypeAugmentationFile(options: GenerateTypeAugmentationOptions): void {\n const { configPath, outputPath, typesPackages = ['@blimu/types', '@blimu/backend'] } = options;\n\n const lines: string[] = [];\n\n // Header\n const packageNames = typesPackages.join(' and ');\n lines.push('/**');\n lines.push(` * Type Augmentation for ${packageNames}`);\n lines.push(' *');\n lines.push(` * This file augments the ${packageNames} packages with union types`);\n lines.push(' * specific to your environment configuration.');\n lines.push(' *');\n lines.push(' * Types are automatically inferred from your blimu.config.ts file.');\n lines.push(' * No regeneration needed when you update your config!');\n lines.push(' *');\n lines.push(' * Make sure to include this file in your tsconfig.json:');\n lines.push(' * {');\n lines.push(' * \"include\": [\"blimu-types.d.ts\"]');\n lines.push(' * }');\n lines.push(' */');\n lines.push('');\n\n // Calculate output directory and relative import path\n const outputDir = path.dirname(outputPath);\n const resolvedConfigPath = path.isAbsolute(configPath)\n ? path.resolve(configPath)\n : path.resolve(outputDir, configPath);\n const relativeConfigPath = path.relative(outputDir, resolvedConfigPath);\n // Remove .ts/.mjs/.js extension and ensure it starts with ./\n const importPath = relativeConfigPath.replace(/\\.(ts|mjs|js)$/, '');\n const finalImportPath = importPath.startsWith('.') ? importPath : `./${importPath}`;\n\n // Import config and type utilities\n lines.push(`import type config from '${finalImportPath}';`);\n lines.push('import type {');\n lines.push(' InferResourceTypes,');\n lines.push(' InferEntitlementTypes,');\n lines.push(' InferPlanTypes,');\n lines.push(' InferLimitTypes,');\n lines.push(' InferUsageLimitTypes,');\n lines.push(\"} from 'blimu';\");\n lines.push('');\n\n // Generate module augmentation for each package\n for (const typesPackage of typesPackages) {\n lines.push(`declare module '${typesPackage}' {`);\n lines.push(' /**');\n lines.push(' * Resource types inferred from your Blimu configuration.');\n lines.push(' */');\n lines.push(' type ResourceType = InferResourceTypes<typeof config>;');\n lines.push('');\n lines.push(' /**');\n lines.push(' * Entitlement types inferred from your Blimu configuration.');\n lines.push(' */');\n lines.push(' type EntitlementType = InferEntitlementTypes<typeof config>;');\n lines.push('');\n lines.push(' /**');\n lines.push(' * Plan types inferred from your Blimu configuration.');\n lines.push(' */');\n lines.push(' type PlanType = InferPlanTypes<typeof config>;');\n lines.push('');\n lines.push(' /**');\n lines.push(' * Limit types inferred from your Blimu configuration.');\n lines.push(' */');\n lines.push(' type LimitType = InferLimitTypes<typeof config>;');\n lines.push('');\n lines.push(' /**');\n lines.push(' * Usage limit types inferred from your Blimu configuration.');\n lines.push(' */');\n lines.push(' type UsageLimitType = InferUsageLimitTypes<typeof config>;');\n lines.push('}');\n lines.push('');\n }\n\n // Ensure output directory exists\n if (!fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, { recursive: true });\n }\n\n // Write file\n fs.writeFileSync(outputPath, lines.join('\\n'), 'utf-8');\n}\n"],"mappings":"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","names":["import_commander","path","fs","clack","fs","path","generateTypeAugmentationFile","options","configPath","outputPath","typesPackages","lines","packageNames","outputDir","resolvedConfigPath","importPath","finalImportPath","typesPackage","findDefaultConfig","possiblePaths","configPath","getRelativeImportPath","fromDir","toFile","withoutExt","codegenCommand","program","options","spinner","absoluteConfigPath","outputPath","outputDir","relativeConfigPath","generateTypeAugmentationFile","error","program","codegenCommand"]}
package/package.json CHANGED
@@ -1,19 +1,34 @@
1
1
  {
2
2
  "name": "blimu",
3
- "version": "0.6.3",
4
- "description": "Blimu - Authorization as a Service",
5
- "main": "index.js",
6
- "types": "index.d.ts",
7
- "bin": "./bin/blimu",
3
+ "version": "1.1.0",
4
+ "description": "Blimu - Authorization as a Service CLI",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": "./dist/main.js",
8
8
  "files": [
9
- "index.js",
10
- "index.d.ts",
9
+ "dist",
11
10
  "README.md",
12
- "bin/**",
13
- "scripts/**"
11
+ "bin/**"
14
12
  ],
15
13
  "scripts": {
16
- "postinstall": "node scripts/postinstall.js"
14
+ "build": "tsup",
15
+ "dev": "tsx watch src/main.ts",
16
+ "type-check": "tsc --noEmit",
17
+ "test": "vitest run",
18
+ "test:watch": "vitest",
19
+ "prepublishOnly": "yarn build"
20
+ },
21
+ "dependencies": {
22
+ "@clack/prompts": "^0.11.0",
23
+ "commander": "^12.1.0",
24
+ "zod": "^3.23.8"
25
+ },
26
+ "devDependencies": {
27
+ "@types/node": "^25.0.8",
28
+ "tsup": "^8.5.1",
29
+ "tsx": "^4.21.0",
30
+ "typescript": "^5.9.3",
31
+ "vitest": "^4.0.16"
17
32
  },
18
33
  "repository": {
19
34
  "type": "git",
@@ -25,9 +40,10 @@
25
40
  "authorization",
26
41
  "rbac",
27
42
  "access-control",
28
- "permissions"
43
+ "permissions",
44
+ "cli"
29
45
  ],
30
46
  "engines": {
31
- "node": ">=18"
47
+ "node": ">=18.0.0"
32
48
  }
33
49
  }
package/bin/blimu DELETED
Binary file
package/index.d.ts DELETED
@@ -1,4 +0,0 @@
1
- // This package is a placeholder to reserve the "blimu" package name on npm
2
- // For the actual Blimu SDK, please use @blimu/backend, @blimu/client, or @blimu/nestjs
3
-
4
- export {};
package/index.js DELETED
@@ -1,4 +0,0 @@
1
- // This package is a placeholder to reserve the "blimu" package name on npm
2
- // For the actual Blimu SDK, please use @blimu/backend, @blimu/client, or @blimu/nestjs
3
-
4
- module.exports = {};
@@ -1,243 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const https = require('https');
4
- const fs = require('fs');
5
- const path = require('path');
6
- const { execSync } = require('child_process');
7
-
8
- const BIN_DIR = path.join(__dirname, '..', 'bin');
9
- const GITHUB_REPO = 'blimu-dev/blimu-cli';
10
-
11
- // Platform mapping
12
- const platformMap = {
13
- darwin: 'darwin',
14
- linux: 'linux',
15
- win32: 'windows',
16
- };
17
-
18
- // Architecture mapping
19
- const archMap = {
20
- x64: 'amd64',
21
- arm64: 'arm64',
22
- };
23
-
24
- function getPlatformInfo() {
25
- const platform = process.platform;
26
- const arch = process.arch;
27
-
28
- const goPlatform = platformMap[platform];
29
- const goArch = archMap[arch];
30
-
31
- if (!goPlatform || !goArch) {
32
- throw new Error(
33
- `Unsupported platform: ${platform}/${arch}. Supported platforms: darwin, linux, win32. Supported architectures: x64, arm64`,
34
- );
35
- }
36
-
37
- const binaryName = platform === 'win32' ? 'blimu.exe' : 'blimu';
38
- const assetName = `blimu-${goPlatform}-${goArch}${platform === 'win32' ? '.exe' : ''}`;
39
-
40
- return {
41
- platform: goPlatform,
42
- arch: goArch,
43
- binaryName,
44
- assetName,
45
- };
46
- }
47
-
48
- /**
49
- * Verify that an existing binary matches the current platform/architecture
50
- * Returns true if the binary is correct, false otherwise
51
- */
52
- function verifyBinaryArchitecture(binaryPath) {
53
- try {
54
- // Use 'file' command to check binary type (available on macOS and Linux)
55
- const output = execSync(`file "${binaryPath}"`, { encoding: 'utf8' });
56
-
57
- const platform = process.platform;
58
- const arch = process.arch;
59
-
60
- if (platform === 'darwin') {
61
- // macOS: should be "Mach-O 64-bit executable arm64" or "Mach-O 64-bit executable x86_64"
62
- const expectedArch = arch === 'arm64' ? 'arm64' : 'x86_64';
63
- if (!output.includes('Mach-O') || !output.includes(expectedArch)) {
64
- return false;
65
- }
66
- } else if (platform === 'linux') {
67
- // Linux: should be "ELF 64-bit LSB executable, x86-64" or "ELF 64-bit LSB executable, ARM aarch64"
68
- const expectedArch = arch === 'arm64' ? 'ARM aarch64' : 'x86-64';
69
- if (!output.includes('ELF') || !output.includes(expectedArch)) {
70
- return false;
71
- }
72
- } else if (platform === 'win32') {
73
- // Windows: should be "PE32+ executable"
74
- if (!output.includes('PE32+')) {
75
- return false;
76
- }
77
- }
78
-
79
- return true;
80
- } catch (err) {
81
- // If 'file' command fails or is not available, assume binary is incorrect to be safe
82
- // This will trigger a re-download
83
- return false;
84
- }
85
- }
86
-
87
- function downloadFile(url, dest) {
88
- return new Promise((resolve, reject) => {
89
- const file = fs.createWriteStream(dest);
90
- https
91
- .get(url, (response) => {
92
- if (response.statusCode === 302 || response.statusCode === 301) {
93
- // Follow redirect
94
- return downloadFile(response.headers.location, dest).then(resolve).catch(reject);
95
- }
96
- if (response.statusCode !== 200) {
97
- file.close();
98
- fs.unlinkSync(dest);
99
- reject(new Error(`Failed to download: ${response.statusCode} ${response.statusMessage}`));
100
- return;
101
- }
102
- response.pipe(file);
103
- file.on('finish', () => {
104
- file.close();
105
- resolve();
106
- });
107
- })
108
- .on('error', (err) => {
109
- file.close();
110
- if (fs.existsSync(dest)) {
111
- fs.unlinkSync(dest);
112
- }
113
- reject(err);
114
- });
115
- });
116
- }
117
-
118
- function getReleaseUrl(version, assetName) {
119
- return new Promise((resolve, reject) => {
120
- // Always use latest release - version parameter is ignored
121
- const tag = 'latest';
122
- const url = `https://api.github.com/repos/${GITHUB_REPO}/releases/${tag}`;
123
-
124
- https
125
- .get(
126
- url,
127
- {
128
- headers: {
129
- 'User-Agent': 'blimu-installer',
130
- Accept: 'application/vnd.github.v3+json',
131
- },
132
- },
133
- (res) => {
134
- let data = '';
135
- res.on('data', (chunk) => {
136
- data += chunk;
137
- });
138
- res.on('end', () => {
139
- if (res.statusCode === 404) {
140
- reject(
141
- new Error(
142
- `Latest CLI release not found. Please check the blimu-cli repository for available releases.`,
143
- ),
144
- );
145
- return;
146
- }
147
- if (res.statusCode !== 200) {
148
- reject(
149
- new Error(`Failed to fetch latest release: ${res.statusCode} ${res.statusMessage}`),
150
- );
151
- return;
152
- }
153
- try {
154
- const release = JSON.parse(data);
155
- const asset = release.assets.find((a) => a.name === assetName);
156
- if (!asset) {
157
- reject(new Error(`Asset ${assetName} not found in latest release`));
158
- return;
159
- }
160
- resolve(asset.browser_download_url);
161
- } catch (err) {
162
- reject(err);
163
- }
164
- });
165
- },
166
- )
167
- .on('error', reject);
168
- });
169
- }
170
-
171
- async function main(version) {
172
- try {
173
- // Always use latest version - version parameter is ignored for consistency
174
- // This ensures users always get the latest CLI features and fixes
175
- version = null;
176
-
177
- const { binaryName, assetName } = getPlatformInfo();
178
-
179
- // Create bin directory if it doesn't exist
180
- if (!fs.existsSync(BIN_DIR)) {
181
- fs.mkdirSync(BIN_DIR, { recursive: true });
182
- }
183
-
184
- const binaryPath = path.join(BIN_DIR, binaryName);
185
-
186
- // Check if binary already exists and is executable
187
- if (fs.existsSync(binaryPath)) {
188
- // Verify the binary matches the current platform/architecture
189
- const isCorrectArchitecture = verifyBinaryArchitecture(binaryPath);
190
-
191
- if (isCorrectArchitecture) {
192
- try {
193
- // Try to make it executable (Unix only)
194
- if (process.platform !== 'win32') {
195
- fs.chmodSync(binaryPath, 0o755);
196
- }
197
- console.log(`✅ Blimu CLI binary already exists at ${binaryPath}`);
198
- return;
199
- } catch (err) {
200
- // If we can't check/update permissions, continue to download
201
- }
202
- } else {
203
- // Binary exists but is for wrong platform/architecture - delete it
204
- console.log(`⚠️ Existing binary is for wrong platform/architecture, will re-download...`);
205
- try {
206
- fs.unlinkSync(binaryPath);
207
- } catch (err) {
208
- console.warn(`Warning: Could not delete incorrect binary: ${err.message}`);
209
- }
210
- }
211
- }
212
-
213
- console.log(
214
- `📥 Downloading Blimu CLI binary (latest) for ${process.platform}/${process.arch}...`,
215
- );
216
-
217
- // Get release download URL
218
- const downloadUrl = await getReleaseUrl(version, assetName);
219
- console.log(`🔗 Download URL: ${downloadUrl}`);
220
-
221
- // Download the binary
222
- await downloadFile(downloadUrl, binaryPath);
223
-
224
- // Make binary executable (Unix only)
225
- if (process.platform !== 'win32') {
226
- fs.chmodSync(binaryPath, 0o755);
227
- }
228
-
229
- console.log(`✅ Blimu CLI binary downloaded successfully to ${binaryPath}`);
230
- } catch (error) {
231
- console.error(`❌ Failed to download Blimu CLI binary: ${error.message}`);
232
- console.error(`\nYou can manually install it by running:`);
233
- console.error(` go install github.com/blimu-dev/blimu-cli/cmd/blimucli@latest`);
234
- console.error(`\nOr download from: https://github.com/${GITHUB_REPO}/releases/latest`);
235
- process.exit(1);
236
- }
237
- }
238
-
239
- if (require.main === module) {
240
- main();
241
- }
242
-
243
- module.exports = { main, getPlatformInfo };
@@ -1,22 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const { main } = require('./download-binary');
4
-
5
- // Only run download if we're in a production install (not in development)
6
- // Check if we're in node_modules (production install) or in the repo (development)
7
- const isProductionInstall = __dirname.includes('node_modules');
8
-
9
- if (isProductionInstall || process.env.BLIMU_DOWNLOAD_CLI !== 'false') {
10
- // Always download the latest CLI version
11
- main(null).catch((error) => {
12
- // Fail the install if binary download fails
13
- console.error('Error: Failed to download Blimu CLI binary during install.');
14
- console.error(error.message);
15
- console.error('\nThe package will download the latest available CLI version.');
16
- console.error('\nYou can manually install it by running:');
17
- console.error(' go install github.com/blimu-dev/blimu-cli/cmd/blimucli@latest');
18
- process.exit(1);
19
- });
20
- } else {
21
- console.log('Skipping Blimu CLI binary download (development mode)');
22
- }