| #!/usr/bin/env node | ||
| 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(` | ||
| `),"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)} | ||
| 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} | ||
| This usually means: | ||
| - The server is not running or not reachable | ||
| - DNS resolution failed | ||
| - SSL/TLS certificate issues | ||
| - Network connectivity problems | ||
| 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"} | ||
| 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(` | ||
| `)}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: | ||
| `+gt(a)+` | ||
| `)}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(); | ||
| //# sourceMappingURL=main.mjs.map |
Sorry, the diff of this file is too big to display
+2
-1
@@ -81,3 +81,4 @@ "use strict"; | ||
| function defineConfig(config) { | ||
| const validated = BlimuConfigSchema.parse(config); | ||
| const _validated = BlimuConfigSchema.parse(config); | ||
| void _validated; | ||
| return config; | ||
@@ -84,0 +85,0 @@ } |
@@ -1,1 +0,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":[]} | ||
| {"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":[]} |
+9
-9
@@ -79,3 +79,3 @@ import { z } from 'zod'; | ||
| type BlimuConfigInput = { | ||
| interface BlimuConfigInput { | ||
| resources: Record<string, ResourceDefinition>; | ||
@@ -85,3 +85,3 @@ entitlements?: Record<string, EntitlementDefinition>; | ||
| plans?: Record<string, PlanDefinition>; | ||
| }; | ||
| } | ||
| declare function defineConfig<T extends BlimuConfigInput>(config: T): T; | ||
@@ -91,20 +91,20 @@ | ||
| resources: infer R; | ||
| } ? R extends Record<string, any> ? keyof R : never : never; | ||
| } ? R extends Record<string, unknown> ? keyof R : never : never; | ||
| type InferEntitlementTypes<T> = T extends { | ||
| entitlements: infer E; | ||
| } ? E extends Record<string, any> ? keyof E : never : never; | ||
| } ? E extends Record<string, unknown> ? keyof E : never : never; | ||
| type InferPlanTypes<T> = T extends { | ||
| plans: infer P; | ||
| } ? P extends Record<string, any> ? keyof P : never : never; | ||
| } ? P extends Record<string, unknown> ? keyof P : never : never; | ||
| type InferLimitTypes<T> = T extends { | ||
| plans: infer P; | ||
| } ? P extends Record<string, any> ? P[keyof P] extends { | ||
| } ? P extends Record<string, unknown> ? P[keyof P] extends { | ||
| resource_limits?: infer RL; | ||
| } ? RL extends Record<string, any> ? keyof RL : never : never : never : never; | ||
| } ? RL extends Record<string, unknown> ? keyof RL : never : never : never : never; | ||
| type InferUsageLimitTypes<T> = T extends { | ||
| plans: infer P; | ||
| } ? P extends Record<string, any> ? P[keyof P] extends { | ||
| } ? P extends Record<string, unknown> ? P[keyof P] extends { | ||
| usage_based_limits?: infer UL; | ||
| } ? UL extends Record<string, any> ? keyof UL : never : never : never : never; | ||
| } ? UL extends Record<string, unknown> ? keyof UL : never : never : never : never; | ||
| 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 }; |
+9
-9
@@ -79,3 +79,3 @@ import { z } from 'zod'; | ||
| type BlimuConfigInput = { | ||
| interface BlimuConfigInput { | ||
| resources: Record<string, ResourceDefinition>; | ||
@@ -85,3 +85,3 @@ entitlements?: Record<string, EntitlementDefinition>; | ||
| plans?: Record<string, PlanDefinition>; | ||
| }; | ||
| } | ||
| declare function defineConfig<T extends BlimuConfigInput>(config: T): T; | ||
@@ -91,20 +91,20 @@ | ||
| resources: infer R; | ||
| } ? R extends Record<string, any> ? keyof R : never : never; | ||
| } ? R extends Record<string, unknown> ? keyof R : never : never; | ||
| type InferEntitlementTypes<T> = T extends { | ||
| entitlements: infer E; | ||
| } ? E extends Record<string, any> ? keyof E : never : never; | ||
| } ? E extends Record<string, unknown> ? keyof E : never : never; | ||
| type InferPlanTypes<T> = T extends { | ||
| plans: infer P; | ||
| } ? P extends Record<string, any> ? keyof P : never : never; | ||
| } ? P extends Record<string, unknown> ? keyof P : never : never; | ||
| type InferLimitTypes<T> = T extends { | ||
| plans: infer P; | ||
| } ? P extends Record<string, any> ? P[keyof P] extends { | ||
| } ? P extends Record<string, unknown> ? P[keyof P] extends { | ||
| resource_limits?: infer RL; | ||
| } ? RL extends Record<string, any> ? keyof RL : never : never : never : never; | ||
| } ? RL extends Record<string, unknown> ? keyof RL : never : never : never : never; | ||
| type InferUsageLimitTypes<T> = T extends { | ||
| plans: infer P; | ||
| } ? P extends Record<string, any> ? P[keyof P] extends { | ||
| } ? P extends Record<string, unknown> ? P[keyof P] extends { | ||
| usage_based_limits?: infer UL; | ||
| } ? UL extends Record<string, any> ? keyof UL : never : never : never : never; | ||
| } ? UL extends Record<string, unknown> ? keyof UL : never : never : never : never; | ||
| 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 }; |
+2
-1
@@ -50,3 +50,4 @@ // src/config/schema.ts | ||
| function defineConfig(config) { | ||
| const validated = BlimuConfigSchema.parse(config); | ||
| const _validated = BlimuConfigSchema.parse(config); | ||
| void _validated; | ||
| return config; | ||
@@ -53,0 +54,0 @@ } |
@@ -1,1 +0,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":[]} | ||
| {"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":[]} |
+10
-6
| { | ||
| "name": "blimu", | ||
| "version": "1.2.1", | ||
| "version": "1.2.2", | ||
| "description": "Blimu - Authorization as a Service CLI", | ||
@@ -8,3 +8,3 @@ "main": "dist/index.cjs", | ||
| "types": "dist/index.d.ts", | ||
| "bin": "./dist/main.cjs", | ||
| "bin": "./dist/main.mjs", | ||
| "files": [ | ||
@@ -28,4 +28,4 @@ "dist", | ||
| "build": "tsup", | ||
| "dev": "tsx watch src/main.ts", | ||
| "cli": "tsx src/main.ts", | ||
| "dev": "tsup --watch", | ||
| "cli": "yarn build --silent && node dist/main.mjs", | ||
| "typecheck": "tsc --noEmit", | ||
@@ -37,9 +37,12 @@ "test": "vitest run", | ||
| "dependencies": { | ||
| "@blimu/backend": "1.2.1", | ||
| "@blimu/backend": "1.2.2", | ||
| "@blimu/fetch": "^0.4.2", | ||
| "@clack/prompts": "^1.0.0", | ||
| "@inquirer/prompts": "^8.2.0", | ||
| "@napi-rs/keyring": "^1.2.0", | ||
| "chalk": "^5.6.2", | ||
| "commander": "^14.0.2", | ||
| "ink": "^5.1.0", | ||
| "ink-spinner": "^5.0.0", | ||
| "open": "^11.0.0", | ||
| "react": "^18.3.1", | ||
| "undici": "^7.19.2", | ||
@@ -50,2 +53,3 @@ "zod": ">=4.3.0" | ||
| "@types/node": "^25.1.0", | ||
| "@types/react": "^18.3.18", | ||
| "msw": "^2.12.7", | ||
@@ -52,0 +56,0 @@ "tsup": "^8.5.1", |
| #!/usr/bin/env node | ||
| "use strict";var Qe=Object.create;var D=Object.defineProperty;var He=Object.getOwnPropertyDescriptor;var Ye=Object.getOwnPropertyNames;var Xe=Object.getPrototypeOf,Ze=Object.prototype.hasOwnProperty;var et=(r,e)=>()=>(r&&(e=r(r=0)),e);var tt=(r,e)=>{for(var t in e)D(r,t,{get:e[t],enumerable:!0})},pe=(r,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Ye(e))!Ze.call(r,n)&&n!==t&&D(r,n,{get:()=>e[n],enumerable:!(o=He(e,n))||o.enumerable});return r};var f=(r,e,t)=>(t=r!=null?Qe(Xe(r)):{},pe(e||!r||!r.__esModule?D(t,"default",{value:r,enumerable:!0}):t,r)),nt=r=>pe(D({},"__esModule",{value:!0}),r);var Re={};tt(Re,{CLIENT_IDS:()=>Ce,DEFAULT_ENVIRONMENT:()=>at,getClientId:()=>T});function T(r){let e=Ce[r];if(!e||e.startsWith("client_id_for_"))throw new Error(`Client ID not configured for environment: ${r}. Please update CLIENT_IDS in client-ids.ts`);return e}var Ce,at,Y=et(()=>{"use strict";Ce={"local-dev":"9MhKB71lI9jF5p5OSfykG4juDo5hiGYm","local-prod":"client_id_for_local_prod","cloud-dev":"client_id_for_cloud_dev","cloud-prod":"client_id_for_cloud_prod"};at="cloud-prod"});var Je=require("commander");var C=f(require("path")),he=f(require("fs")),O=f(require("@clack/prompts"));var P=f(require("fs")),R=f(require("path"));function ue(r){let{configPath:e,outputPath:t,typesPackages:o=["@blimu/types","@blimu/backend"]}=r,n=[],i=o.join(" and ");n.push("/**"),n.push(` * Type Augmentation for ${i}`),n.push(" *"),n.push(` * This file augments the ${i} 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 c=R.dirname(t),m=R.isAbsolute(e)?R.resolve(e):R.resolve(c,e),d=R.relative(c,m).replace(/\.(ts|mjs|js)$/,""),p=d.startsWith(".")?d:`./${d}`;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 v of o)n.push(`declare module '${v}' {`),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("");P.existsSync(c)||P.mkdirSync(c,{recursive:!0}),P.writeFileSync(t,n.join(` | ||
| `),"utf-8")}var U=f(require("@clack/prompts")),$=f(require("chalk")),a={info:r=>{U.log.info(r)},step:r=>{U.log.step($.default.cyan(r))},success:r=>{U.log.success($.default.green(r))},warn:r=>{U.log.warn($.default.yellow(r))},error:r=>{U.log.error($.default.red(r))}};var g=f(require("path")),x=f(require("fs"));function B(){let r=[g.join(process.cwd(),"blimu.config.ts"),g.join(process.cwd(),"blimu.config.mjs"),g.join(process.cwd(),"blimu.config.js"),g.join(process.cwd(),"blimu.config.json")];for(let e of r)if(x.existsSync(e))return e;return null}async function le(r){let e=g.isAbsolute(r)?r:g.resolve(process.cwd(),r);if(!x.existsSync(e))throw new Error(`Config file not found: ${e}`);if(g.extname(e).toLowerCase()===".json"){let n=x.readFileSync(e,"utf-8");return JSON.parse(n)}let o=await import(e);return o.default||o}function de(r,e){let o=g.relative(r,e).replace(/\.(ts|mjs|js)$/,"");return o.startsWith(".")?o:`./${o}`}function fe(r){r.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(e=>{let t=O.spinner();try{let o=e.config||B();o||(O.cancel("No config file found. Please provide --config or ensure blimu.config.ts exists in project root."),process.exit(1));let n=C.isAbsolute(o)?o:C.resolve(process.cwd(),o);he.existsSync(n)||(O.cancel(`Config file not found: ${n}`),process.exit(1)),a.step(`Using config file: ${n}`);let i=e.output?C.isAbsolute(e.output)?e.output:C.resolve(process.cwd(),e.output):C.join(process.cwd(),"blimu-types.d.ts");a.step(`Output: ${i}`);let c=C.dirname(i),m=de(c,n);t.start("Generating type augmentation file with type inference..."),ue({configPath:m,outputPath:i}),t.stop("\u26A1\uFE0F Successfully generated type augmentation file"),a.success(`Generated at: ${i}`),a.info("\u{1F4A1} Tip: Types are automatically inferred from your config."),a.info(" No regeneration needed when you update blimu.config.ts!")}catch(o){t.stop("\u274C Failed to generate type augmentation"),a.error(`Failed to generate type augmentation: ${o instanceof Error?o.message:String(o)}`),o instanceof Error&&o.stack&&a.error(o.stack),process.exit(1)}})}var w=f(require("@clack/prompts"));var s=require("zod"),ot=s.z.object({is_tenant:s.z.boolean().optional(),roles:s.z.array(s.z.string()).min(1,"At least one role must be defined"),parents:s.z.record(s.z.string(),s.z.object({required:s.z.boolean()})).optional(),roles_inheritance:s.z.record(s.z.string().min(1),s.z.array(s.z.string().regex(/^([a-z0-9_-]+->)*[a-z0-9_-]+$/i)).min(1)).optional()}),rt=s.z.object({roles:s.z.array(s.z.string()).min(1).optional(),plans:s.z.array(s.z.string()).optional(),limit:s.z.string().optional()}),it=s.z.object({name:s.z.string(),summary:s.z.string().optional(),entitlements:s.z.array(s.z.string()).optional(),plans:s.z.array(s.z.string()).optional(),default_enabled:s.z.boolean().optional()}),st=s.z.object({name:s.z.string().min(1,"Plan name is required"),summary:s.z.string().optional(),description:s.z.string().min(1,"Plan description is required").optional(),resource_limits:s.z.record(s.z.string(),s.z.number().int().min(0)).optional(),usage_based_limits:s.z.record(s.z.string(),s.z.object({value:s.z.number().int().min(0),period:s.z.enum(["monthly","yearly","lifetime"])})).optional()}),ge=s.z.object({resources:s.z.record(s.z.string().min(1),ot),entitlements:s.z.record(s.z.string().min(1),rt).optional(),features:s.z.record(s.z.string().min(1),it).optional(),plans:s.z.record(s.z.string().min(1),st).optional()});var ae=require("@blimu/fetch");function ye(r){let e=[...r?.authStrategies??[]];return r.bearer&&e.push({type:"bearer",token:r.bearer}),r.apiKey&&e.push({type:"apiKey",key:r.apiKey,location:"header",name:"X-API-KEY"}),e}var L=class{constructor(e){this.core=e}list(e,t,o){return this.core.request({method:"GET",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/api-keys`,...o??{}})}create(e,t,o,n){return this.core.request({method:"POST",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/api-keys`,body:o,...n??{}})}delete(e,t,o,n){return this.core.request({method:"DELETE",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/api-keys/${encodeURIComponent(o)}`,...n??{}})}get(e,t,o,n){return this.core.request({method:"GET",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/api-keys/${encodeURIComponent(o)}`,...n??{}})}reveal(e,t,o,n){return this.core.request({method:"POST",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/api-keys/${encodeURIComponent(o)}/reveal`,...n??{}})}};var F=class{constructor(e){this.core=e}get(e,t,o){return this.core.request({method:"GET",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/definitions`,...o??{}})}update(e,t,o,n){return this.core.request({method:"PUT",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/definitions`,body:o,...n??{}})}validate(e,t,o,n){return this.core.request({method:"POST",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/definitions/validate`,body:o,...n??{}})}};var j=class{constructor(e){this.core=e}getRecords(e,t,o){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/dns/records`,...o??{}})}validate(e,t,o){return this.core.request({method:"POST",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/dns/validate`,...o??{}})}};var K=class{constructor(e){this.core=e}list(e,t,o){return this.core.request({method:"GET",path:`/v1/workspace/${encodeURIComponent(e)}/environments`,query:t,...o??{}})}create(e,t,o){return this.core.request({method:"POST",path:`/v1/workspace/${encodeURIComponent(e)}/environments`,body:t,...o??{}})}delete(e,t,o){return this.core.request({method:"DELETE",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}`,...o??{}})}read(e,t,o){return this.core.request({method:"GET",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}`,...o??{}})}update(e,t,o,n){return this.core.request({method:"PUT",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}`,body:o,...n??{}})}getAuthConfig(e,t,o){return this.core.request({method:"GET",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/auth-config`,...o??{}})}updateAuthConfig(e,t,o,n){return this.core.request({method:"PUT",path:`/v1/workspace/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/auth-config`,body:o,...n??{}})}};var N=class{constructor(e){this.core=e}getAccess(e){return this.core.request({method:"GET",path:"/v1/me/access",...e??{}})}};var G=class{constructor(e){this.core=e}list(e,t,o,n){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/oauth-apps`,query:o,...n??{}})}create(e,t,o,n){return this.core.request({method:"POST",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/oauth-apps`,body:o,...n??{}})}delete(e,t,o,n){return this.core.request({method:"DELETE",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/oauth-apps/${encodeURIComponent(o)}`,...n??{}})}getById(e,t,o,n){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/oauth-apps/${encodeURIComponent(o)}`,...n??{}})}update(e,t,o,n,i){return this.core.request({method:"PUT",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/oauth-apps/${encodeURIComponent(o)}`,body:n,...i??{}})}revokeAllTokens(e,t,o,n){return this.core.request({method:"POST",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/oauth-apps/${encodeURIComponent(o)}/revoke-all`,...n??{}})}rotateSecret(e,t,o,n){return this.core.request({method:"POST",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/oauth-apps/${encodeURIComponent(o)}/rotate-secret`,...n??{}})}listTokens(e,t,o,n,i){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/oauth-apps/${encodeURIComponent(o)}/tokens`,query:n,...i??{}})}};var M=class{constructor(e){this.core=e}list(e,t,o,n){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/resources`,query:o,...n??{}})}create(e,t,o,n){return this.core.request({method:"POST",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/resources`,body:o,...n??{}})}delete(e,t,o,n,i){return this.core.request({method:"DELETE",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/resources/${encodeURIComponent(o)}/${encodeURIComponent(n)}`,...i??{}})}get(e,t,o,n,i){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/resources/${encodeURIComponent(o)}/${encodeURIComponent(n)}`,...i??{}})}update(e,t,o,n,i,c){return this.core.request({method:"PUT",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/resources/${encodeURIComponent(o)}/${encodeURIComponent(n)}`,body:i,...c??{}})}listChildren(e,t,o,n,i,c){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/resources/${encodeURIComponent(o)}/${encodeURIComponent(n)}/children`,query:i,...c??{}})}getResourceUsers(e,t,o,n,i,c){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/resources/${encodeURIComponent(o)}/${encodeURIComponent(n)}/users`,query:i,...c??{}})}};var W=class{constructor(e){this.core=e}provision(e,t,o){return this.core.request({method:"POST",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/ssl/provision`,...o??{}})}getStatus(e,t,o){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/ssl/status`,...o??{}})}};var V=class{constructor(e){this.core=e}list(e,t,o,n){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/users`,query:o,...n??{}})}get(e,t,o,n){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/users/${encodeURIComponent(o)}`,...n??{}})}getUserResources(e,t,o,n){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/environments/${encodeURIComponent(t)}/users/${encodeURIComponent(o)}/resources`,...n??{}})}};var z=class{constructor(e){this.core=e}list(e,t,o){return this.core.request({method:"GET",path:`/v1/workspaces/${encodeURIComponent(e)}/members`,query:t,...o??{}})}remove(e,t,o){return this.core.request({method:"DELETE",path:`/v1/workspaces/${encodeURIComponent(e)}/members/${encodeURIComponent(t)}`,...o??{}})}updateRole(e,t,o,n){return this.core.request({method:"PUT",path:`/v1/workspaces/${encodeURIComponent(e)}/members/${encodeURIComponent(t)}/role`,body:o,...n??{}})}invite(e,t,o){return this.core.request({method:"POST",path:`/v1/workspaces/${encodeURIComponent(e)}/members/invite`,body:t,...o??{}})}};var J=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,o){return this.core.request({method:"PUT",path:`/v1/workspaces/${encodeURIComponent(e)}`,body:t,...o??{}})}};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 o=ye(e??{}),n=new ae.FetchClient({...t,baseURL:e?.baseURL??"https://runtime.blimu.dev",...o.length>0?{authStrategies:o}:{}});this.apiKeys=new L(n),this.definitions=new F(n),this.dns=new j(n),this.environments=new K(n),this.me=new N(n),this.oauthApps=new G(n),this.resources=new M(n),this.ssl=new W(n),this.users=new V(n),this.workspaceMembers=new z(n),this.workspaces=new J(n)}};var we=require("fs");var Q=require("os"),H=require("path"),ce=require("fs"),h={credentials:(0,H.join)((0,Q.homedir)(),".blimu","credentials.json"),config:{primary:(0,H.join)((0,Q.homedir)(),".blimurc.json"),xdg:(0,H.join)((0,Q.homedir)(),".config","blimu","config.json")}};function ve(){return(0,ce.existsSync)(h.config.primary)?h.config.primary:(0,ce.existsSync)(h.config.xdg)?h.config.xdg:null}function X(){let r=ve();if(!r)return null;try{let e=(0,we.readFileSync)(r,"utf-8");return JSON.parse(e)}catch{return null}}function be(r,e){return r||(e?.blimuInternalEnvironment?e.blimuInternalEnvironment:(Y(),nt(Re)).DEFAULT_ENVIRONMENT)}var Ie={"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"},ke={"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 Z(r,e,t){return r||(e?.runtimeApiBaseUrl?e.runtimeApiBaseUrl:t&&Ie[t]?Ie[t]:"https://runtime.blimu.dev")}function Se(r,e,t){return r||(e?.platformApiBaseUrl?e.platformApiBaseUrl:t&&ke[t]?ke[t]:"https://platform.blimu.dev")}var l=require("fs"),Ue=require("path");var A="blimu-cli",ee=null,Pe=null;async function q(){return ee||(Pe??=import("@napi-rs/keyring"),ee=await Pe),ee.Entry}async function Ee(){try{let r=await q(),e=new r(A,"test-availability");return e.setPassword("test"),e.deletePassword(),!0}catch{return!1}}async function _e(r){let e=`refresh-token-${r}`;try{let t=await q(),n=new t(A,e).getPassword();if(n)return n}catch{}if((0,l.existsSync)(h.credentials))try{let t=(0,l.readFileSync)(h.credentials,"utf-8"),o=JSON.parse(t);if(o._keychain_unavailable&&o.refresh_token)return o.refresh_token}catch{}return null}async function te(r,e){let t=`refresh-token-${r}`;try{let i=await q();return new i(A,t).setPassword(e),{usedKeychain:!0}}catch{}let n={...y(),refresh_token:e,_keychain_unavailable:!0,environment:r};return _(n),{usedKeychain:!1}}async function $e(r){let e=`refresh-token-${r}`;try{let t=await q();new t(A,e).deletePassword()}catch{}if((0,l.existsSync)(h.credentials))try{let t=(0,l.readFileSync)(h.credentials,"utf-8"),o=JSON.parse(t);if(o._keychain_unavailable){let{refresh_token:n,_keychain_unavailable:i,...c}=o;_(c)}}catch{}}async function xe(r,e){let t=`code-verifier-${r}`;try{let o=await q();return new o(A,t).setPassword(e),{usedKeychain:!0}}catch{return{usedKeychain:!1}}}function y(){if(!(0,l.existsSync)(h.credentials))throw new Error("No credentials found. Please run `blimu login` first.");try{let r=(0,l.readFileSync)(h.credentials,"utf-8");return JSON.parse(r)}catch(r){throw new Error(`Failed to read credentials: ${r instanceof Error?r.message:String(r)}`)}}function _(r){let e=(0,Ue.dirname)(h.credentials);(0,l.existsSync)(e)||(0,l.mkdirSync)(e,{recursive:!0,mode:448}),(0,l.writeFileSync)(h.credentials,JSON.stringify(r,null,2),"utf-8"),(0,l.chmodSync)(h.credentials,384)}function Oe(){(0,l.existsSync)(h.credentials)&&(0,l.unlinkSync)(h.credentials)}function me(){return(0,l.existsSync)(h.credentials)}async function ct(r,e,t){let o=await _e(t);if(!o)throw new Error("No refresh token found. Please run `blimu login` again.");let n=await fetch(`${r}/v1/oauth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"refresh_token",client_id:e,refresh_token:o})});if(!n.ok){let u=await n.json().catch(()=>({}));throw new Error(u.error_description??u.error??`HTTP ${n.status}: ${n.statusText}`)}let i=await n.json(),c=Math.floor(Date.now()/1e3)+i.expires_in,m=y();return _({...m,access_token:i.access_token,expires_at:c,environment:t}),i.refresh_token!==o&&await te(t,i.refresh_token),{access_token:i.access_token,expires_at:c,refresh_token:i.refresh_token}}function mt(r=60){try{let e=y(),t=Math.floor(Date.now()/1e3);return e.expires_at-t<r}catch{return!0}}async function Te(r,e,t){return mt()?(await ct(r,e,t)).access_token:y().access_token}Y();async function Ae(r={}){let{apiKey:e,bearer:t,platformApiUrl:o,requireAuth:n=!0,spinner:i}=r,c=X(),m;if(me())try{m=y().environment??c?.blimuInternalEnvironment}catch{m=c?.blimuInternalEnvironment}else m=c?.blimuInternalEnvironment;let u=o??Se(void 0,c,m)??"https://platform.blimu.dev",d=e,p=t;if(d||p)return new E({baseURL:u,...d?{apiKey:d}:{},...p?{bearer:p}:{}});if(!n)return new E({baseURL:u});if(!me())throw new Error("Authentication required. Please run `blimu login` first or provide --api-key <key> or --bearer <token>");try{let I=y().environment??c?.blimuInternalEnvironment??"cloud-prod",ie=Z(void 0,c,I),se=T(I);i&&i.start("Refreshing authentication token..."),p=await Te(ie,se,I),i&&i.stop("\u2713 Token refreshed")}catch(v){throw i&&i.stop("\u274C Failed to refresh token"),new Error(`Failed to authenticate: ${v instanceof Error?v.message:String(v)} | ||
| Please run \`blimu login\` again.`)}return new E({baseURL:u,bearer:p})}function qe(r){r.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 (required)").option("--environment-id <id>","Environment ID (required)").option("--platform-api-url <url>","Override Platform API base URL").action(async e=>{let t=w.spinner();try{e.workspaceId||(w.cancel("Workspace ID is required. Use --workspace-id <id>"),process.exit(1)),e.environmentId||(w.cancel("Environment ID is required. Use --environment-id <id>"),process.exit(1));let o;try{t.start("Connecting to Blimu API..."),o=await Ae({...e.apiKey?{apiKey:e.apiKey}:{},...e.bearer?{bearer:e.bearer}:{},...e.platformApiUrl?{platformApiUrl:e.platformApiUrl}:{},requireAuth:!0,spinner:t}),t.stop("\u2713 Connected")}catch(u){t.stop("\u274C Failed to connect"),w.cancel(u instanceof Error?u.message:String(u)),process.exit(1)}let n=e.config??B();n||(w.cancel("No config file found. Please provide --config or ensure blimu.config.ts exists in project root."),process.exit(1)),a.step(`Loading config from: ${n}`),t.start("Loading and validating config file...");let i=await le(n);t.stop("\u2713 Config loaded"),t.start("Validating config structure...");let c=ge.safeParse(i);c.success||(t.stop("\u274C Config validation failed"),a.error("Config validation errors:"),c.error.issues.forEach(u=>{a.error(` - ${u.path.join(".")}: ${u.message}`)}),process.exit(1));let m=c.data;t.stop("\u2713 Config validated"),t.start("Pushing definitions to Blimu..."),await o.definitions.update(e.workspaceId,e.environmentId,{resources:m.resources,...m.entitlements?{entitlements:m.entitlements}:{},...m.features?{features:m.features}:{},...m.plans?{plans:m.plans}:{}}),t.stop("\u2713 Definitions pushed successfully"),a.success(`Successfully pushed definitions to workspace ${e.workspaceId}, environment ${e.environmentId}`)}catch(o){t.stop("\u274C Failed to push definitions"),a.error(`Failed to push definitions: ${o instanceof Error?o.message:String(o)}`),o instanceof Error&&o.stack&&a.error(o.stack),process.exit(1)}})}var je=require("@clack/prompts"),Ke=f(require("open"));var b=require("@blimu/backend");var ne=require("crypto");function De(){let r=(0,ne.randomBytes)(96);return Le(r)}function Be(r){let e=(0,ne.createHash)("sha256").update(r).digest();return Le(e)}function Le(r){return r.toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}async function Fe(r,e={}){let{initialInterval:t=5,maxInterval:o=60,maxAttempts:n=120,timeout:i=6e5}=e,c=Date.now(),m=t,u=0;for(;u<n;){if(Date.now()-c>i)throw new Error("Login timed out");u>0&&await pt(m*1e3),u++;try{let d=await r();if(d.success)return d.data;let p=d.error;if(p.error==="authorization_pending")continue;if(p.error==="slow_down"){m=Math.min(m+5,o);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(d){throw d instanceof Error?d:new Error(`Polling error: ${String(d)}`)}}throw new Error("Login timed out")}function pt(r){return new Promise(e=>setTimeout(e,r))}var re=require("undici");function ut(){let r=new re.Agent({connect:{rejectUnauthorized:!1}});return async(e,t)=>(0,re.fetch)(e,{...t,dispatcher:r})}var oe=class{constructor(e,t,o){this.runtimeApiBaseUrl=e;this.clientId=t;this.environment=o;let n=this.environment==="local-dev"||this.environment==="local-prod"?ut():void 0;this.client=new b.Blimu({baseURL:e,...n?{fetch:n}:{}})}client;async requestDeviceCode(){let e=De(),t=Be(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(o){if(o instanceof b.FetchError){let n=o.data||{};if(o.status===0){let i=o.message||"Unknown network error";throw new Error(`Failed to connect to ${this.runtimeApiBaseUrl}. ${i} | ||
| This usually means: | ||
| - The server is not running or not reachable | ||
| - DNS resolution failed | ||
| - SSL/TLS certificate issues | ||
| - Network connectivity problems | ||
| Please verify that the Runtime API is accessible at: ${this.runtimeApiBaseUrl}`)}throw new Error(n.error_description??n.error??o.message??"Request failed")}throw o}}async pollForTokens(e,t,o){return Fe(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 b.BadRequestError)return{success:!1,error:{error:n.message,error_description:n.message}};if(n instanceof b.FetchError){if(n.status===0)throw new Error(`Network error while polling for tokens: ${n.message||"Connection failed"} | ||
| 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 i=n instanceof Error?n.message:String(n);throw new Error(`Unexpected error while polling for tokens: ${i}`)}},{initialInterval:o,maxInterval:60,maxAttempts:120,timeout:6e5})}};Y();function Ne(r){r.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=(0,je.spinner)(),o=e.verbose;try{let n=X(),i=be(e.execEnv,n),c=Z(e.runtimeApiUrl,n,i);o&&a.info(`Runtime API: ${c}`);let m=T(i);a.step(`Authenticating to ${i} environment...`),await Ee()||a.warn("System keychain not available. Refresh token will be stored in plaintext at ~/.blimu/credentials.json");let d=new oe(c,m,i);o&&t.start("Requesting device code...");let{deviceCodeResponse:p,codeVerifier:v}=await d.requestDeviceCode();o&&t.stop("Device code received"),a.info("To complete authentication, please visit:"),a.info(` ${p.verification_uri_complete}`),a.info(`Or enter this code: ${p.user_code}`);try{await(0,Ke.default)(p.verification_uri_complete)}catch{}await xe(i,v),t.start("Waiting for authorization...");let I=await d.pollForTokens(p.device_code,v,p.interval);t.stop();let ie=Math.floor(Date.now()/1e3)+I.expires_in;_({access_token:I.access_token,token_type:I.token_type,expires_at:ie,environment:i});let{usedKeychain:se}=await te(i,I.refresh_token);a.success("Successfully authenticated!"),o&&(se?a.info("Refresh token stored in system keychain"):a.info("Refresh token stored in credentials file"))}catch(n){let i=n instanceof Error?n.message:String(n);a.error(`Authentication failed: ${lt(i)}`),o&&n instanceof Error&&n.stack&&a.info(n.stack),process.exit(1)}})}function lt(r){let e=r.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}var Ge=f(require("@clack/prompts"));function Me(r){r.command("logout").description("Log out and remove stored credentials").action(async()=>{let e=Ge.spinner();try{let t;try{t=y().environment}catch{a.info("No credentials found. Already logged out.");return}e.start("Removing credentials..."),t&&await $e(t),Oe(),e.stop("\u2713 Credentials removed"),a.success("Successfully logged out!")}catch(t){e.stop("\u274C Logout failed"),a.error(`Failed to logout: ${t instanceof Error?t.message:String(t)}`),process.exit(1)}})}function We(r){return Object.entries(r).map(([e,t])=>{let o;return t==null?o="":typeof t=="object"?o=JSON.stringify(t):o=String(t),`${e}: ${o}`.trimEnd()}).join(` | ||
| `)}function Ve(r){try{let e=r.split(".");if(e.length!==3)return null;let t=e[1];if(!t)return null;let o=Buffer.from(t,"base64url").toString("utf-8");return JSON.parse(o)}catch{return null}}var k=f(require("chalk"));function dt(r){return new Date(r*1e3).toLocaleString()}function ze(r){r.command("whoami").description("Display current authentication information").action(()=>{try{let e=y(),t=Ve(e.access_token),o=Math.floor(Date.now()/1e3),n=e.expires_at-o,i={...t?.sub?{[`${k.default.cyan("@userid")}`]:t.sub}:{},...t?.email?{[`${k.default.cyan("@email")}`]:t.email}:{},...t?.name?{[`${k.default.cyan("@name")}`]:t.name}:{},[`${k.default.cyan("@environment")}`]:e.environment??"unknown",[`${k.default.cyan("@expires")}`]:dt(e.expires_at),...n>0?{[`${k.default.cyan("@expires_in")}`]:`${Math.floor(n/60)} minutes`}:{[`${k.default.red("@expired")}`]:!0}};a.info(`Current authentication: | ||
| `+We(i)+` | ||
| `)}catch(e){e instanceof Error&&e.message.includes("No credentials found")?a.error("Not authenticated. Please run `blimu login` first."):a.error(`Failed to get user info: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}})}var S=new Je.Command;S.name("blimu").description("Blimu - Authorization as a Service CLI").version(process.env.npm_package_version??"0.0.0");fe(S);qe(S);Ne(S);Me(S);ze(S);S.parse(); | ||
| //# sourceMappingURL=main.cjs.map |
Sorry, the diff of this file is too big to display
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
242619
28.43%412
9.57%5
-37.5%12
33.33%7
16.67%5
25%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
Updated