UNPKG

@lunora/cli

Version:

The Lunora CLI: init, dev, deploy, codegen, migrate, seed, doctor, insights, logs, registry, and the rest of the project commands

3 lines (2 loc) 4.76 kB
import{readLinkedProject as g,resolveDeployDriver as v}from"@lunora/config";import{d as h}from"../packem_shared/command-DwC11Cwe.mjs";import{e as y,d as b}from"../packem_shared/detect-package-manager-DSaAqRof.mjs";import{defaultSpawner as w}from"../packem_shared/createRecordingSpawner-DJlNacZ6.mjs";import{createR2Sql as L}from"@lunora/bindings/r2sql";import{createPipelineLogReader as S}from"@lunora/runtime";const _=new Set(["debug","error","fatal","info","log","trace","warn"]),m=/^\d+$/,d=(e,t)=>{if(e===void 0)return;const a=e.trim();if(m.test(a))return Number(a);const r=Date.parse(a);if(Number.isNaN(r))throw new TypeError(`logs: invalid ${t} "${e}" — pass epoch-millis or an ISO 8601 date`);return r},T=e=>Buffer.from(JSON.stringify(e),"utf8").toString("base64url"),C=e=>{const t=e.trim();if(m.test(t))return{ts:Number(t)};let a;try{a=JSON.parse(Buffer.from(t,"base64url").toString("utf8"))}catch{throw new TypeError(`logs: invalid --cursor "${e}" — expected the token printed by the previous page (or a bare epoch-millis ts)`)}if(typeof a!="object"||a===null||typeof a.ts!="number"||!Number.isFinite(a.ts))throw new TypeError(`logs: invalid --cursor "${e}" — expected the token printed by the previous page (or a bare epoch-millis ts)`);const{ts:r}=a,s=a.seen,n=Array.isArray(s)?s.filter(i=>typeof i=="string"):void 0;return n!==void 0&&n.length>0?{seen:n,ts:r}:{ts:r}},u=(e,t)=>{if(e!==void 0){if(!_.has(e))throw new TypeError(`logs: invalid ${t} "${e}" — expected one of trace, debug, log, info, warn, error, fatal`);return e}},I=e=>{const t={},a=d(e.since,"--since");a!==void 0&&(t.sinceTs=a);const r=d(e.until,"--until");r!==void 0&&(t.untilTs=r);const s=u(e.level,"--level");s!==void 0&&(t.level=s);const n=u(e.minLevel,"--min-level");if(n!==void 0&&(t.minLevel=n),e.functionPrefix!==void 0&&(t.functionPathPrefix=e.functionPrefix),e.traceId!==void 0&&(t.traceId=e.traceId),e.shardKey!==void 0&&(t.shardKey=e.shardKey),e.userId!==void 0&&(t.userId=e.userId),e.limit!==void 0){const i=Number(e.limit);if(!Number.isFinite(i))throw new TypeError(`logs: invalid --limit "${e.limit}" — expected a number`);t.limit=i}return e.cursor!==void 0&&(t.cursor=C(e.cursor)),t},$=e=>{const t=new Date(e.ts).toISOString(),a=e.level.toUpperCase().padEnd(5);return`${t} ${a} ${e.functionPath} ${e.message}`},p=async e=>{const t=e.environment??process.env,a=t.R2_SQL_ACCOUNT_ID,r=t.R2_SQL_TOKEN,s=t.R2_SQL_BUCKET,n=[];if((a===void 0||a.length===0)&&n.push("R2_SQL_ACCOUNT_ID"),(r===void 0||r.length===0)&&n.push("R2_SQL_TOKEN"),(s===void 0||s.length===0)&&n.push("R2_SQL_BUCKET"),(e.table===void 0||e.table.length===0)&&n.push("--table"),n.length>0)return e.logger.error(`logs --durable: R2 SQL not configured (missing ${n.join(", ")}). The Pipeline must write to an R2 Data Catalog (Iceberg) table, and you must supply R2_SQL_ACCOUNT_ID / R2_SQL_TOKEN / R2_SQL_BUCKET plus --table — see the observability docs.`),{code:1,error:"not configured"};let i;try{i=I(e)}catch(o){return e.logger.error(o instanceof Error?o.message:String(o)),{code:1,error:"invalid option"}}const l=L({accountId:a,apiToken:r,bucket:s,fetch:e.fetch}),c=await S(l,{namespace:e.namespace,table:e.table}).query(i);for(const o of c.rows)process.stdout.write(`${e.ndjson===!0?JSON.stringify(o):$(o)} `);return c.rows.length===0?e.logger.info("logs --durable: no matching log records"):c.nextCursor!==void 0&&e.logger.info(`logs --durable: more rows available — pass --cursor ${T(c.nextCursor)} for the next page`),{code:0,rows:c.rows}},x=new Set(["json","pretty"]),E=async e=>{const t=e.cwd??process.cwd();if(e.format!==void 0&&!x.has(e.format))return e.logger.error(`logs: unknown --format "${e.format}" — expected pretty | json`),{code:1,descriptor:void 0,error:"invalid format"};const a=e.env??g(t)?.env,r=v(e.target);if(r.toolchain===void 0)return e.logger.error(`logs: deploy target "${r.id}" has no command-line toolchain`),{code:1,descriptor:void 0,error:"no toolchain"};const s=r.toolchain.tail({environment:a,format:e.format,search:e.search,status:e.status,temporary:e.temporary,worker:e.worker}),n=y(b(t),s.tool,s.args),i={args:n.args,command:n.command,cwd:t};return e.logger.info(`tailing logs via ${i.command} ${i.args.join(" ")}`),{code:(await(e.spawner??w)(i)).code,descriptor:i}},k=h(({argument:e,cwd:t,logger:a,options:r})=>r.durable===!0?p({cursor:r.cursor,functionPrefix:r.functionPrefix,level:r.level,limit:r.limit,logger:a,minLevel:r.minLevel,namespace:r.namespace,ndjson:r.ndjson===!0,shardKey:r.shardKey,since:r.since,table:r.table,traceId:r.traceId,until:r.until,userId:r.userId}):E({cwd:t,env:r.env,format:r.format,logger:a,search:r.search,status:r.status,target:r.target,temporary:r.temporary===!0,worker:e[0]}));export{k as execute,E as runLogsCommand};