@sheetxl/scripting
Version:
Scripting - Scripting engine for Macros and formulas; includes TypeScript and EsBuild.
33 lines (32 loc) • 9.93 kB
JavaScript
;/**
* @license @sheetxl/scripting - Scripting - Scripting engine for Macros and formulas; includes TypeScript and EsBuild. - v0.7.27
*
* (C) 2025-present SheetXL Inc. & Michael T. Ford
* License: The license can be found at https://www.sheetxl.com/license.
*/Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const F=require("@sheetxl/primitives"),le=require("@sheetxl/utils");let L=null,q=null;const se={compilerOptions:{target:"esnext"}};async function ce(h,x,b="/script.js",w="__SHEETXL"){try{const K=await(async function(){if(L)return L;if(q){if(await q,!L)throw new Error("ESBuild initialization promise resolved, but instance is not available.");return L}let p,T;q=new Promise((a,S)=>{p=a,T=S});try{const{initialize:a}=await Promise.resolve().then(()=>require("./BgmE5dDR60P-0D05.cjs"));return L=await a(),p(),L}catch(a){throw console.error("Failed to import or initialize esbuild:",a),q=null,T(a),a}})(),O="@sheetxl/primitives",n=`
export const FormulaContext = globalThis.${w}?.FormulaContext;
export const ScalarType = globalThis.${w}?.ScalarType;
export const Observable = globalThis.${w}?.Observable;
export const IRange = globalThis.${w}?.IRange;
export const FormulaError = globalThis.${w}?.FormulaError;
// Add more exports as needed
`,C={name:"sheetxl-esbuild-in-memory",setup(p){const T="sheetxl-"+new Date().getTime();p.onResolve({filter:new RegExp(`^(${b.replace("/","\\/")}|${O})$`)},a=>({path:a.path,namespace:T})),p.onResolve({filter:/.*/},a=>{if(a.namespace!==T)return console.warn(`esbuild: Treating import "${a.path}" as external.`),{path:a.path,external:!0}}),p.onLoad({filter:/.*/,namespace:T},a=>{let S;if(a.path===b)S=x;else{if(a.path!==O)return{errors:[{text:`Cannot load unknown path in ${T}: ${a.path}`}]};S=n}return{contents:S,loader:"ts"}})}},y=await K.build({entryPoints:[b],bundle:!0,write:!1,format:"esm",plugins:[C],sourcemap:"inline",tsconfigRaw:se,minify:!0,platform:"neutral"});if(y.outputFiles&&y.outputFiles.length>0)return y.outputFiles[0].text;throw y.errors&&y.errors.length>0?new Error(`esbuild bundling failed: ${y.errors.map(p=>p.text).join(`
`)}`):new Error("esbuild did not produce an output file.")}catch(K){throw console.error("esbuild bundling process failed:",K),K}}const de=async()=>`
interface FirstTest {
isTrue?: boolean;
}
`,ee=new Map([["IReferenceRange","r"],["IRange","l"]]),te=new Map([["IWorkbook","workbook"],["ISheet","sheet"],["ICellRanges","ranges"],["ICellRange","range"],["IFormulaContext","context"]]),X=(h,x)=>{Array.from(x.keys()).forEach(b=>{const w=x.get(b);x.set(`${h}.${b}`,w)})},ue=new Map([["Scalar","*"],["FormulaError.Known",F.ScalarType.Error],["Date","Date"],["JSON","JSON"]]),pe=new Map([]),_="SheetXL";X(_,ee),X(_,te),X(_,pe);const me=new Map([["Promise",()=>({async:!0})],["Observable",()=>({stream:!0})]]);let B=null;async function fe(){if(B)return B;try{return await(await Promise.resolve().then(()=>require("./C6FgXFuZyUBSYx74.cjs"))).initialize()}catch(h){throw B=null,h}finally{B=null}}exports.compileModule=async function(h){const x=h?.source??null;if(!x)return null;const b=(h.disableBundle||h.declarationsOnly)??!1,w=[de(),fe()],K=await Promise.all(w),O=K[0],n=K[1];let C="",y=null;const p=[],T={allowJs:!0,declaration:!1,sourceMap:!1,inlineSourceMap:!1,inlineSources:!1,isolatedModules:!0,preserveConstEnums:!1,module:99,noResolve:!0,emitDeclarationOnly:!1,target:n.ScriptTarget.ES2020},a="script",S=`${a}.ts`,H="lib.d.ts",W="global.d.ts",M={[S]:x,[H]:`
/**
* Represents the completion of an asynchronous operation
*/
interface Promise<T> {
/**
* Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The
* resolved value cannot be modified from the callback.
* @param onfinally The callback to execute when the Promise is settled (fulfilled or rejected).
* @returns A Promise for the completion of the callback.
*/
finally(onfinally?: (() => void) | undefined | null): Promise<T>;
}
`,[W]:O},ne={getSourceFile:(e,t,u,m)=>n.createSourceFile(e,M[e],n.ScriptTarget.Latest,!0),fileExists:e=>M[e]!==void 0,readFile:e=>M[e],writeFile:(e,t)=>{M[e]=t},getCurrentDirectory:()=>"./",getCanonicalFileName:e=>e,useCaseSensitiveFileNames:()=>!0,getDefaultLibFileName:e=>H,getNewLine:()=>`
`},J=n.createProgram([S,W],T,ne),A=J.getTypeChecker(),re=J.getSourceFile(S),G=J.emit();G.diagnostics.length>0&&console.warn(G.diagnostics),C=M[`${a}.js`];const I=(e,t,u,m)=>{if(e){if(e.kind===n.SyntaxKind.NumberKeyword)t.scalar=F.ScalarType.Number;else if(e.kind===n.SyntaxKind.StringKeyword)t.scalar=F.ScalarType.String;else if(e.kind===n.SyntaxKind.BooleanKeyword)t.scalar=F.ScalarType.Boolean;else if(e.kind===n.SyntaxKind.UndefinedKeyword||e.kind===n.SyntaxKind.NullKeyword||e.kind===n.SyntaxKind.VoidKeyword){if(m)return void k(e,new Error(`'undefined' is not a valid type for input: '${e?.parent?.name?.escapedText}'.`));t.scalar=F.ScalarType.Null}else if(e.kind===n.SyntaxKind.BigIntKeyword)t.scalar=F.ScalarType.Number;else if(e.kind===n.SyntaxKind.AnyKeyword)t.scalar=F.ScalarType.Null;else if(e.kind===n.SyntaxKind.ArrayType){const o=e.elementType;if(!o)return void k(e,new Error(`'Array' must be typed: '${e?.parent?.name?.escapedText}'.`));t.arrayDepth=(t.arrayDepth??0)+1,I(o,t,u,m)}else if(e.kind!==n.SyntaxKind.TupleType){if(e.kind===n.SyntaxKind.TypeReference){const o=e.typeName?.getText?.()??null,R=ee.get(o);let E=!1;R&&(t.range=R,E=!0);const D=ue.get(o);if(D&&(t.scalar=D),D!==void 0&&(E=!0),m){const r=te.get(o);if(r)return r}else{const r=me.get(o);if(r){const l={...t,...r()};let g=0;if(l.async&&g++,l.stream&&g++,g>1)return void k(e,new Error(`'${o}' cannot have multiple modifiers: '${e?.parent?.name?.escapedText}'.`));t=l,E=!0}}if(!E)return void k("node",new Error(`'${o}' is not a valid type: '${e?.parent?.name?.escapedText}'.`));const c=e.typeArguments;if(c){if(c.length!==1)return void k(e,new Error(`'${o}' must be typed with exactly 1 type: '${e?.parent?.name?.escapedText}'.`));I(c[0],t,u,m)}}}}else k(e,new Error(`Type is not defined for '${t?.name??"return"}'.`))},z=[],k=(e,t)=>{z.push(t)};if(n.forEachChild(re,e=>{if((t=>(n.getCombinedModifierFlags(t)&n.ModifierFlags.Export)!==0)(e)&&n.isFunctionDeclaration(e)){const t={},u={parameters:{}},m=e?.name?.getText();try{t.name=m;const o=A.getSymbolAtLocation(e.name).getDocumentationComment(A);if(o&&o.length>0&&o[0].text){let c=o[0].text;c=c.replace(/[\r\n]+/g,"\\n").trim(),u.summary=c}const R={};I(e.type,R,t,!1),t.returnType=R;const E={};(c=>(n.getCombinedModifierFlags(c)&n.ModifierFlags.Default)!==0)(e)&&(E.default=!0,y=m),Object.keys(E).length>0&&(t.behavior=E),t.parameters=[];const D=new Map;for(let c=0;c<e.parameters.length;c++){const r=e.parameters[c],l={};l.name=r.name?.getText();const g=I(r.type,l,t,!0);if(g){if(t.parameters.length!==0){const s=e?.parent,i=s?.name?.getText();return void k(e,new Error(`'${t.name}' contexts must be the first parameter: '${i}'.`))}t.context=g;continue}let P;if((r.initializer!==void 0&&r.initializer!==null||r.questionToken!==void 0&&r.questionToken!==null)&&(l.optional=!0,r.initializer))try{P=r.initializer.kind===n.SyntaxKind.StringLiteral?r.initializer.text:r.initializer.kind===n.SyntaxKind.NumericLiteral?parseFloat(r.initializer.text):r.initializer.kind===n.SyntaxKind.TrueKeyword||r.initializer.kind===n.SyntaxKind.FalseKeyword?r.initializer.kind===n.SyntaxKind.TrueKeyword:r.initializer.kind===n.SyntaxKind.NullKeyword?null:r.initializer.kind===n.SyntaxKind.ObjectLiteralExpression||r.initializer.kind===n.SyntaxKind.ArrayLiteralExpression?r.initializer.getText():r.initializer.getText?.()}catch(s){console.warn(`Couldn't extract default value for parameter '${l.name}'`,s)}r.dotDotDotToken&&(l.rest=!0),t.parameters.push(l);const $={description:""};u.parameters[l.name]=$;const f=A.getSymbolAtLocation(r.name).getDocumentationComment(A);f&&f.length>0&&f[0].text&&($.description=f[0].text),P!==void 0&&($.defaultValue=P),D.set(l.name,l)}if(e.jsDoc&&e.jsDoc.length>0){const c=e.jsDoc,r=c.length;for(let l=0;l<r;l++){const g=c[l]?.tags;if(!g)continue;const P=g.length;for(let $=0;$<P;$++){const f=g[$];let s=f?.tagName?.text;if(!s)continue;s=s.toLowerCase();let i=f.comment;const Y=s==="hidden";if((typeof i=="string"||Y)&&(typeof i=="string"&&(i=i.replace(/[\r\n]+/g,"\\n").trim()),Y||!i||(i=i.split(/\\n/)[0],i&&i.length!==0))){if(i&&typeof i=="string"){const d=/\{@link(code|plain)?\s+([^}|]+)(?:\s*\|\s*([^}]+))?\}/g;let v,N=i,j=[];for(;(v=d.exec(i))!==null;){const[U,V,ae,Z]=v,oe=[ae.trim()];Z&&oe.push(Z.trim())}i=N,j.length>0&&s==="see"&&(u.links||(u.links=[]),u.links.push(...j))}if(s==="name"){const d=i;d!==m&&(u.name=d)}else if(s!=="description"){if(s==="summary"){const d=i;d&&(u.summary=d)}else if(s==="param"){const d=f.name?.text,v=D.get(d);if(!v){z.push(new Error(`Parameter '${d}' not found in function '${m}'.`));continue}if(f.typeExpression&&f.typeExpression.type)try{const N=f.typeExpression.type;if(N.kind===n.SyntaxKind.UnionType){const j=[];v.enums=j,N.types.forEach(U=>{if(U.kind===n.SyntaxKind.LiteralType){const V=U.literal.text;V&&j.push(V)}})}}catch(N){console.warn("Error parsing JSDoc type expression:",N)}}else if(s==="returns"||s==="return")t.returnType.description=i;else if(s==="category")u.category=i;else if(s==="hidden"){let d=!0;const v=i?.toLowerCase();v==="false"?d=!1:v!=="true"&&(d=i),d!==!1&&(u.hidden=d??!0)}}}}}}Object.keys(t.returnType).length===0&&delete t.returnType,p.push([t,u])}catch(o){k(e,new Error(`'${m}': ${o.message}`))}}}),z.length>0)throw console.warn(z),new Error("There were compilation errors.",{cause:z});if(p.length===0)throw new Error("No exported functions.");const ie=`${le.CommonUtils.uuidV4()}-script`;try{b||z.length!==0||(C=await ce(0,C,a))}catch{console.warn("Error bundling script")}const Q={functions:p,commitId:ie,source:x,name:"Script",language:"typescript",compiled:C};return y&&(Q.autoRun=y),Q};