UNPKG

@lunora/cli

Version:

The Lunora CLI: init, dev, deploy, codegen, run, reset, and migrate commands

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