UNPKG

@sheetxl/scripting

Version:

Scripting - Scripting engine for Macros and formulas; includes TypeScript and EsBuild.

33 lines (32 loc) 9.89 kB
"use strict";/** * @license @sheetxl/scripting - Scripting - Scripting engine for Macros and formulas; includes TypeScript and EsBuild. - v0.6.6 * * (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 $=require("@sheetxl/primitives"),ae=require("@sheetxl/utils");let L=null,I=null;const oe={compilerOptions:{target:"esnext"}};async function le(h,x,b="/script.js",w="__SHEETXL"){try{const K=await async function(){if(L)return L;if(I){if(await I,!L)throw new Error("ESBuild initialization promise resolved, but instance is not available.");return L}let p,T;I=new Promise((a,S)=>{p=a,T=S});try{const{initialize:a}=await Promise.resolve().then(()=>require("./9ubjQTZuV1DPiApE.cjs"));return L=await a(),p(),L}catch(a){throw console.error("Failed to import or initialize esbuild:",a),I=null,T(a),a}}(),j="@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 `,F={name:"sheetxl-esbuild-in-memory",setup(p){const T="sheetxl-"+new Date().getTime();p.onResolve({filter:new RegExp(`^(${b.replace("/","\\/")}|${j})$`)},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!==j)return{errors:[{text:`Cannot load unknown path in ${T}: ${a.path}`}]};S=n}return{contents:S,loader:"ts"}})}},f=await K.build({entryPoints:[b],bundle:!0,write:!1,format:"esm",plugins:[F],sourcemap:"inline",tsconfigRaw:oe,minify:!0,platform:"neutral"});if(f.outputFiles&&f.outputFiles.length>0)return f.outputFiles[0].text;throw f.errors&&f.errors.length>0?new Error(`esbuild bundling failed: ${f.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 se=async()=>` interface FirstTest { isTrue?: boolean; } `,Y=new Map([["IReferenceRange","r"],["IRange","l"]]),Z=new Map([["IWorkbook","workbook"],["ISheet","sheet"],["ICellRanges","ranges"],["ICellRange","range"],["IFormulaContext","context"]]),V=(h,x)=>{Array.from(x.keys()).forEach(b=>{const w=x.get(b);x.set(`${h}.${b}`,w)})},ce=new Map([["Scalar","*"],["FormulaError.Known",$.ScalarType.Error],["Date","Date"],["JSON","JSON"]]),de=new Map([]),X="SheetXL";V(X,Y),V(X,Z),V(X,de);const ue=new Map([["Promise",()=>({async:!0})],["Observable",()=>({stream:!0})]]);let q=null;async function pe(){if(q)return q;try{return await(await Promise.resolve().then(()=>require("./B5_T8MuxVtj2DMdb.cjs"))).initialize()}catch(h){throw q=null,h}finally{q=null}}exports.compileModule=async function(h){const x=h?.source??null;if(!x)return null;const b=(h.disableBundle||h.declarationsOnly)??!1,w=[se(),pe()],K=await Promise.all(w),j=K[0],n=K[1];let F="",f=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`,_="lib.d.ts",H="global.d.ts",M={[S]:x,[_]:` /** * 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>; } `,[H]:j},ee={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=>_,getNewLine:()=>` `},B=n.createProgram([S,H],T,ee),O=B.getTypeChecker(),te=B.getSourceFile(S),W=B.emit();W.diagnostics.length>0&&console.warn(W.diagnostics),F=M[`${a}.js`];const A=(e,t,u,m)=>{if(e){if(e.kind===n.SyntaxKind.NumberKeyword)t.scalar=$.ScalarType.Number;else if(e.kind===n.SyntaxKind.StringKeyword)t.scalar=$.ScalarType.String;else if(e.kind===n.SyntaxKind.BooleanKeyword)t.scalar=$.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=$.ScalarType.Null}else if(e.kind===n.SyntaxKind.BigIntKeyword)t.scalar=$.ScalarType.Number;else if(e.kind===n.SyntaxKind.AnyKeyword)t.scalar=$.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,A(o,t,u,m)}else if(e.kind!==n.SyntaxKind.TupleType){if(e.kind===n.SyntaxKind.TypeReference){const o=e.typeName?.getText?.()??null,R=Y.get(o);let E=!1;R&&(t.range=R,E=!0);const z=ce.get(o);if(z&&(t.scalar=z),z!==void 0&&(E=!0),m){const r=Z.get(o);if(r)return r}else{const r=ue.get(o);if(r){const l={...t,...r()};let y=0;if(l.async&&y++,l.stream&&y++,y>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 d=e.typeArguments;if(d){if(d.length!==1)return void k(e,new Error(`'${o}' must be typed with exactly 1 type: '${e?.parent?.name?.escapedText}'.`));A(d[0],t,u,m)}}}}else k(e,new Error(`Type is not defined for '${t?.name??"return"}'.`))},C=[],k=(e,t)=>{C.push(t)};if(n.forEachChild(te,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=O.getSymbolAtLocation(e.name).getDocumentationComment(O);if(o&&o.length>0&&o[0].text){let d=o[0].text;d=d.replace(/[\r\n]+/g,"\\n").trim(),u.summary=d}const R={};A(e.type,R,t,!1),t.returnType=R;const E={};(d=>(n.getCombinedModifierFlags(d)&n.ModifierFlags.Default)!==0)(e)&&(E.default=!0,f=m),Object.keys(E).length>0&&(t.behavior=E),t.parameters=[];const z=new Map;for(let d=0;d<e.parameters.length;d++){const r=e.parameters[d],l={};l.name=r.name?.getText();const y=A(r.type,l,t,!0);if(y){if(t.parameters.length!==0){const D=e?.parent,c=D?.name?.getText();return void k(e,new Error(`'${t.name}' contexts must be the first parameter: '${c}'.`))}t.context=y;continue}let g;if((r.initializer!==void 0&&r.initializer!==null||r.questionToken!==void 0&&r.questionToken!==null)&&(l.optional=!0,r.initializer))try{g=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(D){console.warn(`Couldn't extract default value for parameter '${l.name}'`,D)}r.dotDotDotToken&&(l.rest=!0),t.parameters.push(l);const s={description:""};u.parameters[l.name]=s;const i=O.getSymbolAtLocation(r.name).getDocumentationComment(O);i&&i.length>0&&i[0].text&&(s.description=i[0].text),g!==void 0&&(s.defaultValue=g),z.set(l.name,l)}if(e.jsDoc&&e.jsDoc.length>0){const d=e.jsDoc;for(let r=0;r<d.length;r++){const l=d[r]?.tags;if(l)for(let y=0;y<l.length;y++){const g=l[y];let s=g?.tagName?.text;if(!s)continue;s=s.toLowerCase();let i=g.comment;const D=s==="hidden";if((typeof i=="string"||D)&&(typeof i=="string"&&(i=i.replace(/[\r\n]+/g,"\\n").trim()),D||!i||(i=i.split(/\\n/)[0],i&&i.length!==0))){if(i&&typeof i=="string"){const c=/\{@link(code|plain)?\s+([^}|]+)(?:\s*\|\s*([^}]+))?\}/g;let v,N=i,P=[];for(;(v=c.exec(i))!==null;){const[J,U,re,Q]=v,ie=[re.trim()];Q&&ie.push(Q.trim())}i=N,P.length>0&&s==="see"&&(u.links||(u.links=[]),u.links.push(...P))}if(s==="name"){const c=i;c!==m&&(u.name=c)}else if(s!=="description"){if(s==="summary"){const c=i;c&&(u.summary=c)}else if(s==="param"){const c=g.name?.text,v=z.get(c);if(!v){C.push(new Error(`Parameter '${c}' not found in function '${m}'.`));continue}if(g.typeExpression&&g.typeExpression.type)try{const N=g.typeExpression.type;if(N.kind===n.SyntaxKind.UnionType){const P=[];v.enums=P,N.types.forEach(J=>{if(J.kind===n.SyntaxKind.LiteralType){const U=J.literal.text;U&&P.push(U)}})}}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 c=!0;const v=i?.toLowerCase();v==="false"?c=!1:v!=="true"&&(c=i),c!==!1&&(u.hidden=c??!0)}}}}}}Object.keys(t.returnType).length===0&&delete t.returnType,p.push([t,u])}catch(o){k(e,new Error(`'${m}': ${o.message}`))}}}),C.length>0)throw console.warn(C),new Error("There were compilation errors.",{cause:C});if(p.length===0)throw new Error("No exported functions.");const ne=`${ae.CommonUtils.uuidV4()}-script`;try{b||C.length!==0||(F=await le(0,F,a))}catch{console.warn("Error bundling script")}const G={functions:p,commitId:ne,source:x,name:"Script",language:"typescript",compiled:F};return f&&(G.autoRun=f),G};