@siliconst/metaui 1.4.13 → 1.4.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost-dbg.js +50 -3
- package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost-dbg.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.d.ts +1 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.d.ts.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.js +1 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.ts +57 -4
- package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost-dbg.js +44 -2
- package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost-dbg.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost.d.ts +4 -0
- package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost.d.ts.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost.js +1 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost.ts +51 -4
- package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DialogDelegate-dbg.js +16 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DialogDelegate-dbg.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DialogDelegate.d.ts +6 -0
- package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DialogDelegate.d.ts.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DialogDelegate.js +1 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DialogDelegate.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DialogDelegate.ts +16 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ValidationDelegate-dbg.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ValidationDelegate.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ValidationDelegate.ts +2 -2
- package/src/nz/co/siliconst/ui5/metaui/core/SchemaBuilderRegistry-dbg.js +47 -0
- package/src/nz/co/siliconst/ui5/metaui/core/SchemaBuilderRegistry-dbg.js.map +1 -0
- package/src/nz/co/siliconst/ui5/metaui/core/SchemaBuilderRegistry.d.ts +23 -0
- package/src/nz/co/siliconst/ui5/metaui/core/SchemaBuilderRegistry.d.ts.map +1 -0
- package/src/nz/co/siliconst/ui5/metaui/core/SchemaBuilderRegistry.js +2 -0
- package/src/nz/co/siliconst/ui5/metaui/core/SchemaBuilderRegistry.js.map +1 -0
- package/src/nz/co/siliconst/ui5/metaui/core/SchemaBuilderRegistry.ts +45 -0
- package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer-dbg.js +17 -0
- package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer-dbg.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.d.ts +10 -1
- package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.d.ts.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.js +1 -1
- package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.ts +19 -1
- package/src/nz/co/siliconst/ui5/metaui/interfaces/ISchema-dbg.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/interfaces/ISchema.d.ts +7 -0
- package/src/nz/co/siliconst/ui5/metaui/interfaces/ISchema.d.ts.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/interfaces/ISchema.ts +9 -0
- package/src/nz/co/siliconst/ui5/metaui/interfaces/ISchemaBuilderPlugin-dbg.js +2 -0
- package/src/nz/co/siliconst/ui5/metaui/interfaces/ISchemaBuilderPlugin-dbg.js.map +1 -0
- package/src/nz/co/siliconst/ui5/metaui/interfaces/ISchemaBuilderPlugin.d.ts +23 -0
- package/src/nz/co/siliconst/ui5/metaui/interfaces/ISchemaBuilderPlugin.d.ts.map +1 -0
- package/src/nz/co/siliconst/ui5/metaui/interfaces/ISchemaBuilderPlugin.js +2 -0
- package/src/nz/co/siliconst/ui5/metaui/interfaces/ISchemaBuilderPlugin.js.map +1 -0
- package/src/nz/co/siliconst/ui5/metaui/interfaces/ISchemaBuilderPlugin.ts +23 -0
- package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout-dbg.js +6 -1
- package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout-dbg.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.d.ts.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.js +1 -1
- package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.ts +6 -1
- package/src/nz/co/siliconst/ui5/metaui/library-preload.js +14 -6
- package/src/nz/co/siliconst/ui5/metaui/library-preload.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin-dbg.js +29 -17
- package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin-dbg.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin.d.ts.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin.js +1 -1
- package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin.js.map +1 -1
- package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin.ts +32 -15
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerBuilder-dbg.js +226 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerBuilder-dbg.js.map +1 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerBuilder.d.ts +63 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerBuilder.d.ts.map +1 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerBuilder.js +2 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerBuilder.js.map +1 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerBuilder.ts +233 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerRefResolver-dbg.js +43 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerRefResolver-dbg.js.map +1 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerRefResolver.d.ts +15 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerRefResolver.d.ts.map +1 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerRefResolver.js +2 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerRefResolver.js.map +1 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerRefResolver.ts +37 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerTypeMapper-dbg.js +37 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerTypeMapper-dbg.js.map +1 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerTypeMapper.d.ts +18 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerTypeMapper.d.ts.map +1 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerTypeMapper.js +2 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerTypeMapper.js.map +1 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerTypeMapper.ts +28 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerUIMapper-dbg.js +84 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerUIMapper-dbg.js.map +1 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerUIMapper.d.ts +27 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerUIMapper.d.ts.map +1 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerUIMapper.js +2 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerUIMapper.js.map +1 -0
- package/src/nz/co/siliconst/ui5/metaui/swagger/SwaggerUIMapper.ts +80 -0
|
@@ -47,15 +47,12 @@ sap.ui.define(["./BasePlugin", "sap/m/MultiInput", "sap/m/Token", "sap/m/Text"],
|
|
|
47
47
|
tokenUpdate: oEvent => {
|
|
48
48
|
const params = oEvent.getParameters();
|
|
49
49
|
const type = params.type;
|
|
50
|
-
|
|
50
|
+
if (type === "removed") {
|
|
51
|
+
const model = mi.getModel(modelName);
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if (type === "added") {
|
|
56
|
-
const addedTokens = params.addedTokens;
|
|
57
|
-
addedTokens.forEach(t => arr.push(t.getText()));
|
|
58
|
-
} else if (type === "removed") {
|
|
53
|
+
// Get current array from model
|
|
54
|
+
const rawArr = model.getProperty(bindingPath);
|
|
55
|
+
const arr = Array.isArray(rawArr) ? [...rawArr] : [];
|
|
59
56
|
const removedTokens = params.removedTokens;
|
|
60
57
|
removedTokens.forEach(t => {
|
|
61
58
|
const text = t.getText();
|
|
@@ -64,25 +61,40 @@ sap.ui.define(["./BasePlugin", "sap/m/MultiInput", "sap/m/Token", "sap/m/Text"],
|
|
|
64
61
|
arr.splice(idx, 1);
|
|
65
62
|
}
|
|
66
63
|
});
|
|
64
|
+
|
|
65
|
+
// Update model
|
|
66
|
+
model.setProperty(bindingPath, arr);
|
|
67
|
+
|
|
68
|
+
// Trigger engine validation/extraction
|
|
69
|
+
const result = this.validateAndApplyVisualState();
|
|
70
|
+
if (this.onChange) {
|
|
71
|
+
this.onChange(result.isValid, this.fieldKey);
|
|
72
|
+
}
|
|
67
73
|
}
|
|
74
|
+
}
|
|
75
|
+
});
|
|
68
76
|
|
|
69
|
-
|
|
77
|
+
// Add validator to instantly accept typed text, update model, and clear input
|
|
78
|
+
mi.addValidator(args => {
|
|
79
|
+
const text = args.text?.trim();
|
|
80
|
+
if (text) {
|
|
81
|
+
const model = mi.getModel(modelName);
|
|
82
|
+
const rawArr = model.getProperty(bindingPath);
|
|
83
|
+
const arr = Array.isArray(rawArr) ? [...rawArr] : [];
|
|
84
|
+
arr.push(text);
|
|
70
85
|
model.setProperty(bindingPath, arr);
|
|
71
86
|
|
|
87
|
+
// Clear the input value immediately
|
|
88
|
+
mi.setValue("");
|
|
89
|
+
|
|
72
90
|
// Trigger engine validation/extraction
|
|
73
91
|
const result = this.validateAndApplyVisualState();
|
|
74
92
|
if (this.onChange) {
|
|
75
93
|
this.onChange(result.isValid, this.fieldKey);
|
|
76
94
|
}
|
|
77
95
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
// Add validator to instantly accept typed text as a token
|
|
81
|
-
mi.addValidator(args => {
|
|
82
|
-
return new Token({
|
|
83
|
-
key: args.text,
|
|
84
|
-
text: args.text
|
|
85
|
-
});
|
|
96
|
+
// Return null to explicitly prevent MultiInput from modifying the bound aggregation
|
|
97
|
+
return null;
|
|
86
98
|
});
|
|
87
99
|
|
|
88
100
|
// Bind existing strings to tokens using a factory function
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultiInputPlugin-dbg.js","names":["BasePlugin","___BasePlugin","MultiInputPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","metadata","isEditable","control","TextControl","id","generateStableId","text","path","formatter","val","Array","isArray","join","applyCommonDirectives","mi","MultiInput","enabled","ui","readOnly","placeholder","label","showValueHelp","tokenUpdate","oEvent","params","getParameters","type","model","getModel","rawArr","getProperty","arr","addedTokens","forEach","t","push","getText","removedTokens","idx","indexOf","splice","setProperty","result","validateAndApplyVisualState","isValid","fieldKey","addValidator","args","Token","key","bindAggregation","factory","sId","oContext","getObject","getValue","tokens","getTokens","map","applyState","setEnabled","__exports","__esModule"],"sources":["MultiInputPlugin.ts"],"sourcesContent":["/**\n * @file MultiInputPlugin.ts\n * @description Renders a sap.m.MultiInput for primitive arrays (e.g. arrays of strings).\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport MultiInput from \"sap/m/MultiInput\";\nimport Token from \"sap/m/Token\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\nimport JSONModel from \"sap/ui/model/json/JSONModel\";\nimport Event from \"sap/ui/base/Event\";\nimport Context from \"sap/ui/model/Context\";\n\n/**\n * Handles rendering logic for arrays of primitive strings.\n * Users can type custom strings and press Enter to add them as tokens.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class MultiInputPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.MultiInput` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured MultiInput control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n\n if (!this.isEditable) {\n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: {\n path: `${modelName}>${bindingPath}`,\n formatter: (val: unknown[]) => Array.isArray(val) ? val.join(\", \") : \"\"\n }\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n \n const mi = new MultiInput({\n id: this.generateStableId(engineScopeId, bindingPath),\n enabled: !fieldMetadata.ui?.readOnly,\n placeholder: fieldMetadata.ui?.label || \"Type and press Enter...\",\n showValueHelp: false, // We don't have a list of options for primitive tags\n tokenUpdate: (oEvent: Event) => {\n const params = oEvent.getParameters();\n const type = params.type;\n const model = mi.getModel(modelName) as JSONModel;\n \n // Get current array from model\n const rawArr = model.getProperty(bindingPath);\n const arr: string[] = Array.isArray(rawArr) ? [...rawArr] : [];\n \n if (type === \"added\") {\n const addedTokens = params.addedTokens as Token[];\n addedTokens.forEach(t => arr.push(t.getText()));\n } else if (type === \"removed\") {\n const removedTokens = params.removedTokens as Token[];\n removedTokens.forEach(t => {\n const text = t.getText();\n const idx = arr.indexOf(text);\n if (idx > -1) {\n arr.splice(idx, 1);\n }\n });\n }\n \n // Update model\n model.setProperty(bindingPath, arr);\n \n // Trigger engine validation/extraction\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n });\n\n // Add validator to instantly accept typed text as a token\n mi.addValidator((args: { text: string }) => {\n return new Token({ key: args.text, text: args.text });\n });\n\n // Bind existing strings to tokens using a factory function\n mi.bindAggregation(\"tokens\", {\n path: `${modelName}>${bindingPath}`,\n factory: (sId: string, oContext: Context) => {\n const text = (oContext.getObject() as string) || \"\";\n return new Token(sId, { key: text, text: text });\n }\n });\n\n this.control = mi;\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n /**\n * Retrieves the current primitive array from the model.\n * @returns {unknown} The array of string tokens.\n */\n protected getValue(): unknown {\n if (!this.control) return [];\n const tokens = (this.control as MultiInput).getTokens();\n return tokens.map(t => t.getText());\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as MultiInput).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"MultiInputPlugin-dbg.js","names":["BasePlugin","___BasePlugin","MultiInputPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","metadata","isEditable","control","TextControl","id","generateStableId","text","path","formatter","val","Array","isArray","join","applyCommonDirectives","mi","MultiInput","enabled","ui","readOnly","placeholder","label","showValueHelp","tokenUpdate","oEvent","params","getParameters","type","model","getModel","rawArr","getProperty","arr","removedTokens","forEach","t","getText","idx","indexOf","splice","setProperty","result","validateAndApplyVisualState","isValid","fieldKey","addValidator","args","trim","push","setValue","bindAggregation","factory","sId","oContext","getObject","Token","key","getValue","tokens","getTokens","map","applyState","setEnabled","__exports","__esModule"],"sources":["MultiInputPlugin.ts"],"sourcesContent":["/**\n * @file MultiInputPlugin.ts\n * @description Renders a sap.m.MultiInput for primitive arrays (e.g. arrays of strings).\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport MultiInput from \"sap/m/MultiInput\";\nimport Token from \"sap/m/Token\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\nimport JSONModel from \"sap/ui/model/json/JSONModel\";\nimport Event from \"sap/ui/base/Event\";\nimport Context from \"sap/ui/model/Context\";\n\n/**\n * Handles rendering logic for arrays of primitive strings.\n * Users can type custom strings and press Enter to add them as tokens.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class MultiInputPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.MultiInput` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured MultiInput control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n\n if (!this.isEditable) {\n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: {\n path: `${modelName}>${bindingPath}`,\n formatter: (val: unknown[]) => Array.isArray(val) ? val.join(\", \") : \"\"\n }\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n \n const mi = new MultiInput({\n id: this.generateStableId(engineScopeId, bindingPath),\n enabled: !fieldMetadata.ui?.readOnly,\n placeholder: fieldMetadata.ui?.label || \"Type and press Enter...\",\n showValueHelp: false, // We don't have a list of options for primitive tags\n tokenUpdate: (oEvent: Event) => {\n const params = oEvent.getParameters();\n const type = params.type;\n \n if (type === \"removed\") {\n const model = mi.getModel(modelName) as JSONModel;\n \n // Get current array from model\n const rawArr = model.getProperty(bindingPath);\n const arr: string[] = Array.isArray(rawArr) ? [...rawArr] : [];\n\n const removedTokens = params.removedTokens as Token[];\n removedTokens.forEach(t => {\n const text = t.getText();\n const idx = arr.indexOf(text);\n if (idx > -1) {\n arr.splice(idx, 1);\n }\n });\n \n // Update model\n model.setProperty(bindingPath, arr);\n \n // Trigger engine validation/extraction\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n }\n });\n\n // Add validator to instantly accept typed text, update model, and clear input\n mi.addValidator((args: { text: string }) => {\n const text = args.text?.trim();\n if (text) {\n const model = mi.getModel(modelName) as JSONModel;\n const rawArr = model.getProperty(bindingPath);\n const arr: string[] = Array.isArray(rawArr) ? [...rawArr] : [];\n \n arr.push(text);\n model.setProperty(bindingPath, arr);\n \n // Clear the input value immediately\n mi.setValue(\"\");\n \n // Trigger engine validation/extraction\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n // Return null to explicitly prevent MultiInput from modifying the bound aggregation\n return null;\n });\n\n // Bind existing strings to tokens using a factory function\n mi.bindAggregation(\"tokens\", {\n path: `${modelName}>${bindingPath}`,\n factory: (sId: string, oContext: Context) => {\n const text = (oContext.getObject() as string) || \"\";\n return new Token(sId, { key: text, text: text });\n }\n });\n\n this.control = mi;\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n /**\n * Retrieves the current primitive array from the model.\n * @returns {unknown} The array of string tokens.\n */\n protected getValue(): unknown {\n if (!this.control) return [];\n const tokens = (this.control as MultiInput).getTokens();\n return tokens.map(t => t.getText());\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as MultiInput).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultiInputPlugin.d.ts","sourceRoot":"../../../../../../../../..","sources":["src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,8DAA8D,CAAC;IAC9E;;;OAGG;IAEH,OAAO,EAAE,UAAU,EAAE,MAAM,wDAAwD,CAAC;IACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;IAGlF,OAAO,OAAO,MAAM,qBAAqB,CAAC;IAM1C;;;;;;OAMG;IACH,MAAa,gBAAiB,SAAQ,UAAU;QAC5C;;;;;;;;;WASG;QACI,MAAM,CAAC,aAAa,EAAE,iBAAiB,EAAG,WAAW,EAAE,MAAM,EAAG,SAAS,GAAE,MAAe,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO;
|
|
1
|
+
{"version":3,"file":"MultiInputPlugin.d.ts","sourceRoot":"../../../../../../../../..","sources":["src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,8DAA8D,CAAC;IAC9E;;;OAGG;IAEH,OAAO,EAAE,UAAU,EAAE,MAAM,wDAAwD,CAAC;IACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;IAGlF,OAAO,OAAO,MAAM,qBAAqB,CAAC;IAM1C;;;;;;OAMG;IACH,MAAa,gBAAiB,SAAQ,UAAU;QAC5C;;;;;;;;;WASG;QACI,MAAM,CAAC,aAAa,EAAE,iBAAiB,EAAG,WAAW,EAAE,MAAM,EAAG,SAAS,GAAE,MAAe,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO;QA2F7L;;;WAGG;QACH,SAAS,CAAC,QAAQ,IAAI,OAAO;QAM7B;;WAEG;QACH,SAAS,CAAC,UAAU,IAAI,IAAI;KAM/B;CAEA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
sap.ui.define(["./BasePlugin","sap/m/MultiInput","sap/m/Token","sap/m/Text"],function(t,e,n
|
|
1
|
+
sap.ui.define(["./BasePlugin","sap/m/MultiInput","sap/m/Token","sap/m/Text"],function(t,e,s,n){"use strict";const i=t["BasePlugin"];class a extends i{render(t,i,a="meta",r,o){this.onChange=o;this.metadata=t;if(!this.isEditable){this.control=new n({id:this.generateStableId(r,i),text:{path:`${a}>${i}`,formatter:t=>Array.isArray(t)?t.join(", "):""}});this.applyCommonDirectives(this.control,t,a);return this.control}const l=new e({id:this.generateStableId(r,i),enabled:!t.ui?.readOnly,placeholder:t.ui?.label||"Type and press Enter...",showValueHelp:false,tokenUpdate:t=>{const e=t.getParameters();const s=e.type;if(s==="removed"){const t=l.getModel(a);const s=t.getProperty(i);const n=Array.isArray(s)?[...s]:[];const r=e.removedTokens;r.forEach(t=>{const e=t.getText();const s=n.indexOf(e);if(s>-1){n.splice(s,1)}});t.setProperty(i,n);const o=this.validateAndApplyVisualState();if(this.onChange){this.onChange(o.isValid,this.fieldKey)}}}});l.addValidator(t=>{const e=t.text?.trim();if(e){const t=l.getModel(a);const s=t.getProperty(i);const n=Array.isArray(s)?[...s]:[];n.push(e);t.setProperty(i,n);l.setValue("");const r=this.validateAndApplyVisualState();if(this.onChange){this.onChange(r.isValid,this.fieldKey)}}return null});l.bindAggregation("tokens",{path:`${a}>${i}`,factory:(t,e)=>{const n=e.getObject()||"";return new s(t,{key:n,text:n})}});this.control=l;this.applyCommonDirectives(this.control,t,a);return this.control}getValue(){if(!this.control)return[];const t=this.control.getTokens();return t.map(t=>t.getText())}applyState(){if(this.control&&this.metadata){if(!this.isEditable)return;this.control.setEnabled(!this.metadata.ui?.readOnly)}}}var r={__esModule:true};r.MultiInputPlugin=a;return r});
|
|
2
2
|
//# sourceMappingURL=MultiInputPlugin.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultiInputPlugin.js","names":["BasePlugin","___BasePlugin","MultiInputPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","isEditable","control","TextControl","id","generateStableId","text","path","formatter","val","Array","isArray","join","applyCommonDirectives","mi","MultiInput","enabled","ui","readOnly","placeholder","label","showValueHelp","tokenUpdate","oEvent","params","getParameters","type","model","getModel","rawArr","getProperty","arr","
|
|
1
|
+
{"version":3,"file":"MultiInputPlugin.js","names":["BasePlugin","___BasePlugin","MultiInputPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","isEditable","control","TextControl","id","generateStableId","text","path","formatter","val","Array","isArray","join","applyCommonDirectives","mi","MultiInput","enabled","ui","readOnly","placeholder","label","showValueHelp","tokenUpdate","oEvent","params","getParameters","type","model","getModel","rawArr","getProperty","arr","removedTokens","forEach","t","getText","idx","indexOf","splice","setProperty","result","validateAndApplyVisualState","isValid","fieldKey","addValidator","args","trim","push","setValue","bindAggregation","factory","sId","oContext","getObject","Token","key","getValue","tokens","getTokens","map","applyState","setEnabled","__exports","__esModule"],"sources":["MultiInputPlugin.ts"],"sourcesContent":["/**\n * @file MultiInputPlugin.ts\n * @description Renders a sap.m.MultiInput for primitive arrays (e.g. arrays of strings).\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport MultiInput from \"sap/m/MultiInput\";\nimport Token from \"sap/m/Token\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\nimport JSONModel from \"sap/ui/model/json/JSONModel\";\nimport Event from \"sap/ui/base/Event\";\nimport Context from \"sap/ui/model/Context\";\n\n/**\n * Handles rendering logic for arrays of primitive strings.\n * Users can type custom strings and press Enter to add them as tokens.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class MultiInputPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.MultiInput` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured MultiInput control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n\n if (!this.isEditable) {\n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: {\n path: `${modelName}>${bindingPath}`,\n formatter: (val: unknown[]) => Array.isArray(val) ? val.join(\", \") : \"\"\n }\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n \n const mi = new MultiInput({\n id: this.generateStableId(engineScopeId, bindingPath),\n enabled: !fieldMetadata.ui?.readOnly,\n placeholder: fieldMetadata.ui?.label || \"Type and press Enter...\",\n showValueHelp: false, // We don't have a list of options for primitive tags\n tokenUpdate: (oEvent: Event) => {\n const params = oEvent.getParameters();\n const type = params.type;\n \n if (type === \"removed\") {\n const model = mi.getModel(modelName) as JSONModel;\n \n // Get current array from model\n const rawArr = model.getProperty(bindingPath);\n const arr: string[] = Array.isArray(rawArr) ? [...rawArr] : [];\n\n const removedTokens = params.removedTokens as Token[];\n removedTokens.forEach(t => {\n const text = t.getText();\n const idx = arr.indexOf(text);\n if (idx > -1) {\n arr.splice(idx, 1);\n }\n });\n \n // Update model\n model.setProperty(bindingPath, arr);\n \n // Trigger engine validation/extraction\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n }\n });\n\n // Add validator to instantly accept typed text, update model, and clear input\n mi.addValidator((args: { text: string }) => {\n const text = args.text?.trim();\n if (text) {\n const model = mi.getModel(modelName) as JSONModel;\n const rawArr = model.getProperty(bindingPath);\n const arr: string[] = Array.isArray(rawArr) ? [...rawArr] : [];\n \n arr.push(text);\n model.setProperty(bindingPath, arr);\n \n // Clear the input value immediately\n mi.setValue(\"\");\n \n // Trigger engine validation/extraction\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n // Return null to explicitly prevent MultiInput from modifying the bound aggregation\n return null;\n });\n\n // Bind existing strings to tokens using a factory function\n mi.bindAggregation(\"tokens\", {\n path: `${modelName}>${bindingPath}`,\n factory: (sId: string, oContext: Context) => {\n const text = (oContext.getObject() as string) || \"\";\n return new Token(sId, { key: text, text: text });\n }\n });\n\n this.control = mi;\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n /**\n * Retrieves the current primitive array from the model.\n * @returns {unknown} The array of string tokens.\n */\n protected getValue(): unknown {\n if (!this.control) return [];\n const tokens = (this.control as MultiInput).getTokens();\n return tokens.map(t => t.getText());\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as MultiInput).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"4GAAA,MAKSA,EAAUC,EAAA,cAiBZ,MAAMC,UAAyBF,EAW3BG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAEhB,IAAKK,KAAKE,WAAY,CAClBF,KAAKG,QAAU,IAAIC,EAAY,CAC3BC,GAAIL,KAAKM,iBAAiBR,EAAeF,GACzCW,KAAM,CACFC,KAAM,GAAGX,KAAaD,IACtBa,UAAYC,GAAmBC,MAAMC,QAAQF,GAAOA,EAAIG,KAAK,MAAQ,MAG7Eb,KAAKc,sBAAsBd,KAAKG,QAASR,EAAeE,GACxD,OAAOG,KAAKG,OAChB,CAEA,MAAMY,EAAK,IAAIC,EAAW,CACtBX,GAAIL,KAAKM,iBAAiBR,EAAeF,GACzCqB,SAAUtB,EAAcuB,IAAIC,SAC5BC,YAAazB,EAAcuB,IAAIG,OAAS,0BACxCC,cAAe,MACfC,YAAcC,IACV,MAAMC,EAASD,EAAOE,gBACtB,MAAMC,EAAOF,EAAOE,KAEpB,GAAIA,IAAS,UAAW,CACpB,MAAMC,EAAQb,EAAGc,SAAShC,GAG1B,MAAMiC,EAASF,EAAMG,YAAYnC,GACjC,MAAMoC,EAAgBrB,MAAMC,QAAQkB,GAAU,IAAIA,GAAU,GAE5D,MAAMG,EAAgBR,EAAOQ,cAC7BA,EAAcC,QAAQC,IAClB,MAAM5B,EAAO4B,EAAEC,UACf,MAAMC,EAAML,EAAIM,QAAQ/B,GACxB,GAAI8B,GAAO,EAAG,CACVL,EAAIO,OAAOF,EAAK,EACpB,IAIJT,EAAMY,YAAY5C,EAAaoC,GAG/B,MAAMS,EAASzC,KAAK0C,8BACpB,GAAI1C,KAAKD,SAAU,CACfC,KAAKD,SAAS0C,EAAOE,QAAS3C,KAAK4C,SACvC,CACJ,KAKR7B,EAAG8B,aAAcC,IACb,MAAMvC,EAAOuC,EAAKvC,MAAMwC,OACxB,GAAIxC,EAAM,CACN,MAAMqB,EAAQb,EAAGc,SAAShC,GAC1B,MAAMiC,EAASF,EAAMG,YAAYnC,GACjC,MAAMoC,EAAgBrB,MAAMC,QAAQkB,GAAU,IAAIA,GAAU,GAE5DE,EAAIgB,KAAKzC,GACTqB,EAAMY,YAAY5C,EAAaoC,GAG/BjB,EAAGkC,SAAS,IAGZ,MAAMR,EAASzC,KAAK0C,8BACpB,GAAI1C,KAAKD,SAAU,CACfC,KAAKD,SAAS0C,EAAOE,QAAS3C,KAAK4C,SACvC,CACJ,CAEA,OAAO,OAIX7B,EAAGmC,gBAAgB,SAAU,CACzB1C,KAAM,GAAGX,KAAaD,IACtBuD,QAASA,CAACC,EAAaC,KACnB,MAAM9C,EAAQ8C,EAASC,aAA0B,GACjD,OAAO,IAAIC,EAAMH,EAAK,CAAEI,IAAKjD,EAAMA,KAAMA,OAIjDP,KAAKG,QAAUY,EACff,KAAKc,sBAAsBd,KAAKG,QAASR,EAAeE,GACxD,OAAOG,KAAKG,OAChB,CAMUsD,WACN,IAAKzD,KAAKG,QAAS,MAAO,GAC1B,MAAMuD,EAAU1D,KAAKG,QAAuBwD,YAC5C,OAAOD,EAAOE,IAAIzB,GAAKA,EAAEC,UAC7B,CAKUyB,aACN,GAAI7D,KAAKG,SAAWH,KAAKC,SAAU,CAC/B,IAAKD,KAAKE,WAAY,OACrBF,KAAKG,QAAuB2D,YAAY9D,KAAKC,SAASiB,IAAIC,SAC/D,CACJ,EACH,IAAA4C,EAAA,CAAAC,WAAA,MAAAD,EAAAtE,mBAAA,OAAAsE,CAAA","ignoreList":[]}
|
|
@@ -55,16 +55,14 @@ export class MultiInputPlugin extends BasePlugin {
|
|
|
55
55
|
tokenUpdate: (oEvent: Event) => {
|
|
56
56
|
const params = oEvent.getParameters();
|
|
57
57
|
const type = params.type;
|
|
58
|
-
const model = mi.getModel(modelName) as JSONModel;
|
|
59
|
-
|
|
60
|
-
// Get current array from model
|
|
61
|
-
const rawArr = model.getProperty(bindingPath);
|
|
62
|
-
const arr: string[] = Array.isArray(rawArr) ? [...rawArr] : [];
|
|
63
58
|
|
|
64
|
-
if (type === "
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
59
|
+
if (type === "removed") {
|
|
60
|
+
const model = mi.getModel(modelName) as JSONModel;
|
|
61
|
+
|
|
62
|
+
// Get current array from model
|
|
63
|
+
const rawArr = model.getProperty(bindingPath);
|
|
64
|
+
const arr: string[] = Array.isArray(rawArr) ? [...rawArr] : [];
|
|
65
|
+
|
|
68
66
|
const removedTokens = params.removedTokens as Token[];
|
|
69
67
|
removedTokens.forEach(t => {
|
|
70
68
|
const text = t.getText();
|
|
@@ -73,22 +71,41 @@ export class MultiInputPlugin extends BasePlugin {
|
|
|
73
71
|
arr.splice(idx, 1);
|
|
74
72
|
}
|
|
75
73
|
});
|
|
74
|
+
|
|
75
|
+
// Update model
|
|
76
|
+
model.setProperty(bindingPath, arr);
|
|
77
|
+
|
|
78
|
+
// Trigger engine validation/extraction
|
|
79
|
+
const result = this.validateAndApplyVisualState();
|
|
80
|
+
if (this.onChange) {
|
|
81
|
+
this.onChange(result.isValid, this.fieldKey);
|
|
82
|
+
}
|
|
76
83
|
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// Add validator to instantly accept typed text, update model, and clear input
|
|
88
|
+
mi.addValidator((args: { text: string }) => {
|
|
89
|
+
const text = args.text?.trim();
|
|
90
|
+
if (text) {
|
|
91
|
+
const model = mi.getModel(modelName) as JSONModel;
|
|
92
|
+
const rawArr = model.getProperty(bindingPath);
|
|
93
|
+
const arr: string[] = Array.isArray(rawArr) ? [...rawArr] : [];
|
|
77
94
|
|
|
78
|
-
|
|
95
|
+
arr.push(text);
|
|
79
96
|
model.setProperty(bindingPath, arr);
|
|
80
97
|
|
|
98
|
+
// Clear the input value immediately
|
|
99
|
+
mi.setValue("");
|
|
100
|
+
|
|
81
101
|
// Trigger engine validation/extraction
|
|
82
102
|
const result = this.validateAndApplyVisualState();
|
|
83
103
|
if (this.onChange) {
|
|
84
104
|
this.onChange(result.isValid, this.fieldKey);
|
|
85
105
|
}
|
|
86
106
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
// Add validator to instantly accept typed text as a token
|
|
90
|
-
mi.addValidator((args: { text: string }) => {
|
|
91
|
-
return new Token({ key: args.text, text: args.text });
|
|
107
|
+
// Return null to explicitly prevent MultiInput from modifying the bound aggregation
|
|
108
|
+
return null;
|
|
92
109
|
});
|
|
93
110
|
|
|
94
111
|
// Bind existing strings to tokens using a factory function
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
sap.ui.define(["../utils/Logger", "./SwaggerTypeMapper", "./SwaggerUIMapper", "./SwaggerRefResolver"], function (___utils_Logger, ___SwaggerTypeMapper, ___SwaggerUIMapper, ___SwaggerRefResolver) {
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @file SwaggerBuilder.ts
|
|
6
|
+
* @description Facade orchestration for translating Swagger/OpenAPI JSON into native MetaUI ISchema.
|
|
7
|
+
* Strict Single Responsibility architecture delegates mapping logic to dedicated utilities.
|
|
8
|
+
*/
|
|
9
|
+
const Logger = ___utils_Logger["Logger"];
|
|
10
|
+
const SwaggerTypeMapper = ___SwaggerTypeMapper["SwaggerTypeMapper"];
|
|
11
|
+
const SwaggerUIMapper = ___SwaggerUIMapper["SwaggerUIMapper"];
|
|
12
|
+
const SwaggerRefResolver = ___SwaggerRefResolver["SwaggerRefResolver"];
|
|
13
|
+
class SwaggerBuilder {
|
|
14
|
+
/**
|
|
15
|
+
* Determines if the provided JSON payload is a Swagger or OpenAPI document.
|
|
16
|
+
*
|
|
17
|
+
* @param {any} rawSchema The raw JSON schema to test.
|
|
18
|
+
* @returns {boolean} True if the document contains 'openapi' or 'swagger' root keys.
|
|
19
|
+
*/
|
|
20
|
+
canHandle(rawSchema) {
|
|
21
|
+
return !!(rawSchema && (rawSchema.openapi || rawSchema.swagger));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Builds a strict MetaUI ISchema from the provided OpenAPI payload.
|
|
26
|
+
*
|
|
27
|
+
* @param {any} rawSchema The OpenAPI root document.
|
|
28
|
+
* @returns {ISchema} The translated MetaUI schema.
|
|
29
|
+
*/
|
|
30
|
+
build(rawSchema) {
|
|
31
|
+
return SwaggerBuilder.build(rawSchema);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Asynchronously fetches a remote OpenAPI document and compiles it into a MetaUI ISchema.
|
|
36
|
+
*
|
|
37
|
+
* @param {string} url The URL to fetch the JSON payload from.
|
|
38
|
+
* @param {string} [targetDefinition] Optional. The specific entity schema to extract.
|
|
39
|
+
* @returns {Promise<ISchema>} A Promise resolving to the compiled ISchema.
|
|
40
|
+
*/
|
|
41
|
+
static async fetchAndBuild(url, targetDefinition) {
|
|
42
|
+
try {
|
|
43
|
+
const response = await fetch(url);
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
46
|
+
}
|
|
47
|
+
const swaggerRoot = await response.json();
|
|
48
|
+
return this.build(swaggerRoot, targetDefinition);
|
|
49
|
+
} catch (error) {
|
|
50
|
+
const msg = "Failed to fetch Swagger JSON from URL: " + error.message;
|
|
51
|
+
Logger.error("[MetaUI SwaggerBuilder]", msg);
|
|
52
|
+
throw new Error(msg);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Synchronously builds a MetaUI ISchema from a provided OpenAPI root document.
|
|
58
|
+
* Automatically extracts the requested definition from `components.schemas` or falls back to the first available.
|
|
59
|
+
*
|
|
60
|
+
* @param {any} swaggerRoot The OpenAPI root document.
|
|
61
|
+
* @param {string} [targetDefinition] Optional. The specific entity schema to extract.
|
|
62
|
+
* @returns {ISchema} The translated MetaUI schema.
|
|
63
|
+
*/
|
|
64
|
+
static build(swaggerRoot, targetDefinition) {
|
|
65
|
+
if (!swaggerRoot || typeof swaggerRoot !== "object") {
|
|
66
|
+
throw new Error("[MetaUI SwaggerBuilder] Invalid Swagger root object provided.");
|
|
67
|
+
}
|
|
68
|
+
let targetObject = swaggerRoot;
|
|
69
|
+
if (!targetDefinition) {
|
|
70
|
+
if (swaggerRoot.components && swaggerRoot.components.schemas) {
|
|
71
|
+
const keys = Object.keys(swaggerRoot.components.schemas);
|
|
72
|
+
if (keys.length > 0) targetDefinition = keys[0];
|
|
73
|
+
} else if (swaggerRoot.definitions) {
|
|
74
|
+
const keys = Object.keys(swaggerRoot.definitions);
|
|
75
|
+
if (keys.length > 0) targetDefinition = keys[0];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (targetDefinition) {
|
|
79
|
+
let found = false;
|
|
80
|
+
if (swaggerRoot.components && swaggerRoot.components.schemas && swaggerRoot.components.schemas[targetDefinition]) {
|
|
81
|
+
targetObject = swaggerRoot.components.schemas[targetDefinition];
|
|
82
|
+
found = true;
|
|
83
|
+
} else if (swaggerRoot.definitions && swaggerRoot.definitions[targetDefinition]) {
|
|
84
|
+
targetObject = swaggerRoot.definitions[targetDefinition];
|
|
85
|
+
found = true;
|
|
86
|
+
}
|
|
87
|
+
if (!found) {
|
|
88
|
+
throw new Error(`[MetaUI SwaggerBuilder] Could not find target definition '${targetDefinition}' in components/schemas or definitions.`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const schema = {
|
|
92
|
+
title: targetObject.title || swaggerRoot.info?.title || targetDefinition,
|
|
93
|
+
type: targetObject.type === "array" ? "array" : "object",
|
|
94
|
+
layoutStrategy: targetObject.type === "array" ? "table" : "form"
|
|
95
|
+
};
|
|
96
|
+
if (targetObject.additionalProperties === true) {
|
|
97
|
+
schema.additionalProperties = true;
|
|
98
|
+
}
|
|
99
|
+
if (schema.type === "object") {
|
|
100
|
+
const requiredKeys = Array.isArray(targetObject.required) ? targetObject.required : [];
|
|
101
|
+
schema.properties = this.mapProperties(targetObject.properties || {}, requiredKeys, swaggerRoot);
|
|
102
|
+
} else if (schema.type === "array" && targetObject.items) {
|
|
103
|
+
schema.items = this.mapPropertyMetadata(targetObject.items, "items", false, swaggerRoot);
|
|
104
|
+
}
|
|
105
|
+
return schema;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Recursively traverses and translates an OpenAPI properties block into MetaUI IPropertyMetadata.
|
|
110
|
+
*
|
|
111
|
+
* @param {Record<string, any>} properties The OpenAPI properties object.
|
|
112
|
+
* @param {string[]} requiredKeys An array of keys marked as required in the parent schema.
|
|
113
|
+
* @param {any} swaggerRoot The root document (used for $ref resolution).
|
|
114
|
+
* @returns {Record<string, IPropertyMetadata>} The mapped MetaUI properties object.
|
|
115
|
+
*/
|
|
116
|
+
static mapProperties(properties, requiredKeys, swaggerRoot) {
|
|
117
|
+
const normalizedProps = {};
|
|
118
|
+
for (const key of Object.keys(properties)) {
|
|
119
|
+
const isRequired = requiredKeys.includes(key);
|
|
120
|
+
let propDef = properties[key];
|
|
121
|
+
if (propDef.$ref) {
|
|
122
|
+
const resolved = SwaggerRefResolver.resolve(propDef.$ref, swaggerRoot);
|
|
123
|
+
if (resolved) {
|
|
124
|
+
propDef = {
|
|
125
|
+
...resolved,
|
|
126
|
+
...propDef
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
normalizedProps[key] = this.mapPropertyMetadata(propDef, key, isRequired, swaggerRoot);
|
|
131
|
+
}
|
|
132
|
+
return normalizedProps;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Translates a single OpenAPI property schema into a MetaUI IPropertyMetadata block.
|
|
137
|
+
* Handles local $ref resolution, allOf merging, type mapping, and UI directive injection.
|
|
138
|
+
*
|
|
139
|
+
* @param {any} swaggerProp The OpenAPI property definition.
|
|
140
|
+
* @param {string} keyName The technical key of the property.
|
|
141
|
+
* @param {boolean} isRequired Whether this property is strictly required.
|
|
142
|
+
* @param {any} swaggerRoot The root document (used for $ref resolution).
|
|
143
|
+
* @returns {IPropertyMetadata} The compiled MetaUI property metadata.
|
|
144
|
+
*/
|
|
145
|
+
static mapPropertyMetadata(swaggerProp, keyName, isRequired, swaggerRoot) {
|
|
146
|
+
let currentProp = swaggerProp;
|
|
147
|
+
if (currentProp.$ref) {
|
|
148
|
+
const resolved = SwaggerRefResolver.resolve(currentProp.$ref, swaggerRoot);
|
|
149
|
+
if (resolved) {
|
|
150
|
+
currentProp = {
|
|
151
|
+
...resolved,
|
|
152
|
+
...currentProp
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (Array.isArray(currentProp.allOf)) {
|
|
157
|
+
let merged = {
|
|
158
|
+
...currentProp
|
|
159
|
+
};
|
|
160
|
+
delete merged.allOf;
|
|
161
|
+
for (const subSchema of currentProp.allOf) {
|
|
162
|
+
let resolvedSub = subSchema;
|
|
163
|
+
if (subSchema.$ref) {
|
|
164
|
+
resolvedSub = SwaggerRefResolver.resolve(subSchema.$ref, swaggerRoot) || {};
|
|
165
|
+
}
|
|
166
|
+
merged = {
|
|
167
|
+
...merged,
|
|
168
|
+
...resolvedSub
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
currentProp = merged;
|
|
172
|
+
}
|
|
173
|
+
const type = SwaggerTypeMapper.mapType(currentProp.type);
|
|
174
|
+
const metaProp = {
|
|
175
|
+
type: type,
|
|
176
|
+
required: isRequired
|
|
177
|
+
};
|
|
178
|
+
const uiDirective = SwaggerUIMapper.build(currentProp, keyName);
|
|
179
|
+
if (Object.keys(uiDirective).length > 0) {
|
|
180
|
+
metaProp.ui = uiDirective;
|
|
181
|
+
}
|
|
182
|
+
if (typeof currentProp.maxLength === "number") metaProp.maxLength = currentProp.maxLength;
|
|
183
|
+
if (typeof currentProp.minLength === "number") metaProp.minLength = currentProp.minLength;
|
|
184
|
+
if (typeof currentProp.maximum === "number") metaProp.maximum = currentProp.maximum;
|
|
185
|
+
if (typeof currentProp.minimum === "number") metaProp.minimum = currentProp.minimum;
|
|
186
|
+
if (typeof currentProp.pattern === "string") metaProp.pattern = currentProp.pattern;
|
|
187
|
+
if (typeof currentProp.multipleOf === "number") metaProp.multipleOf = currentProp.multipleOf;
|
|
188
|
+
if (currentProp.default !== undefined) metaProp.default = currentProp.default;
|
|
189
|
+
if (typeof currentProp.nullable === "boolean") metaProp.nullable = currentProp.nullable;
|
|
190
|
+
if (typeof currentProp.writeOnly === "boolean") metaProp.writeOnly = currentProp.writeOnly;
|
|
191
|
+
if (currentProp.example !== undefined) metaProp.example = currentProp.example;
|
|
192
|
+
if (typeof currentProp.deprecated === "boolean") metaProp.deprecated = currentProp.deprecated;
|
|
193
|
+
if (currentProp.exclusiveMinimum !== undefined) metaProp.exclusiveMinimum = currentProp.exclusiveMinimum;
|
|
194
|
+
if (currentProp.exclusiveMaximum !== undefined) metaProp.exclusiveMaximum = currentProp.exclusiveMaximum;
|
|
195
|
+
if (Array.isArray(currentProp.enum)) {
|
|
196
|
+
metaProp.enum = currentProp.enum;
|
|
197
|
+
if (!metaProp.ui) metaProp.ui = {};
|
|
198
|
+
if (!metaProp.ui.widget) {
|
|
199
|
+
if (type === "array") {
|
|
200
|
+
metaProp.ui.widget = "multiSelect";
|
|
201
|
+
} else {
|
|
202
|
+
metaProp.ui.widget = "select";
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (type === "object") {
|
|
207
|
+
if (currentProp.properties) {
|
|
208
|
+
const childRequired = Array.isArray(currentProp.required) ? currentProp.required : [];
|
|
209
|
+
metaProp.properties = this.mapProperties(currentProp.properties, childRequired, swaggerRoot);
|
|
210
|
+
}
|
|
211
|
+
if (currentProp.additionalProperties === true) {
|
|
212
|
+
metaProp.additionalProperties = true;
|
|
213
|
+
}
|
|
214
|
+
} else if (type === "array" && currentProp.items) {
|
|
215
|
+
metaProp.items = this.mapPropertyMetadata(currentProp.items, "items", false, swaggerRoot);
|
|
216
|
+
}
|
|
217
|
+
return metaProp;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
var __exports = {
|
|
221
|
+
__esModule: true
|
|
222
|
+
};
|
|
223
|
+
__exports.SwaggerBuilder = SwaggerBuilder;
|
|
224
|
+
return __exports;
|
|
225
|
+
});
|
|
226
|
+
//# sourceMappingURL=SwaggerBuilder-dbg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SwaggerBuilder-dbg.js","names":["Logger","___utils_Logger","SwaggerTypeMapper","___SwaggerTypeMapper","SwaggerUIMapper","___SwaggerUIMapper","SwaggerRefResolver","___SwaggerRefResolver","SwaggerBuilder","canHandle","rawSchema","openapi","swagger","build","fetchAndBuild","url","targetDefinition","response","fetch","ok","Error","status","swaggerRoot","json","error","msg","message","targetObject","components","schemas","keys","Object","length","definitions","found","schema","title","info","type","layoutStrategy","additionalProperties","requiredKeys","Array","isArray","required","properties","mapProperties","items","mapPropertyMetadata","normalizedProps","key","isRequired","includes","propDef","$ref","resolved","resolve","swaggerProp","keyName","currentProp","allOf","merged","subSchema","resolvedSub","mapType","metaProp","uiDirective","ui","maxLength","minLength","maximum","minimum","pattern","multipleOf","default","undefined","nullable","writeOnly","example","deprecated","exclusiveMinimum","exclusiveMaximum","enum","widget","childRequired","__exports","__esModule"],"sources":["SwaggerBuilder.ts"],"sourcesContent":["/**\n * @file SwaggerBuilder.ts\n * @description Facade orchestration for translating Swagger/OpenAPI JSON into native MetaUI ISchema.\n * Strict Single Responsibility architecture delegates mapping logic to dedicated utilities.\n */\n\nimport { ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { ISchemaBuilderPlugin } from \"../interfaces/ISchemaBuilderPlugin\";\nimport { Logger } from \"../utils/Logger\";\nimport { SwaggerTypeMapper } from \"./SwaggerTypeMapper\";\nimport { SwaggerUIMapper } from \"./SwaggerUIMapper\";\nimport { SwaggerRefResolver } from \"./SwaggerRefResolver\";\n\nexport class SwaggerBuilder implements ISchemaBuilderPlugin {\n\n /**\n * Determines if the provided JSON payload is a Swagger or OpenAPI document.\n * \n * @param {any} rawSchema The raw JSON schema to test.\n * @returns {boolean} True if the document contains 'openapi' or 'swagger' root keys.\n */\n public canHandle(rawSchema: any): boolean {\n return !!(rawSchema && (rawSchema.openapi || rawSchema.swagger));\n }\n\n /**\n * Builds a strict MetaUI ISchema from the provided OpenAPI payload.\n * \n * @param {any} rawSchema The OpenAPI root document.\n * @returns {ISchema} The translated MetaUI schema.\n */\n public build(rawSchema: any): ISchema {\n return SwaggerBuilder.build(rawSchema);\n }\n\n /**\n * Asynchronously fetches a remote OpenAPI document and compiles it into a MetaUI ISchema.\n * \n * @param {string} url The URL to fetch the JSON payload from.\n * @param {string} [targetDefinition] Optional. The specific entity schema to extract.\n * @returns {Promise<ISchema>} A Promise resolving to the compiled ISchema.\n */\n public static async fetchAndBuild(url: string, targetDefinition?: string): Promise<ISchema> {\n try {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n const swaggerRoot = await response.json();\n return this.build(swaggerRoot, targetDefinition);\n } catch (error) {\n const msg = \"Failed to fetch Swagger JSON from URL: \" + (error as Error).message;\n Logger.error(\"[MetaUI SwaggerBuilder]\", msg);\n throw new Error(msg);\n }\n }\n\n /**\n * Synchronously builds a MetaUI ISchema from a provided OpenAPI root document.\n * Automatically extracts the requested definition from `components.schemas` or falls back to the first available.\n * \n * @param {any} swaggerRoot The OpenAPI root document.\n * @param {string} [targetDefinition] Optional. The specific entity schema to extract.\n * @returns {ISchema} The translated MetaUI schema.\n */\n public static build(swaggerRoot: any, targetDefinition?: string): ISchema {\n if (!swaggerRoot || typeof swaggerRoot !== \"object\") {\n throw new Error(\"[MetaUI SwaggerBuilder] Invalid Swagger root object provided.\");\n }\n\n let targetObject = swaggerRoot;\n\n if (!targetDefinition) {\n if (swaggerRoot.components && swaggerRoot.components.schemas) {\n const keys = Object.keys(swaggerRoot.components.schemas);\n if (keys.length > 0) targetDefinition = keys[0];\n } else if (swaggerRoot.definitions) {\n const keys = Object.keys(swaggerRoot.definitions);\n if (keys.length > 0) targetDefinition = keys[0];\n }\n }\n\n if (targetDefinition) {\n let found = false;\n if (swaggerRoot.components && swaggerRoot.components.schemas && swaggerRoot.components.schemas[targetDefinition]) {\n targetObject = swaggerRoot.components.schemas[targetDefinition];\n found = true;\n } else if (swaggerRoot.definitions && swaggerRoot.definitions[targetDefinition]) {\n targetObject = swaggerRoot.definitions[targetDefinition];\n found = true;\n }\n\n if (!found) {\n throw new Error(`[MetaUI SwaggerBuilder] Could not find target definition '${targetDefinition}' in components/schemas or definitions.`);\n }\n }\n\n const schema: ISchema = {\n title: targetObject.title || swaggerRoot.info?.title || targetDefinition,\n type: targetObject.type === \"array\" ? \"array\" : \"object\",\n layoutStrategy: targetObject.type === \"array\" ? \"table\" : \"form\"\n };\n\n if (targetObject.additionalProperties === true) {\n schema.additionalProperties = true;\n }\n\n if (schema.type === \"object\") {\n const requiredKeys = Array.isArray(targetObject.required) ? targetObject.required : [];\n schema.properties = this.mapProperties(targetObject.properties || {}, requiredKeys, swaggerRoot);\n } else if (schema.type === \"array\" && targetObject.items) {\n schema.items = this.mapPropertyMetadata(targetObject.items, \"items\", false, swaggerRoot);\n }\n\n return schema;\n }\n\n /**\n * Recursively traverses and translates an OpenAPI properties block into MetaUI IPropertyMetadata.\n * \n * @param {Record<string, any>} properties The OpenAPI properties object.\n * @param {string[]} requiredKeys An array of keys marked as required in the parent schema.\n * @param {any} swaggerRoot The root document (used for $ref resolution).\n * @returns {Record<string, IPropertyMetadata>} The mapped MetaUI properties object.\n */\n private static mapProperties(properties: Record<string, any>, requiredKeys: string[], swaggerRoot: any): Record<string, IPropertyMetadata> {\n const normalizedProps: Record<string, IPropertyMetadata> = {};\n \n for (const key of Object.keys(properties)) {\n const isRequired = requiredKeys.includes(key);\n let propDef = properties[key];\n\n if (propDef.$ref) {\n const resolved = SwaggerRefResolver.resolve(propDef.$ref, swaggerRoot);\n if (resolved) {\n propDef = { ...resolved, ...propDef };\n }\n }\n\n normalizedProps[key] = this.mapPropertyMetadata(propDef, key, isRequired, swaggerRoot);\n }\n \n return normalizedProps;\n }\n\n /**\n * Translates a single OpenAPI property schema into a MetaUI IPropertyMetadata block.\n * Handles local $ref resolution, allOf merging, type mapping, and UI directive injection.\n * \n * @param {any} swaggerProp The OpenAPI property definition.\n * @param {string} keyName The technical key of the property.\n * @param {boolean} isRequired Whether this property is strictly required.\n * @param {any} swaggerRoot The root document (used for $ref resolution).\n * @returns {IPropertyMetadata} The compiled MetaUI property metadata.\n */\n private static mapPropertyMetadata(swaggerProp: any, keyName: string, isRequired: boolean, swaggerRoot: any): IPropertyMetadata {\n let currentProp = swaggerProp;\n\n if (currentProp.$ref) {\n const resolved = SwaggerRefResolver.resolve(currentProp.$ref, swaggerRoot);\n if (resolved) {\n currentProp = { ...resolved, ...currentProp };\n }\n }\n\n if (Array.isArray(currentProp.allOf)) {\n let merged = { ...currentProp };\n delete merged.allOf;\n for (const subSchema of currentProp.allOf) {\n let resolvedSub = subSchema;\n if (subSchema.$ref) {\n resolvedSub = SwaggerRefResolver.resolve(subSchema.$ref, swaggerRoot) || {};\n }\n merged = { ...merged, ...resolvedSub };\n }\n currentProp = merged;\n }\n\n const type = SwaggerTypeMapper.mapType(currentProp.type);\n\n const metaProp: IPropertyMetadata = {\n type: type,\n required: isRequired\n };\n\n const uiDirective = SwaggerUIMapper.build(currentProp, keyName);\n if (Object.keys(uiDirective).length > 0) {\n metaProp.ui = uiDirective;\n }\n\n if (typeof currentProp.maxLength === \"number\") metaProp.maxLength = currentProp.maxLength;\n if (typeof currentProp.minLength === \"number\") metaProp.minLength = currentProp.minLength;\n if (typeof currentProp.maximum === \"number\") metaProp.maximum = currentProp.maximum;\n if (typeof currentProp.minimum === \"number\") metaProp.minimum = currentProp.minimum;\n if (typeof currentProp.pattern === \"string\") metaProp.pattern = currentProp.pattern;\n\n if (typeof currentProp.multipleOf === \"number\") metaProp.multipleOf = currentProp.multipleOf;\n \n if (currentProp.default !== undefined) metaProp.default = currentProp.default;\n if (typeof currentProp.nullable === \"boolean\") metaProp.nullable = currentProp.nullable;\n if (typeof currentProp.writeOnly === \"boolean\") metaProp.writeOnly = currentProp.writeOnly;\n if (currentProp.example !== undefined) metaProp.example = currentProp.example;\n if (typeof currentProp.deprecated === \"boolean\") metaProp.deprecated = currentProp.deprecated;\n if (currentProp.exclusiveMinimum !== undefined) metaProp.exclusiveMinimum = currentProp.exclusiveMinimum;\n if (currentProp.exclusiveMaximum !== undefined) metaProp.exclusiveMaximum = currentProp.exclusiveMaximum;\n\n if (Array.isArray(currentProp.enum)) {\n metaProp.enum = currentProp.enum;\n if (!metaProp.ui) metaProp.ui = {};\n if (!metaProp.ui.widget) {\n if (type === \"array\") {\n metaProp.ui.widget = \"multiSelect\";\n } else {\n metaProp.ui.widget = \"select\";\n }\n }\n }\n\n if (type === \"object\") {\n if (currentProp.properties) {\n const childRequired = Array.isArray(currentProp.required) ? currentProp.required : [];\n metaProp.properties = this.mapProperties(currentProp.properties, childRequired, swaggerRoot);\n }\n if (currentProp.additionalProperties === true) {\n metaProp.additionalProperties = true;\n }\n } else if (type === \"array\" && currentProp.items) {\n metaProp.items = this.mapPropertyMetadata(currentProp.items, \"items\", false, swaggerRoot);\n }\n\n return metaProp;\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
declare module "nz/co/siliconst/ui5/metaui/swagger/SwaggerBuilder" {
|
|
2
|
+
/**
|
|
3
|
+
* @file SwaggerBuilder.ts
|
|
4
|
+
* @description Facade orchestration for translating Swagger/OpenAPI JSON into native MetaUI ISchema.
|
|
5
|
+
* Strict Single Responsibility architecture delegates mapping logic to dedicated utilities.
|
|
6
|
+
*/
|
|
7
|
+
import { ISchema } from "nz/co/siliconst/ui5/metaui/interfaces/ISchema";
|
|
8
|
+
import { ISchemaBuilderPlugin } from "nz/co/siliconst/ui5/metaui/interfaces/ISchemaBuilderPlugin";
|
|
9
|
+
export class SwaggerBuilder implements ISchemaBuilderPlugin {
|
|
10
|
+
/**
|
|
11
|
+
* Determines if the provided JSON payload is a Swagger or OpenAPI document.
|
|
12
|
+
*
|
|
13
|
+
* @param {any} rawSchema The raw JSON schema to test.
|
|
14
|
+
* @returns {boolean} True if the document contains 'openapi' or 'swagger' root keys.
|
|
15
|
+
*/
|
|
16
|
+
canHandle(rawSchema: any): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Builds a strict MetaUI ISchema from the provided OpenAPI payload.
|
|
19
|
+
*
|
|
20
|
+
* @param {any} rawSchema The OpenAPI root document.
|
|
21
|
+
* @returns {ISchema} The translated MetaUI schema.
|
|
22
|
+
*/
|
|
23
|
+
build(rawSchema: any): ISchema;
|
|
24
|
+
/**
|
|
25
|
+
* Asynchronously fetches a remote OpenAPI document and compiles it into a MetaUI ISchema.
|
|
26
|
+
*
|
|
27
|
+
* @param {string} url The URL to fetch the JSON payload from.
|
|
28
|
+
* @param {string} [targetDefinition] Optional. The specific entity schema to extract.
|
|
29
|
+
* @returns {Promise<ISchema>} A Promise resolving to the compiled ISchema.
|
|
30
|
+
*/
|
|
31
|
+
static fetchAndBuild(url: string, targetDefinition?: string): Promise<ISchema>;
|
|
32
|
+
/**
|
|
33
|
+
* Synchronously builds a MetaUI ISchema from a provided OpenAPI root document.
|
|
34
|
+
* Automatically extracts the requested definition from `components.schemas` or falls back to the first available.
|
|
35
|
+
*
|
|
36
|
+
* @param {any} swaggerRoot The OpenAPI root document.
|
|
37
|
+
* @param {string} [targetDefinition] Optional. The specific entity schema to extract.
|
|
38
|
+
* @returns {ISchema} The translated MetaUI schema.
|
|
39
|
+
*/
|
|
40
|
+
static build(swaggerRoot: any, targetDefinition?: string): ISchema;
|
|
41
|
+
/**
|
|
42
|
+
* Recursively traverses and translates an OpenAPI properties block into MetaUI IPropertyMetadata.
|
|
43
|
+
*
|
|
44
|
+
* @param {Record<string, any>} properties The OpenAPI properties object.
|
|
45
|
+
* @param {string[]} requiredKeys An array of keys marked as required in the parent schema.
|
|
46
|
+
* @param {any} swaggerRoot The root document (used for $ref resolution).
|
|
47
|
+
* @returns {Record<string, IPropertyMetadata>} The mapped MetaUI properties object.
|
|
48
|
+
*/
|
|
49
|
+
private static mapProperties;
|
|
50
|
+
/**
|
|
51
|
+
* Translates a single OpenAPI property schema into a MetaUI IPropertyMetadata block.
|
|
52
|
+
* Handles local $ref resolution, allOf merging, type mapping, and UI directive injection.
|
|
53
|
+
*
|
|
54
|
+
* @param {any} swaggerProp The OpenAPI property definition.
|
|
55
|
+
* @param {string} keyName The technical key of the property.
|
|
56
|
+
* @param {boolean} isRequired Whether this property is strictly required.
|
|
57
|
+
* @param {any} swaggerRoot The root document (used for $ref resolution).
|
|
58
|
+
* @returns {IPropertyMetadata} The compiled MetaUI property metadata.
|
|
59
|
+
*/
|
|
60
|
+
private static mapPropertyMetadata;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=SwaggerBuilder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SwaggerBuilder.d.ts","sourceRoot":"../../../../../../../..","sources":["src/nz/co/siliconst/ui5/metaui/swagger/SwaggerBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,mDAAmD,CAAC;IACnE;;;;OAIG;IAEH,OAAO,EAAE,OAAO,EAAqB,MAAM,+CAA+C,CAAC;IAC3F,OAAO,EAAE,oBAAoB,EAAE,MAAM,4DAA4D,CAAC;IAMlG,MAAa,cAAe,YAAW,oBAAoB;QAEvD;;;;;WAKG;QACI,SAAS,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO;QAIzC;;;;;WAKG;QACI,KAAK,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO;QAIrC;;;;;;WAMG;eACiB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;QAe3F;;;;;;;WAOG;eACW,KAAK,CAAC,WAAW,EAAE,GAAG,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO;QAoDzE;;;;;;;WAOG;QACH,OAAO,CAAC,MAAM,CAAC,aAAa;QAoB5B;;;;;;;;;WASG;QACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;KA6ErC;CAEA"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
sap.ui.define(["../utils/Logger","./SwaggerTypeMapper","./SwaggerUIMapper","./SwaggerRefResolver"],function(e,t,i,r){"use strict";const a=e["Logger"];const n=t["SwaggerTypeMapper"];const s=i["SwaggerUIMapper"];const o=r["SwaggerRefResolver"];class f{canHandle(e){return!!(e&&(e.openapi||e.swagger))}build(e){return f.build(e)}static async fetchAndBuild(e,t){try{const i=await fetch(e);if(!i.ok){throw new Error(`HTTP error! status: ${i.status}`)}const r=await i.json();return this.build(r,t)}catch(e){const t="Failed to fetch Swagger JSON from URL: "+e.message;a.error("[MetaUI SwaggerBuilder]",t);throw new Error(t)}}static build(e,t){if(!e||typeof e!=="object"){throw new Error("[MetaUI SwaggerBuilder] Invalid Swagger root object provided.")}let i=e;if(!t){if(e.components&&e.components.schemas){const i=Object.keys(e.components.schemas);if(i.length>0)t=i[0]}else if(e.definitions){const i=Object.keys(e.definitions);if(i.length>0)t=i[0]}}if(t){let r=false;if(e.components&&e.components.schemas&&e.components.schemas[t]){i=e.components.schemas[t];r=true}else if(e.definitions&&e.definitions[t]){i=e.definitions[t];r=true}if(!r){throw new Error(`[MetaUI SwaggerBuilder] Could not find target definition '${t}' in components/schemas or definitions.`)}}const r={title:i.title||e.info?.title||t,type:i.type==="array"?"array":"object",layoutStrategy:i.type==="array"?"table":"form"};if(i.additionalProperties===true){r.additionalProperties=true}if(r.type==="object"){const t=Array.isArray(i.required)?i.required:[];r.properties=this.mapProperties(i.properties||{},t,e)}else if(r.type==="array"&&i.items){r.items=this.mapPropertyMetadata(i.items,"items",false,e)}return r}static mapProperties(e,t,i){const r={};for(const a of Object.keys(e)){const n=t.includes(a);let s=e[a];if(s.$ref){const e=o.resolve(s.$ref,i);if(e){s={...e,...s}}}r[a]=this.mapPropertyMetadata(s,a,n,i)}return r}static mapPropertyMetadata(e,t,i,r){let a=e;if(a.$ref){const e=o.resolve(a.$ref,r);if(e){a={...e,...a}}}if(Array.isArray(a.allOf)){let e={...a};delete e.allOf;for(const t of a.allOf){let i=t;if(t.$ref){i=o.resolve(t.$ref,r)||{}}e={...e,...i}}a=e}const f=n.mapType(a.type);const l={type:f,required:i};const u=s.build(a,t);if(Object.keys(u).length>0){l.ui=u}if(typeof a.maxLength==="number")l.maxLength=a.maxLength;if(typeof a.minLength==="number")l.minLength=a.minLength;if(typeof a.maximum==="number")l.maximum=a.maximum;if(typeof a.minimum==="number")l.minimum=a.minimum;if(typeof a.pattern==="string")l.pattern=a.pattern;if(typeof a.multipleOf==="number")l.multipleOf=a.multipleOf;if(a.default!==undefined)l.default=a.default;if(typeof a.nullable==="boolean")l.nullable=a.nullable;if(typeof a.writeOnly==="boolean")l.writeOnly=a.writeOnly;if(a.example!==undefined)l.example=a.example;if(typeof a.deprecated==="boolean")l.deprecated=a.deprecated;if(a.exclusiveMinimum!==undefined)l.exclusiveMinimum=a.exclusiveMinimum;if(a.exclusiveMaximum!==undefined)l.exclusiveMaximum=a.exclusiveMaximum;if(Array.isArray(a.enum)){l.enum=a.enum;if(!l.ui)l.ui={};if(!l.ui.widget){if(f==="array"){l.ui.widget="multiSelect"}else{l.ui.widget="select"}}}if(f==="object"){if(a.properties){const e=Array.isArray(a.required)?a.required:[];l.properties=this.mapProperties(a.properties,e,r)}if(a.additionalProperties===true){l.additionalProperties=true}}else if(f==="array"&&a.items){l.items=this.mapPropertyMetadata(a.items,"items",false,r)}return l}}var l={__esModule:true};l.SwaggerBuilder=f;return l});
|
|
2
|
+
//# sourceMappingURL=SwaggerBuilder.js.map
|