1
1
import type { API } from 'jsEngine/api/API' ;
2
2
import 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' ;
4
13
import { ResultRenderer } from 'jsEngine/engine/ResultRenderer' ;
5
14
import { validateAPIArgs } from 'jsEngine/utils/Validators' ;
6
15
import { Component , TFile } from 'obsidian' ;
@@ -50,16 +59,21 @@ export class InternalAPI {
50
59
* @param path
51
60
* @param params
52
61
*/
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 } ) ;
55
64
56
65
const file = this . apiInstance . app . vault . getAbstractFileByPath ( path ) ;
57
66
if ( ! file || ! ( file instanceof TFile ) ) {
58
67
throw new Error ( `File ${ path } not found.` ) ;
59
68
}
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
+ } ) ;
63
77
}
64
78
65
79
/**
@@ -70,16 +84,19 @@ export class InternalAPI {
70
84
* @param path
71
85
* @param params
72
86
*/
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 ( ) } ) , {
75
89
path,
76
90
params,
77
91
} ) ;
78
92
79
93
const component = new Component ( ) ;
80
94
component . load ( ) ;
81
95
try {
82
- return await this . executeFile ( path , { component : component , ...params } ) ;
96
+ return await this . executeFile ( path , {
97
+ component : component ,
98
+ ...params ,
99
+ } ) ;
83
100
} finally {
84
101
component . unload ( ) ;
85
102
}
@@ -89,24 +106,102 @@ export class InternalAPI {
89
106
* Gets the execution context for a specific file, throws when the file does not exist.
90
107
*
91
108
* @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
92
134
*/
93
- public async getContextForFile ( path : string ) : Promise < JsExecutionContext > {
135
+ public async getContextForMarkdownCodeBlock ( path : string ) : Promise < CodeBlockExecutionContext > {
94
136
validateAPIArgs ( z . object ( { path : z . string ( ) } ) , { path } ) ;
95
137
96
138
const file = this . apiInstance . app . vault . getAbstractFileByPath ( path ) ;
97
139
if ( ! file || ! ( file instanceof TFile ) ) {
98
140
throw new Error ( `File ${ path } not found.` ) ;
99
141
}
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
+ }
100
145
101
146
const metadata = this . apiInstance . app . metadataCache . getFileCache ( file ) ;
102
147
103
148
return {
149
+ executionSource : ExecutionSource . MarkdownCodeBlock ,
104
150
file : file ,
105
151
metadata : metadata ?? undefined ,
106
152
block : undefined ,
107
153
} ;
108
154
}
109
155
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
+
110
205
/**
111
206
* Creates execution globals.
112
207
*
0 commit comments