blimu 1.2.1 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -78,7 +78,8 @@ var BlimuConfigSchema = import_zod.z.object({
78
78
 
79
79
  // src/config/define-config.ts
80
80
  function defineConfig(config) {
81
- const validated = BlimuConfigSchema.parse(config);
81
+ const _validated = BlimuConfigSchema.parse(config);
82
+ void _validated;
82
83
  return config;
83
84
  }
84
85
  // Annotate the CommonJS export names for ESM import in node:
@@ -1 +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":[]}
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 interface 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 void _validated;\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,aAAa,kBAAkB,MAAM,MAAM;AACjD,OAAK;AAIL,SAAO;AACT;","names":[]}
package/dist/index.d.mts CHANGED
@@ -76,32 +76,32 @@ type FeatureDefinition = z.infer<typeof FeatureDefinitionSchema>;
76
76
  type PlanDefinition = z.infer<typeof PlanDefinitionSchema>;
77
77
  type BlimuConfig = z.infer<typeof BlimuConfigSchema>;
78
78
 
79
- type BlimuConfigInput = {
79
+ interface BlimuConfigInput {
80
80
  resources: Record<string, ResourceDefinition>;
81
81
  entitlements?: Record<string, EntitlementDefinition>;
82
82
  features?: Record<string, FeatureDefinition>;
83
83
  plans?: Record<string, PlanDefinition>;
84
- };
84
+ }
85
85
  declare function defineConfig<T extends BlimuConfigInput>(config: T): T;
86
86
 
87
87
  type InferResourceTypes<T> = T extends {
88
88
  resources: infer R;
89
- } ? R extends Record<string, any> ? keyof R : never : never;
89
+ } ? R extends Record<string, unknown> ? keyof R : never : never;
90
90
  type InferEntitlementTypes<T> = T extends {
91
91
  entitlements: infer E;
92
- } ? E extends Record<string, any> ? keyof E : never : never;
92
+ } ? E extends Record<string, unknown> ? keyof E : never : never;
93
93
  type InferPlanTypes<T> = T extends {
94
94
  plans: infer P;
95
- } ? P extends Record<string, any> ? keyof P : never : never;
95
+ } ? P extends Record<string, unknown> ? keyof P : never : never;
96
96
  type InferLimitTypes<T> = T extends {
97
97
  plans: infer P;
98
- } ? P extends Record<string, any> ? P[keyof P] extends {
98
+ } ? P extends Record<string, unknown> ? P[keyof P] extends {
99
99
  resource_limits?: infer RL;
100
- } ? RL extends Record<string, any> ? keyof RL : never : never : never : never;
100
+ } ? RL extends Record<string, unknown> ? keyof RL : never : never : never : never;
101
101
  type InferUsageLimitTypes<T> = T extends {
102
102
  plans: infer P;
103
- } ? P extends Record<string, any> ? P[keyof P] extends {
103
+ } ? P extends Record<string, unknown> ? P[keyof P] extends {
104
104
  usage_based_limits?: infer UL;
105
- } ? UL extends Record<string, any> ? keyof UL : never : never : never : never;
105
+ } ? UL extends Record<string, unknown> ? keyof UL : never : never : never : never;
106
106
 
107
107
  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.d.ts CHANGED
@@ -76,32 +76,32 @@ type FeatureDefinition = z.infer<typeof FeatureDefinitionSchema>;
76
76
  type PlanDefinition = z.infer<typeof PlanDefinitionSchema>;
77
77
  type BlimuConfig = z.infer<typeof BlimuConfigSchema>;
78
78
 
79
- type BlimuConfigInput = {
79
+ interface BlimuConfigInput {
80
80
  resources: Record<string, ResourceDefinition>;
81
81
  entitlements?: Record<string, EntitlementDefinition>;
82
82
  features?: Record<string, FeatureDefinition>;
83
83
  plans?: Record<string, PlanDefinition>;
84
- };
84
+ }
85
85
  declare function defineConfig<T extends BlimuConfigInput>(config: T): T;
86
86
 
87
87
  type InferResourceTypes<T> = T extends {
88
88
  resources: infer R;
89
- } ? R extends Record<string, any> ? keyof R : never : never;
89
+ } ? R extends Record<string, unknown> ? keyof R : never : never;
90
90
  type InferEntitlementTypes<T> = T extends {
91
91
  entitlements: infer E;
92
- } ? E extends Record<string, any> ? keyof E : never : never;
92
+ } ? E extends Record<string, unknown> ? keyof E : never : never;
93
93
  type InferPlanTypes<T> = T extends {
94
94
  plans: infer P;
95
- } ? P extends Record<string, any> ? keyof P : never : never;
95
+ } ? P extends Record<string, unknown> ? keyof P : never : never;
96
96
  type InferLimitTypes<T> = T extends {
97
97
  plans: infer P;
98
- } ? P extends Record<string, any> ? P[keyof P] extends {
98
+ } ? P extends Record<string, unknown> ? P[keyof P] extends {
99
99
  resource_limits?: infer RL;
100
- } ? RL extends Record<string, any> ? keyof RL : never : never : never : never;
100
+ } ? RL extends Record<string, unknown> ? keyof RL : never : never : never : never;
101
101
  type InferUsageLimitTypes<T> = T extends {
102
102
  plans: infer P;
103
- } ? P extends Record<string, any> ? P[keyof P] extends {
103
+ } ? P extends Record<string, unknown> ? P[keyof P] extends {
104
104
  usage_based_limits?: infer UL;
105
- } ? UL extends Record<string, any> ? keyof UL : never : never : never : never;
105
+ } ? UL extends Record<string, unknown> ? keyof UL : never : never : never : never;
106
106
 
107
107
  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.mjs CHANGED
@@ -47,7 +47,8 @@ var BlimuConfigSchema = z.object({
47
47
 
48
48
  // src/config/define-config.ts
49
49
  function defineConfig(config) {
50
- const validated = BlimuConfigSchema.parse(config);
50
+ const _validated = BlimuConfigSchema.parse(config);
51
+ void _validated;
51
52
  return config;
52
53
  }
53
54
  export {
@@ -1 +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":[]}
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 interface 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 void _validated;\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,aAAa,kBAAkB,MAAM,MAAM;AACjD,OAAK;AAIL,SAAO;AACT;","names":[]}
package/dist/main.mjs ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ var le=Object.defineProperty;var kt=Object.getOwnPropertyDescriptor;var bt=Object.getOwnPropertyNames;var Rt=Object.prototype.hasOwnProperty;var S=(o,e)=>()=>(o&&(e=o(o=0)),e);var be=(o,e)=>{for(var t in e)le(o,t,{get:e[t],enumerable:!0})},Tt=(o,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of bt(e))!Rt.call(o,n)&&n!==t&&le(o,n,{get:()=>e[n],enumerable:!(r=kt(e,n))||r.enumerable});return o};var St=o=>Tt(le({},"__esModule",{value:!0}),o);import{useState as xt,useEffect as Pt}from"react";import{Text as b}from"ink";import{Fragment as $t,jsx as P,jsxs as K}from"react/jsx-runtime";var Et,Ut,Ot,de,xe=S(()=>{"use strict";Et={pending:"\u25CB",running:"\u25CB",success:"\u25CF",failed:"\u25CF"},Ut={pending:"gray",running:"cyan",success:"greenBright",failed:"red"},Ot=({color:o})=>{let[e,t]=xt(0);return Pt(()=>{let s=setInterval(()=>{t(a=>(a+1)%3)},400);return()=>clearInterval(s)},[]),P(b,{color:o,dimColor:e===0,bold:e===2,children:"\u25CB"})},de=({name:o,status:e,message:t,indent:r=0,isSubItem:n=!1,isFirstSubItem:s=!1})=>{let a=Et[e],m=Ut[e],d=t??o;return n?K(b,{children:[P(b,{children:s?" \u23BF ":" "}),P(b,{dimColor:e==="success",children:d})]}):K(b,{children:[e==="running"?K($t,{children:[P(Ot,{color:m}),P(b,{children:" "})]}):K(b,{color:m,children:[a," "]}),P(b,{dimColor:e==="success"||e==="pending",children:d})]})}});import{Text as Pe}from"ink";import{jsx as _t,jsxs as At}from"react/jsx-runtime";var fe,Ee=S(()=>{"use strict";fe=({type:o,message:e,indent:t=0,isSubItem:r=!1,isFirstSubItem:n=!1,dimmed:s=!1})=>At(Pe,{children:[r?n?" \u23BF ":" ":"",_t(Pe,{color:{info:"blueBright",warn:"yellow",error:"redBright",success:"greenBright"}[o],dimColor:s,children:e})]})});import{useState as Dt,useEffect as qt}from"react";import{Text as _,useInput as Bt}from"ink";import Mt from"clipboardy";import{jsx as W,jsxs as he}from"react/jsx-runtime";var Ft,Lt,Gt,Ue,Oe=S(()=>{"use strict";Ft=()=>process.stdin.isTTY&&typeof process.stdin.setRawMode=="function",Lt=({text:o,dimmed:e=!1,isSubItem:t=!1,isFirstSubItem:r=!1})=>he(_,{children:[t?r?" \u23BF ":" ":"",W(_,{color:"blueBright",dimColor:e,children:o})]}),Gt=({text:o,dimmed:e=!1,isSubItem:t=!1,isFirstSubItem:r=!1})=>{let[n,s]=Dt(!1),a=t?r?" \u23BF ":" ":"";return Bt(m=>{m==="c"&&Mt.write(o).then(()=>{s(!0)}).catch(()=>{})}),qt(()=>{if(n){let m=setTimeout(()=>{s(!1)},2e3);return()=>clearTimeout(m)}},[n]),he(_,{children:[a,W(_,{color:"blueBright",dimColor:e,children:o}),n&&he(_,{color:"green",dimColor:!1,children:[" ","(Copied!)"]})]})},Ue=o=>Ft()?W(Gt,{...o}):W(Lt,{...o})});import{Box as $e}from"ink";import{jsx as A,jsxs as _e}from"react/jsx-runtime";var Nt,ge,Ae=S(()=>{"use strict";xe();Ee();Oe();Nt=o=>{let e=o.filter(s=>s.type==="task"),t=o.filter(s=>s.type==="message"),r=t.some(s=>s.messageType==="error"),n=t.some(s=>s.messageType==="success");if(r)return"failed";if(n)return"success";if(e.length>0){if(e.some(s=>s.status==="failed"))return"failed";if(e.every(s=>s.status==="success"))return"success"}return"running"},ge=({groups:o,globalMessages:e})=>_e($e,{flexDirection:"column",children:[o.map(t=>{let r=Nt(t.items);return _e($e,{flexDirection:"column",children:[A(de,{name:t.name,status:r,indent:0,isSubItem:!1}),t.items.map((n,s)=>n.type==="task"?A(de,{name:n.name,status:n.status,...n.message!==void 0&&{message:n.message},indent:1,isSubItem:!0,isFirstSubItem:s===0},n.id):n.type==="copyable-text"?A(Ue,{text:n.text,isSubItem:!0,isFirstSubItem:s===0,...n.dimmed!==void 0&&{dimmed:n.dimmed}},n.id):A(fe,{type:n.messageType,message:n.message,isSubItem:!0,isFirstSubItem:s===0,...n.dimmed!==void 0&&{dimmed:n.dimmed}},n.id))]},t.id)}),e.map(t=>A(fe,{type:t.messageType,message:t.message,indent:0},t.id))]})});var qe={};be(qe,{InkTaskRunner:()=>Ie});import{render as jt}from"ink";import{jsx as De}from"react/jsx-runtime";var D,ye,ve,Ie,Be=S(()=>{"use strict";Ae();D=0,ye=class{constructor(e,t,r,n){this.groupId=e;this.taskId=t;this.state=r;this.rerender=n}updateTask(e){let t=this.state.groups.find(n=>n.id===this.groupId);if(!t)return;let r=t.items.find(n=>n.type==="task"&&n.id===this.taskId);r?.type==="task"&&(Object.assign(r,e),this.rerender())}update(e){this.updateTask({message:e})}succeed(e){let t={status:"success"};e!==void 0&&(t.message=e),this.updateTask(t)}fail(e){let t={status:"failed"};e!==void 0&&(t.message=e),this.updateTask(t)}},ve=class{constructor(e,t,r){this.groupId=e;this.state=t;this.rerender=r}getGroup(){let e=this.state.groups.find(t=>t.id===this.groupId);if(!e)throw new Error(`Group ${this.groupId} not found`);return e}async task(e,t){let r=`task-${D++}`,n=this.getGroup(),s={type:"task",id:r,name:e,status:"running"};n.items.push(s),this.rerender();let a=new ye(this.groupId,r,this.state,this.rerender);try{await t(a),s.status==="running"&&a.succeed()}catch(m){throw a.fail(),m}}addMessage(e,t,r){let n=this.getGroup(),s={type:"message",id:`msg-${D++}`,messageType:e,message:t};r?.clearable!==void 0&&(s.clearable=r.clearable),r?.dimmed!==void 0&&(s.dimmed=r.dimmed),n.items.push(s),this.rerender()}clearClearableItems(){let e=this.getGroup();e.items=e.items.filter(t=>!(t.type==="message"&&t.clearable||t.type==="copyable-text"&&t.clearable)),this.rerender()}info(e,t){this.addMessage("info",e,t)}warn(e,t){this.addMessage("warn",e,t)}error(e,t){this.addMessage("error",e,t)}success(e,t){this.clearClearableItems(),this.addMessage("success",e,t)}copyableText(e,t){let r=this.getGroup(),n={type:"copyable-text",id:`copyable-${D++}`,text:e};t?.clearable!==void 0&&(n.clearable=t.clearable),t?.dimmed!==void 0&&(n.dimmed=t.dimmed),r.items.push(n),this.rerender()}},Ie=class{state={groups:[],globalMessages:[]};renderInstance=null;isRendering=!1;rerender(){this.renderInstance&&this.renderInstance.rerender(De(ge,{groups:this.state.groups,globalMessages:this.state.globalMessages}))}ensureRendering(){if(!this.isRendering){this.renderInstance=jt(De(ge,{groups:this.state.groups,globalMessages:this.state.globalMessages})),this.isRendering=!0;let e=()=>{this.renderInstance&&this.renderInstance.cleanup()};process.on("exit",e),process.on("SIGINT",()=>{e(),process.exit(0)}),process.on("SIGTERM",()=>{e(),process.exit(0)})}}group(e){this.ensureRendering();let t=`group-${D++}`,r={id:t,name:e,items:[]};return this.state.groups.push(r),this.rerender(),new ve(t,this.state,this.rerender.bind(this))}addGlobalMessage(e,t,r){this.ensureRendering();let n={type:"message",id:`msg-${D++}`,messageType:e,message:t};r?.clearable!==void 0&&(n.clearable=r.clearable),r?.dimmed!==void 0&&(n.dimmed=r.dimmed),this.state.globalMessages.push(n),this.rerender()}info(e,t){this.addGlobalMessage("info",e,t)}warn(e,t){this.addGlobalMessage("warn",e,t)}error(e,t){this.addGlobalMessage("error",e,t)}success(e,t){this.addGlobalMessage("success",e,t)}async wait(){this.renderInstance&&(await this.renderInstance.waitUntilExit(),this.renderInstance.cleanup())}}});var ze={};be(ze,{CLIENT_IDS:()=>We,DEFAULT_ENVIRONMENT:()=>Qt,getClientId:()=>M});function M(o){let e=We[o];if(!e||e.startsWith("client_id_for_"))throw new Error(`Client ID not configured for environment: ${o}. Please update CLIENT_IDS in client-ids.ts`);return e}var We,Qt,oe=S(()=>{"use strict";We={"local-dev":"9MhKB71lI9jF5p5OSfykG4juDo5hiGYm","local-prod":"client_id_for_local_prod","cloud-dev":"client_id_for_cloud_dev","cloud-prod":"Vu_yzofw-d7AzNvR4k8ZHyj05zrQ8Qxp"};Qt="cloud-prod"});import{Command as xn}from"commander";import*as w from"path";import*as Me from"fs";import*as x from"fs";import*as k from"path";function Re(o){let{configPath:e,outputPath:t,typesPackages:r=["@blimu/types","@blimu/backend"]}=o,n=[],s=r.join(" and ");n.push("/**"),n.push(` * Type Augmentation for ${s}`),n.push(" *"),n.push(` * This file augments the ${s} packages with union types`),n.push(" * specific to your environment configuration."),n.push(" *"),n.push(" * Types are automatically inferred from your blimu.config.ts file."),n.push(" * No regeneration needed when you update your config!"),n.push(" *"),n.push(" * Make sure to include this file in your tsconfig.json:"),n.push(" * {"),n.push(' * "include": ["blimu-types.d.ts"]'),n.push(" * }"),n.push(" */"),n.push("");let a=k.dirname(t),m=k.isAbsolute(e)?k.resolve(e):k.resolve(a,e),c=k.relative(a,m).replace(/\.(ts|mjs|js)$/,""),p=c.startsWith(".")?c:`./${c}`;n.push(`import type config from '${p}';`),n.push("import type {"),n.push(" InferResourceTypes,"),n.push(" InferEntitlementTypes,"),n.push(" InferPlanTypes,"),n.push(" InferLimitTypes,"),n.push(" InferUsageLimitTypes,"),n.push("} from 'blimu';"),n.push("");for(let u of r)n.push(`declare module '${u}' {`),n.push(" /**"),n.push(" * Resource types inferred from your Blimu configuration."),n.push(" */"),n.push(" type ResourceType = InferResourceTypes<typeof config>;"),n.push(""),n.push(" /**"),n.push(" * Entitlement types inferred from your Blimu configuration."),n.push(" */"),n.push(" type EntitlementType = InferEntitlementTypes<typeof config>;"),n.push(""),n.push(" /**"),n.push(" * Plan types inferred from your Blimu configuration."),n.push(" */"),n.push(" type PlanType = InferPlanTypes<typeof config>;"),n.push(""),n.push(" /**"),n.push(" * Limit types inferred from your Blimu configuration."),n.push(" */"),n.push(" type LimitType = InferLimitTypes<typeof config>;"),n.push(""),n.push(" /**"),n.push(" * Usage limit types inferred from your Blimu configuration."),n.push(" */"),n.push(" type UsageLimitType = InferUsageLimitTypes<typeof config>;"),n.push("}"),n.push("");x.existsSync(a)||x.mkdirSync(a,{recursive:!0}),x.writeFileSync(t,n.join(`
3
+ `),"utf-8")}import*as v from"path";import*as $ from"fs";function j(){let o=[v.join(process.cwd(),"blimu.config.ts"),v.join(process.cwd(),"blimu.config.mjs"),v.join(process.cwd(),"blimu.config.js"),v.join(process.cwd(),"blimu.config.json")];for(let e of o)if($.existsSync(e))return e;return null}async function Te(o){let e=v.isAbsolute(o)?o:v.resolve(process.cwd(),o);if(!$.existsSync(e))throw new Error(`Config file not found: ${e}`);if(v.extname(e).toLowerCase()===".json"){let n=$.readFileSync(e,"utf-8");return JSON.parse(n)}let r=await import(e);return r.default??r}function Se(o,e){let r=v.relative(o,e).replace(/\.(ts|mjs|js)$/,"");return r.startsWith(".")?r:`./${r}`}async function C(){let{InkTaskRunner:o}=await Promise.resolve().then(()=>(Be(),qe));return new o}function Fe(o){o.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 e=>{let t=await C();try{let r=e.config||j();r||(t.error("No config file found. Please provide --config or ensure blimu.config.ts exists in project root."),await t.wait(),process.exit(1));let n=w.isAbsolute(r)?r:w.resolve(process.cwd(),r);Me.existsSync(n)||(t.error(`Config file not found: ${n}`),await t.wait(),process.exit(1)),t.info(`Using config file: ${n}`);let s=e.output?w.isAbsolute(e.output)?e.output:w.resolve(process.cwd(),e.output):w.join(process.cwd(),"blimu-types.d.ts");t.info(`Output: ${s}`),await t.group("Generating type augmentation").task("Generate types",m=>{let d=w.dirname(s),c=Se(d,n);m.update("Generating type augmentation file with type inference..."),Re({configPath:c,outputPath:s}),m.succeed("Type augmentation file generated")}),t.success(`Generated at: ${s}`),t.info("\u{1F4A1} Tip: Types are automatically inferred from your config."),t.info(" No regeneration needed when you update blimu.config.ts!"),await t.wait()}catch(r){t.error(`Failed to generate type augmentation: ${r instanceof Error?r.message:String(r)}`),r instanceof Error&&r.stack&&t.error(r.stack),await t.wait(),process.exit(1)}})}import{z as i}from"zod";var Kt=i.object({is_tenant:i.boolean().optional(),roles:i.array(i.string()).min(1,"At least one role must be defined"),parents:i.record(i.string(),i.object({required:i.boolean()})).optional(),roles_inheritance:i.record(i.string().min(1),i.array(i.string().regex(/^([a-z0-9_-]+->)*[a-z0-9_-]+$/i)).min(1)).optional()}),Wt=i.object({roles:i.array(i.string()).min(1).optional(),plans:i.array(i.string()).optional(),limit:i.string().optional()}),zt=i.object({name:i.string(),summary:i.string().optional(),entitlements:i.array(i.string()).optional(),plans:i.array(i.string()).optional(),default_enabled:i.boolean().optional()}),Vt=i.object({name:i.string().min(1,"Plan name is required"),summary:i.string().optional(),description:i.string().min(1,"Plan description is required").optional(),resource_limits:i.record(i.string(),i.number().int().min(0)).optional(),usage_based_limits:i.record(i.string(),i.object({value:i.number().int().min(0),period:i.enum(["monthly","yearly","lifetime"])})).optional()}),Le=i.object({resources:i.record(i.string().min(1),Kt),entitlements:i.record(i.string().min(1),Wt).optional(),features:i.record(i.string().min(1),zt).optional(),plans:i.record(i.string().min(1),Vt).optional()});import q from"chalk";var f={info:o=>{console.log(q.dim(o))},step:o=>{console.log(q.cyan(o))},success:o=>{console.log(q.green("\u2714"),o)},warn:o=>{console.log(q.yellow("\u26A0"),o)},error:o=>{console.error(q.red("\u2716"),o)}};import{FetchClient as Jt,FetchError as kr}from"@blimu/fetch";function Ge(o){let e=[...o?.authStrategies??[]];return o.bearer&&e.push({type:"bearer",token:o.bearer}),o.apiKey&&e.push({type:"apiKey",key:o.apiKey,location:"header",name:"X-API-KEY"}),e}var z=class{constructor(e){this.core=e}list(e,t,r){return this.core.request({method:"GET",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/api-keys`,...r??{}})}create(e,t,r,n){return this.core.request({method:"POST",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/api-keys`,body:r,...n??{}})}delete(e,t,r,n){return this.core.request({method:"DELETE",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/api-keys/${encodeURIComponent(r)}`,...n??{}})}get(e,t,r,n){return this.core.request({method:"GET",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/api-keys/${encodeURIComponent(r)}`,...n??{}})}reveal(e,t,r,n){return this.core.request({method:"POST",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/api-keys/${encodeURIComponent(r)}/reveal`,...n??{}})}};var V=class{constructor(e){this.core=e}get(e,t,r){return this.core.request({method:"GET",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/definitions`,...r??{}})}update(e,t,r,n){return this.core.request({method:"PUT",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/definitions`,body:r,...n??{}})}validate(e,t,r,n){return this.core.request({method:"POST",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/definitions/validate`,body:r,...n??{}})}};var J=class{constructor(e){this.core=e}getRecords(e,t,r){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/dns/records`,...r??{}})}validate(e,t,r){return this.core.request({method:"POST",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/dns/validate`,...r??{}})}};var Q=class{constructor(e){this.core=e}list(e,t,r){return this.core.request({method:"GET",path:`/v1/workspace/${encodeURIComponent(e)}/environments`,query:t,...r??{}})}create(e,t,r){return this.core.request({method:"POST",path:`/v1/workspace/${encodeURIComponent(e)}/environments`,body:t,...r??{}})}delete(e,t,r){return this.core.request({method:"DELETE",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}`,...r??{}})}read(e,t,r){return this.core.request({method:"GET",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}`,...r??{}})}update(e,t,r,n){return this.core.request({method:"PUT",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}`,body:r,...n??{}})}getAuthConfig(e,t,r){return this.core.request({method:"GET",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/auth-config`,...r??{}})}updateAuthConfig(e,t,r,n){return this.core.request({method:"PUT",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/auth-config`,body:r,...n??{}})}};var H=class{constructor(e){this.core=e}getAccess(e){return this.core.request({method:"GET",path:"/v1/me/access",...e??{}})}};var Y=class{constructor(e){this.core=e}list(e,t,r,n){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/oauth-apps`,query:r,...n??{}})}create(e,t,r,n){return this.core.request({method:"POST",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/oauth-apps`,body:r,...n??{}})}delete(e,t,r,n){return this.core.request({method:"DELETE",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/oauth-apps/${encodeURIComponent(r)}`,...n??{}})}getById(e,t,r,n){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/oauth-apps/${encodeURIComponent(r)}`,...n??{}})}update(e,t,r,n,s){return this.core.request({method:"PUT",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/oauth-apps/${encodeURIComponent(r)}`,body:n,...s??{}})}revokeAllTokens(e,t,r,n){return this.core.request({method:"POST",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/oauth-apps/${encodeURIComponent(r)}/revoke-all`,...n??{}})}rotateSecret(e,t,r,n){return this.core.request({method:"POST",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/oauth-apps/${encodeURIComponent(r)}/rotate-secret`,...n??{}})}listTokens(e,t,r,n,s){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/oauth-apps/${encodeURIComponent(r)}/tokens`,query:n,...s??{}})}};var X=class{constructor(e){this.core=e}list(e,t,r,n){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/resources`,query:r,...n??{}})}create(e,t,r,n){return this.core.request({method:"POST",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/resources`,body:r,...n??{}})}delete(e,t,r,n,s){return this.core.request({method:"DELETE",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/resources/${encodeURIComponent(r)}/${encodeURIComponent(n)}`,...s??{}})}get(e,t,r,n,s){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/resources/${encodeURIComponent(r)}/${encodeURIComponent(n)}`,...s??{}})}update(e,t,r,n,s,a){return this.core.request({method:"PUT",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/resources/${encodeURIComponent(r)}/${encodeURIComponent(n)}`,body:s,...a??{}})}listChildren(e,t,r,n,s,a){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/resources/${encodeURIComponent(r)}/${encodeURIComponent(n)}/children`,query:s,...a??{}})}getResourceUsers(e,t,r,n,s,a){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/resources/${encodeURIComponent(r)}/${encodeURIComponent(n)}/users`,query:s,...a??{}})}};var Z=class{constructor(e){this.core=e}provision(e,t,r){return this.core.request({method:"POST",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/ssl/provision`,...r??{}})}getStatus(e,t,r){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/ssl/status`,...r??{}})}};var ee=class{constructor(e){this.core=e}list(e,t,r,n){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/users`,query:r,...n??{}})}get(e,t,r,n){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/users/${encodeURIComponent(r)}`,...n??{}})}getUserResources(e,t,r,n){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/users/${encodeURIComponent(r)}/resources`,...n??{}})}};var te=class{constructor(e){this.core=e}list(e,t,r){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/members`,query:t,...r??{}})}remove(e,t,r){return this.core.request({method:"DELETE",path:`/v1/workspaces/${encodeURIComponent(e)}/members/${encodeURIComponent(t)}`,...r??{}})}updateRole(e,t,r,n){return this.core.request({method:"PUT",path:`/v1/workspaces/${encodeURIComponent(e)}/members/${encodeURIComponent(t)}/role`,body:r,...n??{}})}invite(e,t,r){return this.core.request({method:"POST",path:`/v1/workspaces/${encodeURIComponent(e)}/members/invite`,body:t,...r??{}})}};var ne=class{constructor(e){this.core=e}list(e){return this.core.request({method:"GET",path:"/v1/workspaces",...e??{}})}create(e,t){return this.core.request({method:"POST",path:"/v1/workspaces",body:e,...t??{}})}getCurrent(e,t){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}`,...t??{}})}update(e,t,r){return this.core.request({method:"PUT",path:`/v1/workspaces/${encodeURIComponent(e)}`,body:t,...r??{}})}};var E=class{apiKeys;definitions;dns;environments;me;oauthApps;resources;ssl;users;workspaceMembers;workspaces;constructor(e){let t={...e??{}};delete t.apiKey,delete t.bearer;let r=Ge(e??{}),n=new Jt({...t,baseURL:e?.baseURL??"https://runtime.blimu.dev",...r.length>0?{authStrategies:r}:{}});this.apiKeys=new z(n),this.definitions=new V(n),this.dns=new J(n),this.environments=new Q(n),this.me=new H(n),this.oauthApps=new Y(n),this.resources=new X(n),this.ssl=new Z(n),this.users=new ee(n),this.workspaceMembers=new te(n),this.workspaces=new ne(n)}};import{readFileSync as Ht}from"fs";import{homedir as je}from"os";import{join as B}from"path";import{existsSync as Ne}from"fs";var re=B(je(),".config","blimu"),l={configDir:re,credentials:B(re,"credentials.json"),preferences:B(re,"preferences.json"),config:{primary:B(re,"config.json"),legacy:B(je(),".blimurc.json")}};function Ke(){return Ne(l.config.primary)?l.config.primary:Ne(l.config.legacy)?l.config.legacy:null}function se(){let o=Ke();if(!o)return null;try{let e=Ht(o,"utf-8");return JSON.parse(e)}catch{return null}}function Qe(o,e){return o||(e?.blimuInternalEnvironment?e.blimuInternalEnvironment:(oe(),St(ze)).DEFAULT_ENVIRONMENT)}var Ve={"local-dev":"https://runtime-api.dev-blimu.dev","local-prod":"https://runtime-api.dev-blimu.dev","cloud-dev":"https://api.blimu.dev","cloud-prod":"https://api.blimu.dev"},Je={"local-dev":"https://platform-api.dev-blimu.dev","local-prod":"https://platform.blimu.dev","cloud-dev":"https://platform.blimu.dev","cloud-prod":"https://platform.blimu.dev"};function ie(o,e,t){return o||(e?.runtimeApiBaseUrl?e.runtimeApiBaseUrl:t&&Ve[t]?Ve[t]:"https://runtime.blimu.dev")}function He(o,e,t){return o||(e?.platformApiBaseUrl?e.platformApiBaseUrl:t&&Je[t]?Je[t]:"https://platform.blimu.dev")}import{readFileSync as Ce,writeFileSync as Yt,mkdirSync as Xt,existsSync as U,chmodSync as Zt,unlinkSync as en}from"fs";import{dirname as tn}from"path";var F="blimu-cli",ae=null,Ye=null;async function L(){return ae||(Ye??=import("@napi-rs/keyring"),ae=await Ye),ae.Entry}async function Xe(){try{let o=await L(),e=new o(F,"test-availability");return e.setPassword("test"),e.deletePassword(),!0}catch{return!1}}async function Ze(o){let e=`refresh-token-${o}`;try{let t=await L(),n=new t(F,e).getPassword();if(n)return n}catch{}if(U(l.credentials))try{let t=Ce(l.credentials,"utf-8"),r=JSON.parse(t);if(r._keychain_unavailable&&r.refresh_token)return r.refresh_token}catch{}return null}async function ce(o,e){let t=`refresh-token-${o}`;try{let s=await L();return new s(F,t).setPassword(e),{usedKeychain:!0}}catch{}let n={...y(),refresh_token:e,_keychain_unavailable:!0,environment:o};return O(n),{usedKeychain:!1}}async function et(o){let e=`refresh-token-${o}`;try{let t=await L();new t(F,e).deletePassword()}catch{}if(U(l.credentials))try{let t=Ce(l.credentials,"utf-8"),r=JSON.parse(t);if(r._keychain_unavailable){let{refresh_token:n,_keychain_unavailable:s,...a}=r;O(a)}}catch{}}async function tt(o,e){let t=`code-verifier-${o}`;try{let r=await L();return new r(F,t).setPassword(e),{usedKeychain:!0}}catch{return{usedKeychain:!1}}}function y(){if(!U(l.credentials))throw new Error("No credentials found. Please run `blimu login` first.");try{let o=Ce(l.credentials,"utf-8");return JSON.parse(o)}catch(o){throw new Error(`Failed to read credentials: ${o instanceof Error?o.message:String(o)}`)}}function O(o){let e=tn(l.credentials);U(e)||Xt(e,{recursive:!0,mode:448}),Yt(l.credentials,JSON.stringify(o,null,2),"utf-8"),Zt(l.credentials,384)}function nt(){U(l.credentials)&&en(l.credentials)}function G(){return U(l.credentials)}async function nn(o,e,t){let r=await Ze(t);if(!r)throw new Error("No refresh token found. Please run `blimu login` again.");let n=await fetch(`${o}/v1/oauth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"refresh_token",client_id:e,refresh_token:r})});if(!n.ok){let d=await n.json().catch(()=>({}));throw new Error(d.error_description??d.error??`HTTP ${n.status}: ${n.statusText}`)}let s=await n.json(),a=Math.floor(Date.now()/1e3)+s.expires_in,m=y();return O({...m,access_token:s.access_token,expires_at:a,environment:t}),s.refresh_token!==r&&await ce(t,s.refresh_token),{access_token:s.access_token,expires_at:a,refresh_token:s.refresh_token}}function rn(o=60){try{let e=y(),t=Math.floor(Date.now()/1e3);return e.expires_at-t<o}catch{return!0}}async function rt(o,e,t){return rn()?(await nn(o,e,t)).access_token:y().access_token}oe();async function me(o={}){let{apiKey:e,bearer:t,platformApiUrl:r,requireAuth:n=!0}=o,s=se(),a;if(G())try{a=y().environment??s?.blimuInternalEnvironment}catch{a=s?.blimuInternalEnvironment}else a=s?.blimuInternalEnvironment;let m=r??He(void 0,s,a)??"https://platform.blimu.dev",d=e,c=t;if(d||c)return new E({baseURL:m,...d?{apiKey:d}:{},...c?{bearer:c}:{}});if(!n)return new E({baseURL:m});if(!G())throw new Error("Authentication required. Please run `blimu login` first or provide --api-key <key> or --bearer <token>");try{let u=y().environment??s?.blimuInternalEnvironment??"cloud-prod",I=ie(void 0,s,u),g=M(u);c=await rt(I,g,u)}catch(p){throw new Error(`Failed to authenticate: ${p instanceof Error?p.message:String(p)}
4
+ Please run \`blimu login\` again.`)}return new E({baseURL:m,bearer:c})}import{readFileSync as on,writeFileSync as sn,mkdirSync as an,existsSync as ot,chmodSync as cn}from"fs";import{dirname as mn}from"path";function pn(o){try{let e=o.split(".");if(e.length!==3)return null;let t=e[1];if(!t)return null;let r=t.replace(/-/g,"+").replace(/_/g,"/"),n=Buffer.from(r,"base64").toString("utf-8"),s=JSON.parse(n);return typeof s.sub=="string"?s.sub:null}catch{return null}}function st(){if(!G())return null;try{let o=y();return pn(o.access_token)}catch{return null}}function it(){if(!ot(l.preferences))return{};try{let o=on(l.preferences,"utf-8");return JSON.parse(o)}catch{return{}}}function un(o){let e=mn(l.preferences);ot(e)||an(e,{recursive:!0,mode:448}),sn(l.preferences,JSON.stringify(o,null,2),"utf-8"),cn(l.preferences,384)}function at(){let o=st();return o?it()[o]?.default_workspace_id??null:null}function we(o){let e=st();if(!e)throw new Error("Cannot set workspace preference: No authenticated user found");let t=it();t[e]={...t[e],default_workspace_id:o},un(t)}function ln(){return process.env.CI==="true"||process.env.CI==="1"}function dn(){if(ln()||!process.stdout.isTTY)return!1;let o=process.env.TERM;return!(!o||o==="dumb")}function ke(){return dn()}import{select as fn}from"@inquirer/prompts";async function N(o){try{return await fn({message:o.title,choices:o.choices.map(t=>{let r={name:t.label,value:t.value};return t.description!=null?{...r,description:t.description}:r})})}catch{return null}}function ct(o){o.command("push").description("Push definitions to Blimu API").option("--config <path>","Path to Blimu config file (defaults to blimu.config.ts in project root)").option("--workspace-id <id>","Workspace ID (prompts if not specified)").option("--environment-id <id>","Environment ID (prompts if not specified)").option("--platform-api-url <url>","Override Platform API base URL").action(async e=>{try{let t=await C(),r=t.group("Connecting to Blimu"),n;await r.task("Authenticate",async u=>{n=await me({...e.apiKey?{apiKey:e.apiKey}:{},...e.bearer?{bearer:e.bearer}:{},...e.platformApiUrl?{platformApiUrl:e.platformApiUrl}:{},requireAuth:!0}),u.succeed("Connected")}),n||(r.error("Failed to connect to Blimu API"),await t.wait(),process.exit(1)),r.success("Ready"),await t.wait();let s=e.workspaceId??at();if(!s)if(ke()){let{data:u}=await n.workspaces.list();u.length===0&&(f.error("No workspaces found. Please create a workspace first."),process.exit(1));let I=u.map(h=>({label:h.name,value:h.id,description:`ID: ${h.id}`})),g=await N({title:"Select a workspace:",choices:I});g||(f.error("Workspace selection cancelled"),process.exit(1)),s=g}else f.error("No workspace specified. Use --workspace-id <id> or run `blimu login` to set a default workspace."),process.exit(1);let a=e.environmentId;if(!a)if(ke()){let{data:u}=await n.environments.list(s);u.length===0&&(f.error("No environments found in this workspace. Please create an environment first."),process.exit(1));let I=u.map(h=>({label:`${h.name} (${h.variant})`,value:h.id,description:`ID: ${h.id}`})),g=await N({title:"Select an environment:",choices:I});g||(f.error("Environment selection cancelled"),process.exit(1)),a=g}else f.error("No environment specified. Use --environment-id <id>"),process.exit(1);let m=e.config??j();m||(f.error("No config file found. Please provide --config or ensure blimu.config.ts exists in project root."),process.exit(1));let d=await C(),c=d.group("Pushing definitions");c.info(`Config: ${m}`),c.info(`Workspace: ${s}`),c.info(`Environment: ${a}`);let p;await c.task("Load and validate config",async u=>{u.update("Loading config file...");let I=await Te(m);u.update("Validating schema...");let g=Le.safeParse(I);g.success||(u.fail("Config validation failed"),c.error("Config validation errors:"),g.error.issues.forEach(h=>{c.error(` - ${h.path.join(".")}: ${h.message}`)}),await d.wait(),process.exit(1)),p=g.data,u.succeed("Config validated")}),await c.task("Push to environment",async u=>{if(!n)throw new Error("Client is not connected");if(!p)throw new Error("Config is not loaded");await n.definitions.update(s,a,{resources:p.resources,...p.entitlements?{entitlements:p.entitlements}:{},...p.features?{features:p.features}:{},...p.plans?{plans:p.plans}:{}}),u.succeed("Pushed successfully")}),c.success("Definitions updated"),await d.wait()}catch(t){f.error(`Failed to push definitions: ${t instanceof Error?t.message:String(t)}`),t instanceof Error&&t.stack&&console.error(t.stack),process.exit(1)}})}import bn from"open";import{Blimu as vn,FetchError as dt,BadRequestError as In}from"@blimu/backend";import{createHash as hn,randomBytes as gn}from"crypto";function mt(){let o=gn(96);return ut(o)}function pt(o){let e=hn("sha256").update(o).digest();return ut(e)}function ut(o){return o.toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}async function lt(o,e={}){let{initialInterval:t=5,maxInterval:r=60,maxAttempts:n=120,timeout:s=6e5}=e,a=Date.now(),m=t,d=0;for(;d<n;){if(Date.now()-a>s)throw new Error("Login timed out");d>0&&await yn(m*1e3),d++;try{let c=await o();if(c.success)return c.data;let p=c.error;if(p.error==="authorization_pending")continue;if(p.error==="slow_down"){m=Math.min(m+5,r);continue}throw p.error==="access_denied"?new Error("Authorization was denied"):p.error==="expired_token"?new Error("Login session has expired"):new Error(p.error_description??p.error??"Authorization failed")}catch(c){throw c instanceof Error?c:new Error(`Polling error: ${String(c)}`)}}throw new Error("Login timed out")}function yn(o){return new Promise(e=>setTimeout(e,o))}import{Agent as Cn,fetch as wn}from"undici";function kn(){let o=new Cn({connect:{rejectUnauthorized:!1}});return async(e,t)=>wn(e,{...t,dispatcher:o})}var pe=class{constructor(e,t,r){this.runtimeApiBaseUrl=e;this.clientId=t;this.environment=r;let n=this.environment==="local-dev"||this.environment==="local-prod"?kn():void 0;this.client=new vn({baseURL:e,...n?{fetch:n}:{}})}client;async requestDeviceCode(){let e=mt(),t=pt(e);try{return{deviceCodeResponse:await this.client.oauth.requestDeviceCode({client_id:this.clientId,code_challenge:t,code_challenge_method:"S256"}),codeVerifier:e,codeChallenge:t}}catch(r){if(r instanceof dt){let n=r.data||{};if(r.status===0){let s=r.message||"Unknown network error";throw new Error(`Failed to connect to ${this.runtimeApiBaseUrl}. ${s}
5
+ This usually means:
6
+ - The server is not running or not reachable
7
+ - DNS resolution failed
8
+ - SSL/TLS certificate issues
9
+ - Network connectivity problems
10
+
11
+ Please verify that the Runtime API is accessible at: ${this.runtimeApiBaseUrl}`)}throw new Error(n.error_description??n.error??r.message??"Request failed")}throw r}}async pollForTokens(e,t,r){return lt(async()=>{try{return{success:!0,data:await this.client.oauth.exchangeDeviceCode({grant_type:"urn:ietf:params:oauth:grant-type:device_code",device_code:e,client_id:this.clientId,code_verifier:t})}}catch(n){if(n instanceof In)return{success:!1,error:{error:n.message,error_description:n.message}};if(n instanceof dt){if(n.status===0)throw new Error(`Network error while polling for tokens: ${n.message||"Connection failed"}
12
+ Please verify that the Runtime API is accessible at: ${this.runtimeApiBaseUrl}`);return{success:!1,error:{error:`http_${n.status}`,error_description:n.message||`HTTP ${n.status} error`}}}let s=n instanceof Error?n.message:String(n);throw new Error(`Unexpected error while polling for tokens: ${s}`)}},{initialInterval:r,maxInterval:60,maxAttempts:120,timeout:6e5})}};oe();function ft(o){o.command("login").description("Authenticate with Blimu using OAuth2 device flow").option("--exec-env <env>","Blimu internal environment (local-dev, local-prod, cloud-dev, cloud-prod)").option("--runtime-api-url <url>","Override Runtime API base URL").option("--verbose","Show detailed output",!1).action(async e=>{let t=e.verbose;try{let r=await C(),n=se(),s=Qe(e.execEnv,n),a=ie(e.runtimeApiUrl,n,s);t&&r.info(`Runtime API: ${a}`);let m=M(s),d=s==="cloud-prod"?"Blimu platform":`${s} environment`,c=r.group(`Authenticating to ${d}`);await Xe()||c.warn("System keychain not available. Refresh token will be stored in plaintext at ~/.config/blimu/credentials.json");let u=new pe(a,m,s),{deviceCodeResponse:I,codeVerifier:g}=await u.requestDeviceCode();c.info("Browser didn't open? Use the url below to sign in (c to copy)",{clearable:!0}),c.copyableText(I.verification_uri_complete,{clearable:!0,dimmed:!0});try{await bn(I.verification_uri_complete)}catch{}await tt(s,g);let h=await u.pollForTokens(I.device_code,g,I.interval),It=Math.floor(Date.now()/1e3)+h.expires_in;O({access_token:h.access_token,token_type:h.token_type,expires_at:It,environment:s});let{usedKeychain:Ct}=await ce(s,h.refresh_token);c.success("Login successful"),t&&(Ct?r.info("Refresh token stored in system keychain"):r.info("Refresh token stored in credentials file"));let ue=r;ue.renderInstance&&(ue.renderInstance.cleanup(),ue.isRendering=!1),await new Promise(wt=>setTimeout(wt,100)),await Rn()}catch(r){let n=r instanceof Error?r.message:String(r);f.error(`Authentication failed: ${Tn(n)}`),t&&r instanceof Error&&r.stack&&f.info(r.stack),process.exit(1)}})}async function Rn(){try{f.info("Fetching workspaces...");let o=await me({requireAuth:!0}),{data:e}=await o.workspaces.list();if(f.info(`Found ${e.length} workspace(s)`),e.length===1){let n=e[0];n&&(we(n.id),f.info(`Default workspace set to: ${n.name}`));return}if(e.length===0)return;let t=e.map(n=>({label:n.name,value:n.id,description:`ID: ${n.id}`})),r=await N({title:"Select a default workspace:",choices:t});if(r){we(r);let n=e.find(s=>s.id===r);f.success(`Default workspace set to: ${n?.name}`)}}catch(o){if(f.warn("Could not fetch workspaces for default selection"),o instanceof Error){f.info(`Reason: ${o.message}`);let e=o;console.error("Full error details:",o),e.status!==void 0&&console.error("HTTP Status:",e.status),e.data!==void 0&&console.error("Response data:",e.data)}}}function Tn(o){let e=o.replace(/^HTTP \d+:\s*/i,"");return{"Invalid request":"The authorization request was invalid. Please try again.","User denied authorization":"Authorization was denied.","Device code has expired":"The login session has expired. Please try again.","Polling timeout exceeded":"Login timed out. Please try again.","Maximum polling attempts exceeded":"Login timed out. Please try again."}[e]??e}function ht(o){o.command("logout").description("Log out and remove stored credentials").action(async()=>{try{let e=await C(),t;try{t=y().environment}catch{e.info("No credentials found. Already logged out."),await e.wait();return}await e.group("Logging out").task("Remove credentials",async n=>{t&&await et(t),nt(),n.succeed("Credentials removed")}),e.success("Successfully logged out!"),await e.wait()}catch(e){f.error(`Failed to logout: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}})}function gt(o){return Object.entries(o).map(([e,t])=>{let r;return t==null?r="":typeof t=="object"?r=JSON.stringify(t):r=String(t),`${e}: ${r}`.trimEnd()}).join(`
13
+ `)}function yt(o){try{let e=o.split(".");if(e.length!==3)return null;let t=e[1];if(!t)return null;let r=Buffer.from(t,"base64url").toString("utf-8");return JSON.parse(r)}catch{return null}}import R from"chalk";function Sn(o){return new Date(o*1e3).toLocaleString()}function vt(o){o.command("whoami").description("Display current authentication information").action(async()=>{let e=await C();try{let t=y(),r=yt(t.access_token),n=Math.floor(Date.now()/1e3),s=t.expires_at-n,a={...r?.sub?{[`${R.cyan("@userid")}`]:r.sub}:{},...r?.email?{[`${R.cyan("@email")}`]:r.email}:{},...r?.name?{[`${R.cyan("@name")}`]:r.name}:{},[`${R.cyan("@environment")}`]:t.environment??"unknown",[`${R.cyan("@expires")}`]:Sn(t.expires_at),...s>0?{[`${R.cyan("@expires_in")}`]:`${Math.floor(s/60)} minutes`}:{[`${R.red("@expired")}`]:!0}};e.info(`Current authentication:
14
+
15
+ `+gt(a)+`
16
+ `)}catch(t){t instanceof Error&&t.message.includes("No credentials found")?e.error("Not authenticated. Please run `blimu login` first."):e.error(`Failed to get user info: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}})}var T=new xn;T.name("blimu").description("Blimu - Authorization as a Service CLI").version(process.env.npm_package_version??"0.0.0");Fe(T);ct(T);ft(T);ht(T);vt(T);T.parse();
17
+ //# sourceMappingURL=main.mjs.map