11import { type IPlugin } from 'packages/core/src/IPlugin' ;
2- import { InputFieldAPI } from 'packages/core/src/api/InputFieldAPI' ;
32import { SyntaxHighlightingAPI } from 'packages/core/src/api/SyntaxHighlightingAPI' ;
4- import { type RenderChildType } from 'packages/core/src/config/FieldConfigs' ;
3+ import { RenderChildType } from 'packages/core/src/config/FieldConfigs' ;
54import { type FieldBase } from 'packages/core/src/fields/FieldBase' ;
65import { ButtonActionRunner } from 'packages/core/src/fields/button/ButtonActionRunner' ;
76import { ButtonBase } from 'packages/core/src/fields/button/ButtonBase' ;
@@ -14,26 +13,92 @@ import { ViewFieldBase } from 'packages/core/src/fields/viewFields/ViewFieldBase
1413import { ViewFieldFactory } from 'packages/core/src/fields/viewFields/ViewFieldFactory' ;
1514import type { BindTargetScope } from 'packages/core/src/metadata/BindTargetScope' ;
1615import { BindTargetParser } from 'packages/core/src/parsers/bindTargetParser/BindTargetParser' ;
17- import { InputFieldDeclarationParser } from 'packages/core/src/parsers/inputFieldParser/InputFieldParser' ;
16+ import { InputFieldParser } from 'packages/core/src/parsers/inputFieldParser/InputFieldParser' ;
1817import { ViewFieldParser } from 'packages/core/src/parsers/viewFieldParser/ViewFieldParser' ;
1918import { expectType , getUUID } from 'packages/core/src/utils/Utils' ;
2019import { ErrorLevel , MetaBindInternalError } from 'packages/core/src/utils/errors/MetaBindErrors' ;
20+ import { EmbedBase } from 'packages/core/src/fields/embed/EmbedBase' ;
21+ import { ExcludedBase } from 'packages/core/src/fields/excluded/ExcludedBase' ;
22+ import {
23+ type InputFieldDeclaration ,
24+ type SimpleInputFieldDeclaration ,
25+ } from 'packages/core/src/parsers/inputFieldParser/InputFieldDeclaration' ;
26+ import {
27+ type JsViewFieldDeclaration ,
28+ type SimpleJsViewFieldDeclaration ,
29+ type SimpleViewFieldDeclaration ,
30+ type ViewFieldDeclaration ,
31+ } from 'packages/core/src/parsers/viewFieldParser/ViewFieldDeclaration' ;
32+ import { type ButtonConfig } from 'packages/core/src/config/ButtonConfig' ;
33+ import {
34+ type ButtonDeclaration ,
35+ ButtonParser ,
36+ type InlineButtonDeclaration ,
37+ type SimpleInlineButtonDeclaration ,
38+ } from 'packages/core/src/parsers/ButtonParser' ;
39+ import { JsViewFieldParser } from 'packages/core/src/parsers/viewFieldParser/JsViewFieldParser' ;
2140
2241export enum FieldType {
2342 INPUT_FIELD = 'INPUT_FIELD' ,
2443 VIEW_FIELD = 'VIEW_FIELD' ,
2544 JS_VIEW_FIELD = 'JS_VIEW_FIELD' ,
2645 INLINE_BUTTON = 'INLINE_BUTTON' ,
2746 BUTTON = 'BUTTON' ,
47+ EMBED = 'EMBED' ,
48+ EXCLUDED = 'EXCLUDED' ,
2849}
2950
30- export function isFieldTypeAllowedInline ( type : FieldType ) : boolean {
51+ export interface InputFieldOptions {
52+ renderChildType : RenderChildType ;
53+ declaration : SimpleInputFieldDeclaration | string ;
54+ scope : BindTargetScope | undefined ;
55+ }
56+
57+ export interface ViewFieldOptions {
58+ renderChildType : RenderChildType ;
59+ declaration : SimpleViewFieldDeclaration | string ;
60+ scope : BindTargetScope | undefined ;
61+ }
62+
63+ export interface JsViewFieldOptions {
64+ declaration : SimpleJsViewFieldDeclaration | string ;
65+ }
66+
67+ export interface InlineButtonOptions {
68+ declaration : SimpleInlineButtonDeclaration | string ;
69+ }
70+
71+ export interface ButtonOptions {
72+ declaration : ButtonConfig | string ;
73+ isPreview : boolean ;
74+ }
75+
76+ export interface EmbedOptions {
77+ depth : number ;
78+ content : string ;
79+ }
80+
81+ export interface FieldOptionMap {
82+ [ FieldType . INPUT_FIELD ] : InputFieldOptions ;
83+ [ FieldType . VIEW_FIELD ] : ViewFieldOptions ;
84+ [ FieldType . JS_VIEW_FIELD ] : JsViewFieldOptions ;
85+ [ FieldType . INLINE_BUTTON ] : InlineButtonOptions ;
86+ [ FieldType . BUTTON ] : ButtonOptions ;
87+ [ FieldType . EMBED ] : EmbedOptions ;
88+ [ FieldType . EXCLUDED ] : undefined ;
89+ }
90+
91+ export type InlineFieldType = FieldType . INPUT_FIELD | FieldType . VIEW_FIELD | FieldType . INLINE_BUTTON ;
92+
93+ export function isFieldTypeAllowedInline ( type : FieldType ) : type is InlineFieldType {
3194 return type === FieldType . INPUT_FIELD || type === FieldType . VIEW_FIELD || type === FieldType . INLINE_BUTTON ;
3295}
3396
3497export interface APIFieldOverrides {
35- inputFieldParser ?: InputFieldDeclarationParser ;
98+ inputFieldParser ?: InputFieldParser ;
3699 viewFieldParser ?: ViewFieldParser ;
100+ jsViewFieldParser ?: JsViewFieldParser ;
101+ buttonParser ?: ButtonParser ;
37102 bindTargetParser ?: BindTargetParser ;
38103 inputFieldFactory ?: InputFieldFactory ;
39104 viewFieldFactory ?: ViewFieldFactory ;
@@ -44,10 +109,11 @@ export interface APIFieldOverrides {
44109
45110export abstract class API < Plugin extends IPlugin > {
46111 readonly plugin : Plugin ;
47- readonly inputField : InputFieldAPI ;
48112
49- readonly inputFieldParser : InputFieldDeclarationParser ;
113+ readonly inputFieldParser : InputFieldParser ;
50114 readonly viewFieldParser : ViewFieldParser ;
115+ readonly jsViewFieldParser : JsViewFieldParser ;
116+ readonly buttonParser : ButtonParser ;
51117 readonly bindTargetParser : BindTargetParser ;
52118
53119 readonly inputFieldFactory : InputFieldFactory ;
@@ -60,10 +126,11 @@ export abstract class API<Plugin extends IPlugin> {
60126
61127 constructor ( plugin : Plugin , overrides ?: APIFieldOverrides ) {
62128 this . plugin = plugin ;
63- this . inputField = new InputFieldAPI ( plugin ) ;
64129
65- this . inputFieldParser = overrides ?. inputFieldParser ?? new InputFieldDeclarationParser ( plugin ) ;
130+ this . inputFieldParser = overrides ?. inputFieldParser ?? new InputFieldParser ( plugin ) ;
66131 this . viewFieldParser = overrides ?. viewFieldParser ?? new ViewFieldParser ( plugin ) ;
132+ this . jsViewFieldParser = overrides ?. jsViewFieldParser ?? new JsViewFieldParser ( plugin ) ;
133+ this . buttonParser = overrides ?. buttonParser ?? new ButtonParser ( plugin ) ;
67134 this . bindTargetParser = overrides ?. bindTargetParser ?? new BindTargetParser ( plugin ) ;
68135
69136 this . inputFieldFactory = overrides ?. inputFieldFactory ?? new InputFieldFactory ( plugin ) ;
@@ -75,28 +142,30 @@ export abstract class API<Plugin extends IPlugin> {
75142 this . syntaxHighlighting = overrides ?. syntaxHighlighting ?? new SyntaxHighlightingAPI ( plugin ) ;
76143 }
77144
78- public createField (
79- type : FieldType ,
145+ public createField < Type extends FieldType > (
146+ type : Type ,
80147 filePath : string ,
81- renderChildType : RenderChildType ,
82- content : string ,
83- scope ?: BindTargetScope | undefined ,
148+ options : FieldOptionMap [ Type ] ,
149+ honorExcludedSetting : boolean = true ,
84150 ) : FieldBase {
85- const uuid = getUUID ( ) ;
151+ if ( this . plugin . internal . isFilePathExcluded ( filePath ) && honorExcludedSetting ) {
152+ return this . createExcludedBase ( filePath , undefined ) ;
153+ }
86154
87155 if ( type === FieldType . INPUT_FIELD ) {
88- const declaration = this . inputFieldParser . parseString ( content , filePath , scope ) ;
89- return new InputFieldBase ( this . plugin , uuid , filePath , renderChildType , declaration ) ;
156+ return this . createInputFieldBase ( filePath , options as FieldOptionMap [ FieldType . INPUT_FIELD ] ) ;
90157 } else if ( type === FieldType . VIEW_FIELD ) {
91- const declaration = this . viewFieldParser . parseString ( content , filePath , scope ) ;
92- return new ViewFieldBase ( this . plugin , uuid , filePath , renderChildType , declaration ) ;
158+ return this . createViewFieldBase ( filePath , options as FieldOptionMap [ FieldType . VIEW_FIELD ] ) ;
93159 } else if ( type === FieldType . JS_VIEW_FIELD ) {
94- const declaration = this . viewFieldParser . parseJsString ( content , filePath ) ;
95- return new JsViewField ( this . plugin , uuid , filePath , renderChildType , declaration ) ;
160+ return this . createJsViewFieldBase ( filePath , options as FieldOptionMap [ FieldType . JS_VIEW_FIELD ] ) ;
96161 } else if ( type === FieldType . INLINE_BUTTON ) {
97- return new InlineButtonBase ( this . plugin , uuid , filePath , content ) ;
162+ return this . createInlineButtonBase ( filePath , options as FieldOptionMap [ FieldType . INLINE_BUTTON ] ) ;
98163 } else if ( type === FieldType . BUTTON ) {
99- return new ButtonBase ( this . plugin , uuid , filePath , content , false ) ;
164+ return this . createButtonBase ( filePath , options as FieldOptionMap [ FieldType . BUTTON ] ) ;
165+ } else if ( type === FieldType . EMBED ) {
166+ return this . createEmbedBase ( filePath , options as FieldOptionMap [ FieldType . EMBED ] ) ;
167+ } else if ( type === FieldType . EXCLUDED ) {
168+ return this . createExcludedBase ( filePath , options as FieldOptionMap [ FieldType . EXCLUDED ] ) ;
100169 }
101170
102171 expectType < never > ( type ) ;
@@ -105,35 +174,179 @@ export abstract class API<Plugin extends IPlugin> {
105174 throw new Error ( `Unknown field type: ${ type } ` ) ;
106175 }
107176
177+ public createInlineFieldFromString (
178+ filePath : string ,
179+ fieldString : string ,
180+ scope : BindTargetScope | undefined ,
181+ honorExcludedSetting : boolean = true ,
182+ ) : FieldBase {
183+ const fieldType = this . isInlineFieldDeclarationAndGetType ( fieldString ) ;
184+ if ( fieldType === undefined ) {
185+ throw new MetaBindInternalError ( {
186+ errorLevel : ErrorLevel . CRITICAL ,
187+ effect : 'failed to create inline field' ,
188+ cause : `Invalid inline mdrc type "${ fieldType } "` ,
189+ } ) ;
190+ }
191+
192+ return this . createInlineFieldOfTypeFromString ( fieldType , filePath , fieldString , scope , honorExcludedSetting ) ;
193+ }
194+
195+ public createInlineFieldOfTypeFromString (
196+ type : InlineFieldType ,
197+ filePath : string ,
198+ fieldString : string ,
199+ scope : BindTargetScope | undefined ,
200+ honorExcludedSetting : boolean = true ,
201+ ) : FieldBase {
202+ if ( this . plugin . internal . isFilePathExcluded ( filePath ) && honorExcludedSetting ) {
203+ return this . createExcludedBase ( filePath , undefined ) ;
204+ }
205+
206+ if ( type === FieldType . INPUT_FIELD ) {
207+ return this . createInputFieldBase ( filePath , {
208+ renderChildType : RenderChildType . INLINE ,
209+ declaration : fieldString ,
210+ scope : scope ,
211+ } ) ;
212+ }
213+
214+ if ( type === FieldType . VIEW_FIELD ) {
215+ return this . createViewFieldBase ( filePath , {
216+ renderChildType : RenderChildType . INLINE ,
217+ declaration : fieldString ,
218+ scope : scope ,
219+ } ) ;
220+ }
221+
222+ if ( type === FieldType . INLINE_BUTTON ) {
223+ return this . createInlineButtonBase ( filePath , { declaration : fieldString } ) ;
224+ }
225+
226+ expectType < never > ( type ) ;
227+
228+ throw new MetaBindInternalError ( {
229+ errorLevel : ErrorLevel . CRITICAL ,
230+ effect : 'failed to create inline field' ,
231+ cause : `Invalid inline mdrc type "${ type } "` ,
232+ } ) ;
233+ }
234+
235+ public createInputFieldBase ( filePath : string , options : FieldOptionMap [ FieldType . INPUT_FIELD ] ) : InputFieldBase {
236+ const uuid = getUUID ( ) ;
237+
238+ let declaration : InputFieldDeclaration ;
239+ if ( typeof options . declaration === 'string' ) {
240+ declaration = this . inputFieldParser . fromStringAndValidate ( options . declaration , filePath , options . scope ) ;
241+ } else {
242+ declaration = this . inputFieldParser . fromSimpleDeclarationAndValidate (
243+ options . declaration ,
244+ filePath ,
245+ options . scope ,
246+ ) ;
247+ }
248+
249+ return new InputFieldBase ( this . plugin , uuid , filePath , options . renderChildType , declaration ) ;
250+ }
251+
252+ public createViewFieldBase ( filePath : string , options : FieldOptionMap [ FieldType . VIEW_FIELD ] ) : ViewFieldBase {
253+ const uuid = getUUID ( ) ;
254+
255+ let declaration : ViewFieldDeclaration ;
256+ if ( typeof options . declaration === 'string' ) {
257+ declaration = this . viewFieldParser . fromStringAndValidate ( options . declaration , filePath , options . scope ) ;
258+ } else {
259+ declaration = this . viewFieldParser . fromSimpleDeclarationAndValidate (
260+ options . declaration ,
261+ filePath ,
262+ options . scope ,
263+ ) ;
264+ }
265+
266+ return new ViewFieldBase ( this . plugin , uuid , filePath , options . renderChildType , declaration ) ;
267+ }
268+
269+ public createJsViewFieldBase ( filePath : string , options : FieldOptionMap [ FieldType . JS_VIEW_FIELD ] ) : JsViewField {
270+ const uuid = getUUID ( ) ;
271+
272+ let declaration : JsViewFieldDeclaration ;
273+ if ( typeof options . declaration === 'string' ) {
274+ declaration = this . jsViewFieldParser . fromStringAndValidate ( options . declaration , filePath ) ;
275+ } else {
276+ declaration = this . jsViewFieldParser . fromSimpleDeclarationAndValidate ( options . declaration , filePath ) ;
277+ }
278+
279+ return new JsViewField ( this . plugin , uuid , filePath , declaration ) ;
280+ }
281+
282+ public createInlineButtonBase (
283+ filePath : string ,
284+ options : FieldOptionMap [ FieldType . INLINE_BUTTON ] ,
285+ ) : InlineButtonBase {
286+ const uuid = getUUID ( ) ;
287+
288+ let declaration : InlineButtonDeclaration ;
289+ if ( typeof options . declaration === 'string' ) {
290+ declaration = this . buttonParser . parseInlineString ( options . declaration ) ;
291+ } else {
292+ declaration = this . buttonParser . validateSimpleInlineDeclaration ( options . declaration ) ;
293+ }
294+
295+ return new InlineButtonBase ( this . plugin , uuid , filePath , declaration ) ;
296+ }
297+
298+ public createButtonBase ( filePath : string , options : FieldOptionMap [ FieldType . BUTTON ] ) : ButtonBase {
299+ const uuid = getUUID ( ) ;
300+
301+ let declaration : ButtonDeclaration ;
302+ if ( typeof options . declaration === 'string' ) {
303+ declaration = this . buttonParser . parseButtonString ( options . declaration ) ;
304+ } else {
305+ declaration = this . buttonParser . validateSimpleButtonConfig ( options . declaration ) ;
306+ }
307+
308+ return new ButtonBase ( this . plugin , uuid , filePath , declaration , options . isPreview ) ;
309+ }
310+
311+ public createEmbedBase ( filePath : string , options : FieldOptionMap [ FieldType . EMBED ] ) : EmbedBase {
312+ const uuid = getUUID ( ) ;
313+ return new EmbedBase ( this . plugin , uuid , filePath , options . depth , options . content ) ;
314+ }
315+
316+ public createExcludedBase ( filePath : string , _options : FieldOptionMap [ FieldType . EXCLUDED ] ) : ExcludedBase {
317+ const uuid = getUUID ( ) ;
318+ return new ExcludedBase ( this . plugin , uuid , filePath ) ;
319+ }
320+
108321 /**
109322 * Gets the prefix of a given widget type. (e.g. INPUT or VIEW)
110323 *
111- * @param mdrcType
324+ * @param fieldType
112325 */
113- public getInlineFieldDeclarationPrefix ( mdrcType : FieldType ) : string {
114- if ( mdrcType === FieldType . INPUT_FIELD ) {
326+ public getInlineFieldDeclarationPrefix ( fieldType : FieldType ) : string {
327+ if ( fieldType === FieldType . INPUT_FIELD ) {
115328 return 'INPUT' ;
116- } else if ( mdrcType === FieldType . VIEW_FIELD ) {
329+ } else if ( fieldType === FieldType . VIEW_FIELD ) {
117330 return 'VIEW' ;
118- } else if ( mdrcType === FieldType . INLINE_BUTTON ) {
331+ } else if ( fieldType === FieldType . INLINE_BUTTON ) {
119332 return 'BUTTON' ;
120333 }
121334
122335 throw new MetaBindInternalError ( {
123336 errorLevel : ErrorLevel . CRITICAL ,
124337 effect : 'failed to get declaration prefix' ,
125- cause : `Invalid inline mdrc type "${ mdrcType } "` ,
338+ cause : `Invalid inline mdrc type "${ fieldType } "` ,
126339 } ) ;
127340 }
128341
129342 /**
130343 * Checks if a string is a declaration of a given widget type.
131344 *
132- * @param mdrcType
345+ * @param fieldType
133346 * @param str
134347 */
135- public isInlineFieldDeclaration ( mdrcType : FieldType , str : string ) : boolean {
136- const startStr : string = this . getInlineFieldDeclarationPrefix ( mdrcType ) + '[' ;
348+ public isInlineFieldDeclaration ( fieldType : FieldType , str : string ) : boolean {
349+ const startStr : string = this . getInlineFieldDeclarationPrefix ( fieldType ) + '[' ;
137350 const endStr : string = ']' ;
138351
139352 return str . startsWith ( startStr ) && str . endsWith ( endStr ) ;
@@ -145,7 +358,7 @@ export abstract class API<Plugin extends IPlugin> {
145358 *
146359 * @param str
147360 */
148- public isInlineFieldDeclarationAndGetType ( str : string ) : FieldType | undefined {
361+ public isInlineFieldDeclarationAndGetType ( str : string ) : InlineFieldType | undefined {
149362 if ( ! str . endsWith ( ']' ) ) {
150363 return undefined ;
151364 }
0 commit comments