11import type { API } from 'jsEngine/api/API' ;
22import type { EngineExecutionParams } from 'jsEngine/engine/Engine' ;
3- import type { JsExecution , JsExecutionContext , JsExecutionGlobals , JsExecutionGlobalsConstructionOptions } from 'jsEngine/engine/JsExecution' ;
3+ import type {
4+ JsExecution ,
5+ ExecutionContext ,
6+ JsExecutionGlobals ,
7+ JsExecutionGlobalsConstructionOptions ,
8+ CodeBlockExecutionContext ,
9+ JSFileExecutionContext ,
10+ UnknownExecutionContext ,
11+ } from 'jsEngine/engine/JsExecution' ;
12+ import { ExecutionSource } from 'jsEngine/engine/JsExecution' ;
413import { ResultRenderer } from 'jsEngine/engine/ResultRenderer' ;
514import { validateAPIArgs } from 'jsEngine/utils/Validators' ;
615import { Component , TFile } from 'obsidian' ;
@@ -50,16 +59,21 @@ export class InternalAPI {
5059 * @param path
5160 * @param params
5261 */
53- public async executeFile ( path : string , params : Omit < EngineExecutionParams , 'code' > ) : Promise < JsExecution > {
54- validateAPIArgs ( z . object ( { path : z . string ( ) , params : this . apiInstance . validators . engineExecutionParamsNoCode } ) , { path, params } ) ;
62+ public async executeFile ( path : string , params : Omit < EngineExecutionParams , 'code' | 'context' > ) : Promise < JsExecution > {
63+ validateAPIArgs ( z . object ( { path : z . string ( ) , params : this . apiInstance . validators . engineExecutionParamsFile } ) , { path, params } ) ;
5564
5665 const file = this . apiInstance . app . vault . getAbstractFileByPath ( path ) ;
5766 if ( ! file || ! ( file instanceof TFile ) ) {
5867 throw new Error ( `File ${ path } not found.` ) ;
5968 }
60- const fullParams = params as EngineExecutionParams ;
61- fullParams . code = await this . apiInstance . app . vault . read ( file ) ;
62- return await this . execute ( fullParams ) ;
69+ return await this . execute ( {
70+ ...params ,
71+ code : await this . apiInstance . app . vault . read ( file ) ,
72+ context : {
73+ executionSource : ExecutionSource . JSFile ,
74+ file : file ,
75+ } ,
76+ } ) ;
6377 }
6478
6579 /**
@@ -70,16 +84,19 @@ export class InternalAPI {
7084 * @param path
7185 * @param params
7286 */
73- public async executeFileSimple ( path : string , params ?: Omit < EngineExecutionParams , 'code' | 'component' > ) : Promise < JsExecution > {
74- validateAPIArgs ( z . object ( { path : z . string ( ) , params : this . apiInstance . validators . engineExecutionParamsNoCodeAndComponent . optional ( ) } ) , {
87+ public async executeFileSimple ( path : string , params ?: Omit < EngineExecutionParams , 'code' | 'component' | 'context' > ) : Promise < JsExecution > {
88+ validateAPIArgs ( z . object ( { path : z . string ( ) , params : this . apiInstance . validators . engineExecutionParamsFileSimple . optional ( ) } ) , {
7589 path,
7690 params,
7791 } ) ;
7892
7993 const component = new Component ( ) ;
8094 component . load ( ) ;
8195 try {
82- return await this . executeFile ( path , { component : component , ...params } ) ;
96+ return await this . executeFile ( path , {
97+ component : component ,
98+ ...params ,
99+ } ) ;
83100 } finally {
84101 component . unload ( ) ;
85102 }
@@ -89,24 +106,102 @@ export class InternalAPI {
89106 * Gets the execution context for a specific file, throws when the file does not exist.
90107 *
91108 * @param path
109+ * @deprecated use {@link getContextForMarkdownCodeBlock}, {@link getContextForJSFile}, or {@link getContextForUnknown} instead
110+ */
111+ public async getContextForFile ( path : string ) : Promise < ExecutionContext > {
112+ validateAPIArgs ( z . object ( { path : z . string ( ) } ) , { path } ) ;
113+
114+ const file = this . apiInstance . app . vault . getAbstractFileByPath ( path ) ;
115+ if ( ! file || ! ( file instanceof TFile ) ) {
116+ throw new Error ( `File ${ path } not found.` ) ;
117+ }
118+
119+ const metadata = this . apiInstance . app . metadataCache . getFileCache ( file ) ;
120+
121+ return {
122+ executionSource : ExecutionSource . MarkdownCodeBlock ,
123+ file : file ,
124+ metadata : metadata ?? undefined ,
125+ block : undefined ,
126+ } ;
127+ }
128+
129+ /**
130+ * Gets the execution context for a markdown code block.
131+ *
132+ * @param path The file path of the markdown file the code block is in.
133+ * @returns
92134 */
93- public async getContextForFile ( path : string ) : Promise < JsExecutionContext > {
135+ public async getContextForMarkdownCodeBlock ( path : string ) : Promise < CodeBlockExecutionContext > {
94136 validateAPIArgs ( z . object ( { path : z . string ( ) } ) , { path } ) ;
95137
96138 const file = this . apiInstance . app . vault . getAbstractFileByPath ( path ) ;
97139 if ( ! file || ! ( file instanceof TFile ) ) {
98140 throw new Error ( `File ${ path } not found.` ) ;
99141 }
142+ if ( file . extension !== 'md' && file . extension !== '.md' ) {
143+ throw new Error ( `File ${ path } is not a markdown file. Expected file extension to be ".md".` ) ;
144+ }
100145
101146 const metadata = this . apiInstance . app . metadataCache . getFileCache ( file ) ;
102147
103148 return {
149+ executionSource : ExecutionSource . MarkdownCodeBlock ,
104150 file : file ,
105151 metadata : metadata ?? undefined ,
106152 block : undefined ,
107153 } ;
108154 }
109155
156+ /**
157+ * Gets the execution context for a JS file.
158+ *
159+ * @param path The file path of the JS file.
160+ * @returns
161+ */
162+ public async getContextForJSFile ( path : string ) : Promise < JSFileExecutionContext > {
163+ validateAPIArgs ( z . object ( { path : z . string ( ) } ) , { path } ) ;
164+
165+ const file = this . apiInstance . app . vault . getAbstractFileByPath ( path ) ;
166+ if ( ! file || ! ( file instanceof TFile ) ) {
167+ throw new Error ( `File ${ path } not found.` ) ;
168+ }
169+ if ( file . extension !== 'js' && file . extension !== '.js' ) {
170+ throw new Error ( `File ${ path } is not a JS file. Expected file extension to be ".js".` ) ;
171+ }
172+
173+ return {
174+ executionSource : ExecutionSource . JSFile ,
175+ file : file ,
176+ } ;
177+ }
178+
179+ /**
180+ * Gets an unknown execution context for anything that is not a markdown code block or a JS file.
181+ *
182+ * @param path An optional file path that will get resolved to a {@link TFile}.
183+ * @returns
184+ */
185+ public async getContextForUnknown ( path ?: string ) : Promise < UnknownExecutionContext > {
186+ validateAPIArgs ( z . object ( { path : z . string ( ) . optional ( ) } ) , { path } ) ;
187+
188+ if ( path ) {
189+ const file = this . apiInstance . app . vault . getAbstractFileByPath ( path ) ;
190+ if ( ! file || ! ( file instanceof TFile ) ) {
191+ throw new Error ( `File ${ path } not found.` ) ;
192+ }
193+
194+ return {
195+ executionSource : ExecutionSource . Unknown ,
196+ file : file ,
197+ } ;
198+ } else {
199+ return {
200+ executionSource : ExecutionSource . Unknown ,
201+ } ;
202+ }
203+ }
204+
110205 /**
111206 * Creates execution globals.
112207 *
0 commit comments