d365fo-mcp 1.0.0
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/LICENSE +21 -0
- package/README.md +205 -0
- package/dist/bridge/bridgeAdapter.d.ts +319 -0
- package/dist/bridge/bridgeAdapter.d.ts.map +1 -0
- package/dist/bridge/bridgeAdapter.js +2003 -0
- package/dist/bridge/bridgeAdapter.js.map +1 -0
- package/dist/bridge/bridgeClient.d.ts +255 -0
- package/dist/bridge/bridgeClient.d.ts.map +1 -0
- package/dist/bridge/bridgeClient.js +741 -0
- package/dist/bridge/bridgeClient.js.map +1 -0
- package/dist/bridge/bridgeTypes.d.ts +561 -0
- package/dist/bridge/bridgeTypes.d.ts.map +1 -0
- package/dist/bridge/bridgeTypes.js +6 -0
- package/dist/bridge/bridgeTypes.js.map +1 -0
- package/dist/bridge/debouncedRefresh.d.ts +16 -0
- package/dist/bridge/debouncedRefresh.d.ts.map +1 -0
- package/dist/bridge/debouncedRefresh.js +77 -0
- package/dist/bridge/debouncedRefresh.js.map +1 -0
- package/dist/bridge/index.d.ts +21 -0
- package/dist/bridge/index.d.ts.map +1 -0
- package/dist/bridge/index.js +20 -0
- package/dist/bridge/index.js.map +1 -0
- package/dist/cli/commands/config.d.ts +8 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +77 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +2 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +177 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/indexCmd.d.ts +8 -0
- package/dist/cli/commands/indexCmd.d.ts.map +1 -0
- package/dist/cli/commands/indexCmd.js +78 -0
- package/dist/cli/commands/indexCmd.js.map +1 -0
- package/dist/cli/commands/instance.d.ts +4 -0
- package/dist/cli/commands/instance.d.ts.map +1 -0
- package/dist/cli/commands/instance.js +183 -0
- package/dist/cli/commands/instance.js.map +1 -0
- package/dist/cli/commands/setup.d.ts +4 -0
- package/dist/cli/commands/setup.d.ts.map +1 -0
- package/dist/cli/commands/setup.js +246 -0
- package/dist/cli/commands/setup.js.map +1 -0
- package/dist/cli/commands/start.d.ts +2 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +49 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/update.d.ts +4 -0
- package/dist/cli/commands/update.d.ts.map +1 -0
- package/dist/cli/commands/update.js +55 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/context.d.ts +26 -0
- package/dist/cli/context.d.ts.map +1 -0
- package/dist/cli/context.js +38 -0
- package/dist/cli/context.js.map +1 -0
- package/dist/cli/envFile.d.ts +23 -0
- package/dist/cli/envFile.d.ts.map +1 -0
- package/dist/cli/envFile.js +79 -0
- package/dist/cli/envFile.js.map +1 -0
- package/dist/cli/exec.d.ts +13 -0
- package/dist/cli/exec.d.ts.map +1 -0
- package/dist/cli/exec.js +47 -0
- package/dist/cli/exec.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +122 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/instances.d.ts +19 -0
- package/dist/cli/instances.d.ts.map +1 -0
- package/dist/cli/instances.js +60 -0
- package/dist/cli/instances.js.map +1 -0
- package/dist/cli/mcpJson.d.ts +15 -0
- package/dist/cli/mcpJson.d.ts.map +1 -0
- package/dist/cli/mcpJson.js +44 -0
- package/dist/cli/mcpJson.js.map +1 -0
- package/dist/cli/settingsPrompt.d.ts +20 -0
- package/dist/cli/settingsPrompt.d.ts.map +1 -0
- package/dist/cli/settingsPrompt.js +150 -0
- package/dist/cli/settingsPrompt.js.map +1 -0
- package/dist/cli/settingsStore.d.ts +47 -0
- package/dist/cli/settingsStore.d.ts.map +1 -0
- package/dist/cli/settingsStore.js +144 -0
- package/dist/cli/settingsStore.js.map +1 -0
- package/dist/cli/target.d.ts +23 -0
- package/dist/cli/target.d.ts.map +1 -0
- package/dist/cli/target.js +62 -0
- package/dist/cli/target.js.map +1 -0
- package/dist/cli/ui.d.ts +26 -0
- package/dist/cli/ui.d.ts.map +1 -0
- package/dist/cli/ui.js +48 -0
- package/dist/cli/ui.js.map +1 -0
- package/dist/cli/xppConfig.d.ts +35 -0
- package/dist/cli/xppConfig.d.ts.map +1 -0
- package/dist/cli/xppConfig.js +97 -0
- package/dist/cli/xppConfig.js.map +1 -0
- package/dist/config/configFile.d.ts +50 -0
- package/dist/config/configFile.d.ts.map +1 -0
- package/dist/config/configFile.js +152 -0
- package/dist/config/configFile.js.map +1 -0
- package/dist/config/settings.d.ts +58 -0
- package/dist/config/settings.d.ts.map +1 -0
- package/dist/config/settings.js +641 -0
- package/dist/config/settings.js.map +1 -0
- package/dist/database/download.d.ts +27 -0
- package/dist/database/download.d.ts.map +1 -0
- package/dist/database/download.js +241 -0
- package/dist/database/download.js.map +1 -0
- package/dist/eval/audit/knowledgeAudit.d.ts +66 -0
- package/dist/eval/audit/knowledgeAudit.d.ts.map +1 -0
- package/dist/eval/audit/knowledgeAudit.js +117 -0
- package/dist/eval/audit/knowledgeAudit.js.map +1 -0
- package/dist/eval/audit/knowledgeAuditCli.d.ts +17 -0
- package/dist/eval/audit/knowledgeAuditCli.d.ts.map +1 -0
- package/dist/eval/audit/knowledgeAuditCli.js +83 -0
- package/dist/eval/audit/knowledgeAuditCli.js.map +1 -0
- package/dist/eval/audit/knowledgeRefs.d.ts +37 -0
- package/dist/eval/audit/knowledgeRefs.d.ts.map +1 -0
- package/dist/eval/audit/knowledgeRefs.js +150 -0
- package/dist/eval/audit/knowledgeRefs.js.map +1 -0
- package/dist/eval/audit/symbolLookup.d.ts +23 -0
- package/dist/eval/audit/symbolLookup.d.ts.map +1 -0
- package/dist/eval/audit/symbolLookup.js +80 -0
- package/dist/eval/audit/symbolLookup.js.map +1 -0
- package/dist/eval/coverage/coverage.d.ts +65 -0
- package/dist/eval/coverage/coverage.d.ts.map +1 -0
- package/dist/eval/coverage/coverage.js +136 -0
- package/dist/eval/coverage/coverage.js.map +1 -0
- package/dist/eval/coverage/coverageCli.d.ts +13 -0
- package/dist/eval/coverage/coverageCli.d.ts.map +1 -0
- package/dist/eval/coverage/coverageCli.js +106 -0
- package/dist/eval/coverage/coverageCli.js.map +1 -0
- package/dist/eval/coverage/sources.d.ts +17 -0
- package/dist/eval/coverage/sources.d.ts.map +1 -0
- package/dist/eval/coverage/sources.js +40 -0
- package/dist/eval/coverage/sources.js.map +1 -0
- package/dist/eval/coverage/taxonomy.d.ts +59 -0
- package/dist/eval/coverage/taxonomy.d.ts.map +1 -0
- package/dist/eval/coverage/taxonomy.js +400 -0
- package/dist/eval/coverage/taxonomy.js.map +1 -0
- package/dist/eval/improver/caseMining.d.ts +55 -0
- package/dist/eval/improver/caseMining.d.ts.map +1 -0
- package/dist/eval/improver/caseMining.js +64 -0
- package/dist/eval/improver/caseMining.js.map +1 -0
- package/dist/eval/improver/caseMiningCli.d.ts +10 -0
- package/dist/eval/improver/caseMiningCli.d.ts.map +1 -0
- package/dist/eval/improver/caseMiningCli.js +50 -0
- package/dist/eval/improver/caseMiningCli.js.map +1 -0
- package/dist/eval/improver/cli.d.ts +11 -0
- package/dist/eval/improver/cli.d.ts.map +1 -0
- package/dist/eval/improver/cli.js +73 -0
- package/dist/eval/improver/cli.js.map +1 -0
- package/dist/eval/improver/cluster.d.ts +47 -0
- package/dist/eval/improver/cluster.d.ts.map +1 -0
- package/dist/eval/improver/cluster.js +0 -0
- package/dist/eval/improver/cluster.js.map +1 -0
- package/dist/eval/improver/corpusIO.d.ts +26 -0
- package/dist/eval/improver/corpusIO.d.ts.map +1 -0
- package/dist/eval/improver/corpusIO.js +50 -0
- package/dist/eval/improver/corpusIO.js.map +1 -0
- package/dist/eval/improver/fixBrief.d.ts +34 -0
- package/dist/eval/improver/fixBrief.d.ts.map +1 -0
- package/dist/eval/improver/fixBrief.js +69 -0
- package/dist/eval/improver/fixBrief.js.map +1 -0
- package/dist/eval/improver/fixBriefCli.d.ts +11 -0
- package/dist/eval/improver/fixBriefCli.d.ts.map +1 -0
- package/dist/eval/improver/fixBriefCli.js +46 -0
- package/dist/eval/improver/fixBriefCli.js.map +1 -0
- package/dist/eval/improver/flakeDetection.d.ts +50 -0
- package/dist/eval/improver/flakeDetection.d.ts.map +1 -0
- package/dist/eval/improver/flakeDetection.js +0 -0
- package/dist/eval/improver/flakeDetection.js.map +1 -0
- package/dist/eval/improver/flakeDetectionCli.d.ts +8 -0
- package/dist/eval/improver/flakeDetectionCli.d.ts.map +1 -0
- package/dist/eval/improver/flakeDetectionCli.js +27 -0
- package/dist/eval/improver/flakeDetectionCli.js.map +1 -0
- package/dist/eval/improver/heldout.d.ts +44 -0
- package/dist/eval/improver/heldout.d.ts.map +1 -0
- package/dist/eval/improver/heldout.js +52 -0
- package/dist/eval/improver/heldout.js.map +1 -0
- package/dist/eval/improver/knowledgeFeedback.d.ts +56 -0
- package/dist/eval/improver/knowledgeFeedback.d.ts.map +1 -0
- package/dist/eval/improver/knowledgeFeedback.js +88 -0
- package/dist/eval/improver/knowledgeFeedback.js.map +1 -0
- package/dist/eval/improver/knowledgeFeedbackCli.d.ts +8 -0
- package/dist/eval/improver/knowledgeFeedbackCli.d.ts.map +1 -0
- package/dist/eval/improver/knowledgeFeedbackCli.js +28 -0
- package/dist/eval/improver/knowledgeFeedbackCli.js.map +1 -0
- package/dist/eval/improver/report.d.ts +36 -0
- package/dist/eval/improver/report.d.ts.map +1 -0
- package/dist/eval/improver/report.js +61 -0
- package/dist/eval/improver/report.js.map +1 -0
- package/dist/eval/improver/reportCli.d.ts +7 -0
- package/dist/eval/improver/reportCli.d.ts.map +1 -0
- package/dist/eval/improver/reportCli.js +27 -0
- package/dist/eval/improver/reportCli.js.map +1 -0
- package/dist/eval/oracle/actualArtifactResolution.d.ts +49 -0
- package/dist/eval/oracle/actualArtifactResolution.d.ts.map +1 -0
- package/dist/eval/oracle/actualArtifactResolution.js +73 -0
- package/dist/eval/oracle/actualArtifactResolution.js.map +1 -0
- package/dist/eval/oracle/cli.d.ts +30 -0
- package/dist/eval/oracle/cli.d.ts.map +1 -0
- package/dist/eval/oracle/cli.js +179 -0
- package/dist/eval/oracle/cli.js.map +1 -0
- package/dist/eval/oracle/diff.d.ts +26 -0
- package/dist/eval/oracle/diff.d.ts.map +1 -0
- package/dist/eval/oracle/diff.js +51 -0
- package/dist/eval/oracle/diff.js.map +1 -0
- package/dist/eval/oracle/index.d.ts +81 -0
- package/dist/eval/oracle/index.d.ts.map +1 -0
- package/dist/eval/oracle/index.js +55 -0
- package/dist/eval/oracle/index.js.map +1 -0
- package/dist/eval/oracle/normalize.d.ts +85 -0
- package/dist/eval/oracle/normalize.d.ts.map +1 -0
- package/dist/eval/oracle/normalize.js +321 -0
- package/dist/eval/oracle/normalize.js.map +1 -0
- package/dist/eval/oracle/score.d.ts +26 -0
- package/dist/eval/oracle/score.d.ts.map +1 -0
- package/dist/eval/oracle/score.js +15 -0
- package/dist/eval/oracle/score.js.map +1 -0
- package/dist/eval/oracle/systest.d.ts +30 -0
- package/dist/eval/oracle/systest.d.ts.map +1 -0
- package/dist/eval/oracle/systest.js +98 -0
- package/dist/eval/oracle/systest.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +753 -0
- package/dist/index.js.map +1 -0
- package/dist/knowledge/formPatterns/catalog/subPatterns/customFilters.d.ts +10 -0
- package/dist/knowledge/formPatterns/catalog/subPatterns/customFilters.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/catalog/subPatterns/customFilters.js +38 -0
- package/dist/knowledge/formPatterns/catalog/subPatterns/customFilters.js.map +1 -0
- package/dist/knowledge/formPatterns/catalog/subPatterns/fields.d.ts +21 -0
- package/dist/knowledge/formPatterns/catalog/subPatterns/fields.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/catalog/subPatterns/fields.js +168 -0
- package/dist/knowledge/formPatterns/catalog/subPatterns/fields.js.map +1 -0
- package/dist/knowledge/formPatterns/catalog/subPatterns/panels.d.ts +9 -0
- package/dist/knowledge/formPatterns/catalog/subPatterns/panels.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/catalog/subPatterns/panels.js +47 -0
- package/dist/knowledge/formPatterns/catalog/subPatterns/panels.js.map +1 -0
- package/dist/knowledge/formPatterns/catalog/subPatterns/toolbar.d.ts +16 -0
- package/dist/knowledge/formPatterns/catalog/subPatterns/toolbar.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/catalog/subPatterns/toolbar.js +124 -0
- package/dist/knowledge/formPatterns/catalog/subPatterns/toolbar.js.map +1 -0
- package/dist/knowledge/formPatterns/catalog/subPatterns/workspaceSections.d.ts +12 -0
- package/dist/knowledge/formPatterns/catalog/subPatterns/workspaceSections.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/catalog/subPatterns/workspaceSections.js +36 -0
- package/dist/knowledge/formPatterns/catalog/subPatterns/workspaceSections.js.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/common.d.ts +11 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/common.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/common.js +37 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/common.js.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/detailsMaster.d.ts +8 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/detailsMaster.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/detailsMaster.js +86 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/detailsMaster.js.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/detailsTransaction.d.ts +7 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/detailsTransaction.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/detailsTransaction.js +69 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/detailsTransaction.js.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/dialog.d.ts +14 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/dialog.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/dialog.js +187 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/dialog.js.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/factBox.d.ts +10 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/factBox.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/factBox.js +54 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/factBox.js.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/listPage.d.ts +7 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/listPage.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/listPage.js +33 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/listPage.js.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/lookup.d.ts +10 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/lookup.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/lookup.js +95 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/lookup.js.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/simpleDetails.d.ts +16 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/simpleDetails.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/simpleDetails.js +158 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/simpleDetails.js.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/simpleList.d.ts +7 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/simpleList.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/simpleList.js +34 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/simpleList.js.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/simpleListDetails.d.ts +9 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/simpleListDetails.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/simpleListDetails.js +99 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/simpleListDetails.js.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/tableOfContents.d.ts +8 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/tableOfContents.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/tableOfContents.js +95 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/tableOfContents.js.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/task.d.ts +9 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/task.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/task.js +42 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/task.js.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/wizard.d.ts +7 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/wizard.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/wizard.js +42 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/wizard.js.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/workspace.d.ts +17 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/workspace.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/workspace.js +157 -0
- package/dist/knowledge/formPatterns/catalog/topLevel/workspace.js.map +1 -0
- package/dist/knowledge/formPatterns/crossCheck.d.ts +44 -0
- package/dist/knowledge/formPatterns/crossCheck.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/crossCheck.js +109 -0
- package/dist/knowledge/formPatterns/crossCheck.js.map +1 -0
- package/dist/knowledge/formPatterns/index.d.ts +30 -0
- package/dist/knowledge/formPatterns/index.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/index.js +158 -0
- package/dist/knowledge/formPatterns/index.js.map +1 -0
- package/dist/knowledge/formPatterns/methodStubs.d.ts +45 -0
- package/dist/knowledge/formPatterns/methodStubs.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/methodStubs.js +257 -0
- package/dist/knowledge/formPatterns/methodStubs.js.map +1 -0
- package/dist/knowledge/formPatterns/types.d.ts +115 -0
- package/dist/knowledge/formPatterns/types.d.ts.map +1 -0
- package/dist/knowledge/formPatterns/types.js +44 -0
- package/dist/knowledge/formPatterns/types.js.map +1 -0
- package/dist/metadata/enhancedParser.d.ts +91 -0
- package/dist/metadata/enhancedParser.d.ts.map +1 -0
- package/dist/metadata/enhancedParser.js +379 -0
- package/dist/metadata/enhancedParser.js.map +1 -0
- package/dist/metadata/formPatternMiner.d.ts +78 -0
- package/dist/metadata/formPatternMiner.d.ts.map +1 -0
- package/dist/metadata/formPatternMiner.js +220 -0
- package/dist/metadata/formPatternMiner.js.map +1 -0
- package/dist/metadata/labelParser.d.ts +71 -0
- package/dist/metadata/labelParser.d.ts.map +1 -0
- package/dist/metadata/labelParser.js +258 -0
- package/dist/metadata/labelParser.js.map +1 -0
- package/dist/metadata/symbolCountsWorker.d.ts +16 -0
- package/dist/metadata/symbolCountsWorker.d.ts.map +1 -0
- package/dist/metadata/symbolCountsWorker.js +42 -0
- package/dist/metadata/symbolCountsWorker.js.map +1 -0
- package/dist/metadata/symbolIndex.d.ts +474 -0
- package/dist/metadata/symbolIndex.d.ts.map +1 -0
- package/dist/metadata/symbolIndex.js +3152 -0
- package/dist/metadata/symbolIndex.js.map +1 -0
- package/dist/metadata/types.d.ts +267 -0
- package/dist/metadata/types.d.ts.map +1 -0
- package/dist/metadata/types.js +5 -0
- package/dist/metadata/types.js.map +1 -0
- package/dist/metadata/xmlParser.d.ts +232 -0
- package/dist/metadata/xmlParser.d.ts.map +1 -0
- package/dist/metadata/xmlParser.js +1021 -0
- package/dist/metadata/xmlParser.js.map +1 -0
- package/dist/metadata/xppDeclaration.d.ts +116 -0
- package/dist/metadata/xppDeclaration.d.ts.map +1 -0
- package/dist/metadata/xppDeclaration.js +350 -0
- package/dist/metadata/xppDeclaration.js.map +1 -0
- package/dist/middleware/apiKeyAuth.d.ts +7 -0
- package/dist/middleware/apiKeyAuth.d.ts.map +1 -0
- package/dist/middleware/apiKeyAuth.js +70 -0
- package/dist/middleware/apiKeyAuth.js.map +1 -0
- package/dist/middleware/rateLimiter.d.ts +7 -0
- package/dist/middleware/rateLimiter.d.ts.map +1 -0
- package/dist/middleware/rateLimiter.js +78 -0
- package/dist/middleware/rateLimiter.js.map +1 -0
- package/dist/prompts/codeReview.d.ts +8 -0
- package/dist/prompts/codeReview.d.ts.map +1 -0
- package/dist/prompts/codeReview.js +619 -0
- package/dist/prompts/codeReview.js.map +1 -0
- package/dist/prompts/index.d.ts +6 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +6 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/systemInstructions.d.ts +33 -0
- package/dist/prompts/systemInstructions.d.ts.map +1 -0
- package/dist/prompts/systemInstructions.js +154 -0
- package/dist/prompts/systemInstructions.js.map +1 -0
- package/dist/resources/classResource.d.ts +17 -0
- package/dist/resources/classResource.d.ts.map +1 -0
- package/dist/resources/classResource.js +33 -0
- package/dist/resources/classResource.js.map +1 -0
- package/dist/resources/index.d.ts +20 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +154 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/server/mcpServer.d.ts +11 -0
- package/dist/server/mcpServer.d.ts.map +1 -0
- package/dist/server/mcpServer.js +185 -0
- package/dist/server/mcpServer.js.map +1 -0
- package/dist/server/serverMode.d.ts +53 -0
- package/dist/server/serverMode.d.ts.map +1 -0
- package/dist/server/serverMode.js +72 -0
- package/dist/server/serverMode.js.map +1 -0
- package/dist/server/toolAnnotations.d.ts +28 -0
- package/dist/server/toolAnnotations.d.ts.map +1 -0
- package/dist/server/toolAnnotations.js +70 -0
- package/dist/server/toolAnnotations.js.map +1 -0
- package/dist/server/toolSchemas/analyzeCode.d.ts +71 -0
- package/dist/server/toolSchemas/analyzeCode.d.ts.map +1 -0
- package/dist/server/toolSchemas/analyzeCode.js +50 -0
- package/dist/server/toolSchemas/analyzeCode.js.map +1 -0
- package/dist/server/toolSchemas/batchGetInfo.d.ts +32 -0
- package/dist/server/toolSchemas/batchGetInfo.d.ts.map +1 -0
- package/dist/server/toolSchemas/batchGetInfo.js +35 -0
- package/dist/server/toolSchemas/batchGetInfo.js.map +1 -0
- package/dist/server/toolSchemas/buildD365foProject.d.ts +44 -0
- package/dist/server/toolSchemas/buildD365foProject.d.ts.map +1 -0
- package/dist/server/toolSchemas/buildD365foProject.js +47 -0
- package/dist/server/toolSchemas/buildD365foProject.js.map +1 -0
- package/dist/server/toolSchemas/d365foFile.d.ts +99 -0
- package/dist/server/toolSchemas/d365foFile.d.ts.map +1 -0
- package/dist/server/toolSchemas/d365foFile.js +163 -0
- package/dist/server/toolSchemas/d365foFile.js.map +1 -0
- package/dist/server/toolSchemas/extensionInfo.d.ts +65 -0
- package/dist/server/toolSchemas/extensionInfo.d.ts.map +1 -0
- package/dist/server/toolSchemas/extensionInfo.js +73 -0
- package/dist/server/toolSchemas/extensionInfo.js.map +1 -0
- package/dist/server/toolSchemas/findReferences.d.ts +35 -0
- package/dist/server/toolSchemas/findReferences.d.ts.map +1 -0
- package/dist/server/toolSchemas/findReferences.js +35 -0
- package/dist/server/toolSchemas/findReferences.js.map +1 -0
- package/dist/server/toolSchemas/generateObject.d.ts +246 -0
- package/dist/server/toolSchemas/generateObject.d.ts.map +1 -0
- package/dist/server/toolSchemas/generateObject.js +158 -0
- package/dist/server/toolSchemas/generateObject.js.map +1 -0
- package/dist/server/toolSchemas/getKnowledge.d.ts +39 -0
- package/dist/server/toolSchemas/getKnowledge.d.ts.map +1 -0
- package/dist/server/toolSchemas/getKnowledge.js +46 -0
- package/dist/server/toolSchemas/getKnowledge.js.map +1 -0
- package/dist/server/toolSchemas/getMethod.d.ts +30 -0
- package/dist/server/toolSchemas/getMethod.d.ts.map +1 -0
- package/dist/server/toolSchemas/getMethod.js +34 -0
- package/dist/server/toolSchemas/getMethod.js.map +1 -0
- package/dist/server/toolSchemas/getObjectInfo.d.ts +24 -0
- package/dist/server/toolSchemas/getObjectInfo.d.ts.map +1 -0
- package/dist/server/toolSchemas/getObjectInfo.js +30 -0
- package/dist/server/toolSchemas/getObjectInfo.js.map +1 -0
- package/dist/server/toolSchemas/getWorkspaceInfo.d.ts +29 -0
- package/dist/server/toolSchemas/getWorkspaceInfo.d.ts.map +1 -0
- package/dist/server/toolSchemas/getWorkspaceInfo.js +29 -0
- package/dist/server/toolSchemas/getWorkspaceInfo.js.map +1 -0
- package/dist/server/toolSchemas/index.d.ts +1142 -0
- package/dist/server/toolSchemas/index.d.ts.map +1 -0
- package/dist/server/toolSchemas/index.js +60 -0
- package/dist/server/toolSchemas/index.js.map +1 -0
- package/dist/server/toolSchemas/labels.d.ts +172 -0
- package/dist/server/toolSchemas/labels.d.ts.map +1 -0
- package/dist/server/toolSchemas/labels.js +159 -0
- package/dist/server/toolSchemas/labels.js.map +1 -0
- package/dist/server/toolSchemas/objectPatterns.d.ts +93 -0
- package/dist/server/toolSchemas/objectPatterns.d.ts.map +1 -0
- package/dist/server/toolSchemas/objectPatterns.js +104 -0
- package/dist/server/toolSchemas/objectPatterns.js.map +1 -0
- package/dist/server/toolSchemas/prepare.d.ts +49 -0
- package/dist/server/toolSchemas/prepare.d.ts.map +1 -0
- package/dist/server/toolSchemas/prepare.js +57 -0
- package/dist/server/toolSchemas/prepare.js.map +1 -0
- package/dist/server/toolSchemas/reviewWorkspaceChanges.d.ts +20 -0
- package/dist/server/toolSchemas/reviewWorkspaceChanges.d.ts.map +1 -0
- package/dist/server/toolSchemas/reviewWorkspaceChanges.js +19 -0
- package/dist/server/toolSchemas/reviewWorkspaceChanges.js.map +1 -0
- package/dist/server/toolSchemas/runBpCheck.d.ts +36 -0
- package/dist/server/toolSchemas/runBpCheck.d.ts.map +1 -0
- package/dist/server/toolSchemas/runBpCheck.js +21 -0
- package/dist/server/toolSchemas/runBpCheck.js.map +1 -0
- package/dist/server/toolSchemas/runSystestClass.d.ts +32 -0
- package/dist/server/toolSchemas/runSystestClass.d.ts.map +1 -0
- package/dist/server/toolSchemas/runSystestClass.js +20 -0
- package/dist/server/toolSchemas/runSystestClass.js.map +1 -0
- package/dist/server/toolSchemas/search.d.ts +109 -0
- package/dist/server/toolSchemas/search.d.ts.map +1 -0
- package/dist/server/toolSchemas/search.js +123 -0
- package/dist/server/toolSchemas/search.js.map +1 -0
- package/dist/server/toolSchemas/securityInfo.d.ts +45 -0
- package/dist/server/toolSchemas/securityInfo.d.ts.map +1 -0
- package/dist/server/toolSchemas/securityInfo.js +39 -0
- package/dist/server/toolSchemas/securityInfo.js.map +1 -0
- package/dist/server/toolSchemas/suggestEdt.d.ts +29 -0
- package/dist/server/toolSchemas/suggestEdt.d.ts.map +1 -0
- package/dist/server/toolSchemas/suggestEdt.js +29 -0
- package/dist/server/toolSchemas/suggestEdt.js.map +1 -0
- package/dist/server/toolSchemas/triggerDbSync.d.ts +47 -0
- package/dist/server/toolSchemas/triggerDbSync.d.ts.map +1 -0
- package/dist/server/toolSchemas/triggerDbSync.js +31 -0
- package/dist/server/toolSchemas/triggerDbSync.js.map +1 -0
- package/dist/server/toolSchemas/undoLastModification.d.ts +20 -0
- package/dist/server/toolSchemas/undoLastModification.d.ts.map +1 -0
- package/dist/server/toolSchemas/undoLastModification.js +17 -0
- package/dist/server/toolSchemas/undoLastModification.js.map +1 -0
- package/dist/server/toolSchemas/updateSymbolIndex.d.ts +19 -0
- package/dist/server/toolSchemas/updateSymbolIndex.d.ts.map +1 -0
- package/dist/server/toolSchemas/updateSymbolIndex.js +18 -0
- package/dist/server/toolSchemas/updateSymbolIndex.js.map +1 -0
- package/dist/server/toolSchemas/validateCode.d.ts +35 -0
- package/dist/server/toolSchemas/validateCode.d.ts.map +1 -0
- package/dist/server/toolSchemas/validateCode.js +38 -0
- package/dist/server/toolSchemas/validateCode.js.map +1 -0
- package/dist/server/toolSchemas/validateObjectNaming.d.ts +33 -0
- package/dist/server/toolSchemas/validateObjectNaming.d.ts.map +1 -0
- package/dist/server/toolSchemas/validateObjectNaming.js +32 -0
- package/dist/server/toolSchemas/validateObjectNaming.js.map +1 -0
- package/dist/server/toolSchemas/verifyD365foProject.d.ts +50 -0
- package/dist/server/toolSchemas/verifyD365foProject.d.ts.map +1 -0
- package/dist/server/toolSchemas/verifyD365foProject.js +46 -0
- package/dist/server/toolSchemas/verifyD365foProject.js.map +1 -0
- package/dist/server/transport.d.ts +30 -0
- package/dist/server/transport.d.ts.map +1 -0
- package/dist/server/transport.js +391 -0
- package/dist/server/transport.js.map +1 -0
- package/dist/tools/analyzeCode.d.ts +17 -0
- package/dist/tools/analyzeCode.d.ts.map +1 -0
- package/dist/tools/analyzeCode.js +63 -0
- package/dist/tools/analyzeCode.js.map +1 -0
- package/dist/tools/analyzeCompleteness.d.ts +20 -0
- package/dist/tools/analyzeCompleteness.d.ts.map +1 -0
- package/dist/tools/analyzeCompleteness.js +103 -0
- package/dist/tools/analyzeCompleteness.js.map +1 -0
- package/dist/tools/analyzeExtensionPoints.d.ts +21 -0
- package/dist/tools/analyzeExtensionPoints.d.ts.map +1 -0
- package/dist/tools/analyzeExtensionPoints.js +343 -0
- package/dist/tools/analyzeExtensionPoints.js.map +1 -0
- package/dist/tools/analyzePatterns.d.ts +20 -0
- package/dist/tools/analyzePatterns.d.ts.map +1 -0
- package/dist/tools/analyzePatterns.js +71 -0
- package/dist/tools/analyzePatterns.js.map +1 -0
- package/dist/tools/apiUsagePatterns.d.ts +20 -0
- package/dist/tools/apiUsagePatterns.d.ts.map +1 -0
- package/dist/tools/apiUsagePatterns.js +136 -0
- package/dist/tools/apiUsagePatterns.js.map +1 -0
- package/dist/tools/batchGetInfo.d.ts +50 -0
- package/dist/tools/batchGetInfo.d.ts.map +1 -0
- package/dist/tools/batchGetInfo.js +52 -0
- package/dist/tools/batchGetInfo.js.map +1 -0
- package/dist/tools/batchSearch.d.ts +64 -0
- package/dist/tools/batchSearch.d.ts.map +1 -0
- package/dist/tools/batchSearch.js +265 -0
- package/dist/tools/batchSearch.js.map +1 -0
- package/dist/tools/buildProject.d.ts +28 -0
- package/dist/tools/buildProject.d.ts.map +1 -0
- package/dist/tools/buildProject.js +929 -0
- package/dist/tools/buildProject.js.map +1 -0
- package/dist/tools/classInfo.d.ts +8 -0
- package/dist/tools/classInfo.d.ts.map +1 -0
- package/dist/tools/classInfo.js +235 -0
- package/dist/tools/classInfo.js.map +1 -0
- package/dist/tools/codeGen.d.ts +19 -0
- package/dist/tools/codeGen.d.ts.map +1 -0
- package/dist/tools/codeGen.js +1956 -0
- package/dist/tools/codeGen.js.map +1 -0
- package/dist/tools/completion.d.ts +8 -0
- package/dist/tools/completion.d.ts.map +1 -0
- package/dist/tools/completion.js +272 -0
- package/dist/tools/completion.js.map +1 -0
- package/dist/tools/configKeyInfo.d.ts +22 -0
- package/dist/tools/configKeyInfo.d.ts.map +1 -0
- package/dist/tools/configKeyInfo.js +74 -0
- package/dist/tools/configKeyInfo.js.map +1 -0
- package/dist/tools/createD365File.d.ts +479 -0
- package/dist/tools/createD365File.d.ts.map +1 -0
- package/dist/tools/createD365File.js +4185 -0
- package/dist/tools/createD365File.js.map +1 -0
- package/dist/tools/createLabel.d.ts +51 -0
- package/dist/tools/createLabel.d.ts.map +1 -0
- package/dist/tools/createLabel.js +761 -0
- package/dist/tools/createLabel.js.map +1 -0
- package/dist/tools/d365foErrorHelp.d.ts +29 -0
- package/dist/tools/d365foErrorHelp.d.ts.map +1 -0
- package/dist/tools/d365foErrorHelp.js +389 -0
- package/dist/tools/d365foErrorHelp.js.map +1 -0
- package/dist/tools/d365foFile.d.ts +20 -0
- package/dist/tools/d365foFile.d.ts.map +1 -0
- package/dist/tools/d365foFile.js +58 -0
- package/dist/tools/d365foFile.js.map +1 -0
- package/dist/tools/d365foFileOpSpecs.d.ts +41 -0
- package/dist/tools/d365foFileOpSpecs.d.ts.map +1 -0
- package/dist/tools/d365foFileOpSpecs.js +336 -0
- package/dist/tools/d365foFileOpSpecs.js.map +1 -0
- package/dist/tools/dataEntityInfo.d.ts +23 -0
- package/dist/tools/dataEntityInfo.d.ts.map +1 -0
- package/dist/tools/dataEntityInfo.js +45 -0
- package/dist/tools/dataEntityInfo.js.map +1 -0
- package/dist/tools/dataEntityXml.d.ts +31 -0
- package/dist/tools/dataEntityXml.d.ts.map +1 -0
- package/dist/tools/dataEntityXml.js +131 -0
- package/dist/tools/dataEntityXml.js.map +1 -0
- package/dist/tools/dbSync.d.ts +8 -0
- package/dist/tools/dbSync.d.ts.map +1 -0
- package/dist/tools/dbSync.js +285 -0
- package/dist/tools/dbSync.js.map +1 -0
- package/dist/tools/edtInfo.d.ts +23 -0
- package/dist/tools/edtInfo.d.ts.map +1 -0
- package/dist/tools/edtInfo.js +122 -0
- package/dist/tools/edtInfo.js.map +1 -0
- package/dist/tools/enumInfo.d.ts +17 -0
- package/dist/tools/enumInfo.d.ts.map +1 -0
- package/dist/tools/enumInfo.js +44 -0
- package/dist/tools/enumInfo.js.map +1 -0
- package/dist/tools/extensionInfo.d.ts +26 -0
- package/dist/tools/extensionInfo.d.ts.map +1 -0
- package/dist/tools/extensionInfo.js +73 -0
- package/dist/tools/extensionInfo.js.map +1 -0
- package/dist/tools/extensionSearch.d.ts +20 -0
- package/dist/tools/extensionSearch.d.ts.map +1 -0
- package/dist/tools/extensionSearch.js +72 -0
- package/dist/tools/extensionSearch.js.map +1 -0
- package/dist/tools/extensionStrategyAdvisor.d.ts +15 -0
- package/dist/tools/extensionStrategyAdvisor.d.ts.map +1 -0
- package/dist/tools/extensionStrategyAdvisor.js +519 -0
- package/dist/tools/extensionStrategyAdvisor.js.map +1 -0
- package/dist/tools/findCocExtensions.d.ts +20 -0
- package/dist/tools/findCocExtensions.d.ts.map +1 -0
- package/dist/tools/findCocExtensions.js +285 -0
- package/dist/tools/findCocExtensions.js.map +1 -0
- package/dist/tools/findEventHandlers.d.ts +21 -0
- package/dist/tools/findEventHandlers.d.ts.map +1 -0
- package/dist/tools/findEventHandlers.js +196 -0
- package/dist/tools/findEventHandlers.js.map +1 -0
- package/dist/tools/findReferences.d.ts +30 -0
- package/dist/tools/findReferences.d.ts.map +1 -0
- package/dist/tools/findReferences.js +551 -0
- package/dist/tools/findReferences.js.map +1 -0
- package/dist/tools/formInfo.d.ts +13 -0
- package/dist/tools/formInfo.d.ts.map +1 -0
- package/dist/tools/formInfo.js +407 -0
- package/dist/tools/formInfo.js.map +1 -0
- package/dist/tools/formPattern.d.ts +19 -0
- package/dist/tools/formPattern.d.ts.map +1 -0
- package/dist/tools/formPattern.js +52 -0
- package/dist/tools/formPattern.js.map +1 -0
- package/dist/tools/generateD365Xml.d.ts +12 -0
- package/dist/tools/generateD365Xml.d.ts.map +1 -0
- package/dist/tools/generateD365Xml.js +1454 -0
- package/dist/tools/generateD365Xml.js.map +1 -0
- package/dist/tools/generateFindMethods.d.ts +69 -0
- package/dist/tools/generateFindMethods.d.ts.map +1 -0
- package/dist/tools/generateFindMethods.js +207 -0
- package/dist/tools/generateFindMethods.js.map +1 -0
- package/dist/tools/generateMetadata.d.ts +37 -0
- package/dist/tools/generateMetadata.d.ts.map +1 -0
- package/dist/tools/generateMetadata.js +213 -0
- package/dist/tools/generateMetadata.js.map +1 -0
- package/dist/tools/generateObject.d.ts +34 -0
- package/dist/tools/generateObject.d.ts.map +1 -0
- package/dist/tools/generateObject.js +47 -0
- package/dist/tools/generateObject.js.map +1 -0
- package/dist/tools/generateRelationXpp.d.ts +45 -0
- package/dist/tools/generateRelationXpp.d.ts.map +1 -0
- package/dist/tools/generateRelationXpp.js +129 -0
- package/dist/tools/generateRelationXpp.js.map +1 -0
- package/dist/tools/generateSmart.d.ts +32 -0
- package/dist/tools/generateSmart.d.ts.map +1 -0
- package/dist/tools/generateSmart.js +52 -0
- package/dist/tools/generateSmart.js.map +1 -0
- package/dist/tools/generateSmartForm.d.ts +82 -0
- package/dist/tools/generateSmartForm.d.ts.map +1 -0
- package/dist/tools/generateSmartForm.js +996 -0
- package/dist/tools/generateSmartForm.js.map +1 -0
- package/dist/tools/generateSmartReport.d.ts +90 -0
- package/dist/tools/generateSmartReport.d.ts.map +1 -0
- package/dist/tools/generateSmartReport.js +1254 -0
- package/dist/tools/generateSmartReport.js.map +1 -0
- package/dist/tools/generateSmartTable.d.ts +138 -0
- package/dist/tools/generateSmartTable.d.ts.map +1 -0
- package/dist/tools/generateSmartTable.js +1305 -0
- package/dist/tools/generateSmartTable.js.map +1 -0
- package/dist/tools/generateTableFields.d.ts +48 -0
- package/dist/tools/generateTableFields.d.ts.map +1 -0
- package/dist/tools/generateTableFields.js +186 -0
- package/dist/tools/generateTableFields.js.map +1 -0
- package/dist/tools/generateTableRelation.d.ts +35 -0
- package/dist/tools/generateTableRelation.d.ts.map +1 -0
- package/dist/tools/generateTableRelation.js +161 -0
- package/dist/tools/generateTableRelation.js.map +1 -0
- package/dist/tools/getFormPatternSpec.d.ts +13 -0
- package/dist/tools/getFormPatternSpec.d.ts.map +1 -0
- package/dist/tools/getFormPatternSpec.js +290 -0
- package/dist/tools/getFormPatternSpec.js.map +1 -0
- package/dist/tools/getFormPatterns.d.ts +68 -0
- package/dist/tools/getFormPatterns.d.ts.map +1 -0
- package/dist/tools/getFormPatterns.js +471 -0
- package/dist/tools/getFormPatterns.js.map +1 -0
- package/dist/tools/getKnowledge.d.ts +27 -0
- package/dist/tools/getKnowledge.d.ts.map +1 -0
- package/dist/tools/getKnowledge.js +50 -0
- package/dist/tools/getKnowledge.js.map +1 -0
- package/dist/tools/getLabelInfo.d.ts +21 -0
- package/dist/tools/getLabelInfo.d.ts.map +1 -0
- package/dist/tools/getLabelInfo.js +138 -0
- package/dist/tools/getLabelInfo.js.map +1 -0
- package/dist/tools/getMethod.d.ts +19 -0
- package/dist/tools/getMethod.d.ts.map +1 -0
- package/dist/tools/getMethod.js +77 -0
- package/dist/tools/getMethod.js.map +1 -0
- package/dist/tools/getMethodSource.d.ts +17 -0
- package/dist/tools/getMethodSource.d.ts.map +1 -0
- package/dist/tools/getMethodSource.js +161 -0
- package/dist/tools/getMethodSource.js.map +1 -0
- package/dist/tools/getObjectInfo.d.ts +17 -0
- package/dist/tools/getObjectInfo.d.ts.map +1 -0
- package/dist/tools/getObjectInfo.js +88 -0
- package/dist/tools/getObjectInfo.js.map +1 -0
- package/dist/tools/getTablePatterns.d.ts +45 -0
- package/dist/tools/getTablePatterns.d.ts.map +1 -0
- package/dist/tools/getTablePatterns.js +235 -0
- package/dist/tools/getTablePatterns.js.map +1 -0
- package/dist/tools/index.d.ts +11 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +11 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/labels.d.ts +25 -0
- package/dist/tools/labels.d.ts.map +1 -0
- package/dist/tools/labels.js +111 -0
- package/dist/tools/labels.js.map +1 -0
- package/dist/tools/macroInfo.d.ts +23 -0
- package/dist/tools/macroInfo.d.ts.map +1 -0
- package/dist/tools/macroInfo.js +62 -0
- package/dist/tools/macroInfo.js.map +1 -0
- package/dist/tools/mapInfo.d.ts +21 -0
- package/dist/tools/mapInfo.d.ts.map +1 -0
- package/dist/tools/mapInfo.js +54 -0
- package/dist/tools/mapInfo.js.map +1 -0
- package/dist/tools/mapXml.d.ts +26 -0
- package/dist/tools/mapXml.d.ts.map +1 -0
- package/dist/tools/mapXml.js +88 -0
- package/dist/tools/mapXml.js.map +1 -0
- package/dist/tools/menuItemInfo.d.ts +20 -0
- package/dist/tools/menuItemInfo.d.ts.map +1 -0
- package/dist/tools/menuItemInfo.js +185 -0
- package/dist/tools/menuItemInfo.js.map +1 -0
- package/dist/tools/methodSignature.d.ts +33 -0
- package/dist/tools/methodSignature.d.ts.map +1 -0
- package/dist/tools/methodSignature.js +348 -0
- package/dist/tools/methodSignature.js.map +1 -0
- package/dist/tools/modifyD365File.d.ts +130 -0
- package/dist/tools/modifyD365File.d.ts.map +1 -0
- package/dist/tools/modifyD365File.js +2179 -0
- package/dist/tools/modifyD365File.js.map +1 -0
- package/dist/tools/objectInfoRegistry.d.ts +36 -0
- package/dist/tools/objectInfoRegistry.d.ts.map +1 -0
- package/dist/tools/objectInfoRegistry.js +98 -0
- package/dist/tools/objectInfoRegistry.js.map +1 -0
- package/dist/tools/objectPatterns.d.ts +16 -0
- package/dist/tools/objectPatterns.d.ts.map +1 -0
- package/dist/tools/objectPatterns.js +84 -0
- package/dist/tools/objectPatterns.js.map +1 -0
- package/dist/tools/prepare.d.ts +18 -0
- package/dist/tools/prepare.d.ts.map +1 -0
- package/dist/tools/prepare.js +47 -0
- package/dist/tools/prepare.js.map +1 -0
- package/dist/tools/prepareChange.d.ts +43 -0
- package/dist/tools/prepareChange.d.ts.map +1 -0
- package/dist/tools/prepareChange.js +327 -0
- package/dist/tools/prepareChange.js.map +1 -0
- package/dist/tools/prepareCreate.d.ts +45 -0
- package/dist/tools/prepareCreate.d.ts.map +1 -0
- package/dist/tools/prepareCreate.js +263 -0
- package/dist/tools/prepareCreate.js.map +1 -0
- package/dist/tools/queryInfo.d.ts +17 -0
- package/dist/tools/queryInfo.d.ts.map +1 -0
- package/dist/tools/queryInfo.js +46 -0
- package/dist/tools/queryInfo.js.map +1 -0
- package/dist/tools/queryViewXml.d.ts +36 -0
- package/dist/tools/queryViewXml.d.ts.map +1 -0
- package/dist/tools/queryViewXml.js +129 -0
- package/dist/tools/queryViewXml.js.map +1 -0
- package/dist/tools/renameLabel.d.ts +29 -0
- package/dist/tools/renameLabel.d.ts.map +1 -0
- package/dist/tools/renameLabel.js +377 -0
- package/dist/tools/renameLabel.js.map +1 -0
- package/dist/tools/repairFormControls.d.ts +21 -0
- package/dist/tools/repairFormControls.d.ts.map +1 -0
- package/dist/tools/repairFormControls.js +151 -0
- package/dist/tools/repairFormControls.js.map +1 -0
- package/dist/tools/reportInfo.d.ts +14 -0
- package/dist/tools/reportInfo.d.ts.map +1 -0
- package/dist/tools/reportInfo.js +302 -0
- package/dist/tools/reportInfo.js.map +1 -0
- package/dist/tools/resolveReferences.d.ts +89 -0
- package/dist/tools/resolveReferences.d.ts.map +1 -0
- package/dist/tools/resolveReferences.js +791 -0
- package/dist/tools/resolveReferences.js.map +1 -0
- package/dist/tools/reviewWorkspaceChanges.d.ts +14 -0
- package/dist/tools/reviewWorkspaceChanges.d.ts.map +1 -0
- package/dist/tools/reviewWorkspaceChanges.js +73 -0
- package/dist/tools/reviewWorkspaceChanges.js.map +1 -0
- package/dist/tools/runBpCheck.d.ts +14 -0
- package/dist/tools/runBpCheck.d.ts.map +1 -0
- package/dist/tools/runBpCheck.js +241 -0
- package/dist/tools/runBpCheck.js.map +1 -0
- package/dist/tools/search.d.ts +20 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +246 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/searchLabels.d.ts +26 -0
- package/dist/tools/searchLabels.d.ts.map +1 -0
- package/dist/tools/searchLabels.js +91 -0
- package/dist/tools/searchLabels.js.map +1 -0
- package/dist/tools/searchUnified.d.ts +28 -0
- package/dist/tools/searchUnified.d.ts.map +1 -0
- package/dist/tools/searchUnified.js +48 -0
- package/dist/tools/searchUnified.js.map +1 -0
- package/dist/tools/securityArtifactInfo.d.ts +14 -0
- package/dist/tools/securityArtifactInfo.d.ts.map +1 -0
- package/dist/tools/securityArtifactInfo.js +192 -0
- package/dist/tools/securityArtifactInfo.js.map +1 -0
- package/dist/tools/securityCoverageInfo.d.ts +21 -0
- package/dist/tools/securityCoverageInfo.d.ts.map +1 -0
- package/dist/tools/securityCoverageInfo.js +248 -0
- package/dist/tools/securityCoverageInfo.js.map +1 -0
- package/dist/tools/securityInfo.d.ts +22 -0
- package/dist/tools/securityInfo.d.ts.map +1 -0
- package/dist/tools/securityInfo.js +43 -0
- package/dist/tools/securityInfo.js.map +1 -0
- package/dist/tools/securityPolicyInfo.d.ts +22 -0
- package/dist/tools/securityPolicyInfo.d.ts.map +1 -0
- package/dist/tools/securityPolicyInfo.js +49 -0
- package/dist/tools/securityPolicyInfo.js.map +1 -0
- package/dist/tools/securityPrivilegeXml.d.ts +21 -0
- package/dist/tools/securityPrivilegeXml.d.ts.map +1 -0
- package/dist/tools/securityPrivilegeXml.js +61 -0
- package/dist/tools/securityPrivilegeXml.js.map +1 -0
- package/dist/tools/serviceInfo.d.ts +25 -0
- package/dist/tools/serviceInfo.d.ts.map +1 -0
- package/dist/tools/serviceInfo.js +93 -0
- package/dist/tools/serviceInfo.js.map +1 -0
- package/dist/tools/suggestEdt.d.ts +15 -0
- package/dist/tools/suggestEdt.d.ts.map +1 -0
- package/dist/tools/suggestEdt.js +348 -0
- package/dist/tools/suggestEdt.js.map +1 -0
- package/dist/tools/suggestImplementation.d.ts +20 -0
- package/dist/tools/suggestImplementation.d.ts.map +1 -0
- package/dist/tools/suggestImplementation.js +144 -0
- package/dist/tools/suggestImplementation.js.map +1 -0
- package/dist/tools/sysTestRunner.d.ts +14 -0
- package/dist/tools/sysTestRunner.d.ts.map +1 -0
- package/dist/tools/sysTestRunner.js +145 -0
- package/dist/tools/sysTestRunner.js.map +1 -0
- package/dist/tools/tableExtensionInfo.d.ts +91 -0
- package/dist/tools/tableExtensionInfo.d.ts.map +1 -0
- package/dist/tools/tableExtensionInfo.js +305 -0
- package/dist/tools/tableExtensionInfo.js.map +1 -0
- package/dist/tools/tableInfo.d.ts +23 -0
- package/dist/tools/tableInfo.d.ts.map +1 -0
- package/dist/tools/tableInfo.js +125 -0
- package/dist/tools/tableInfo.js.map +1 -0
- package/dist/tools/toolHandler.d.ts +4 -0
- package/dist/tools/toolHandler.d.ts.map +1 -0
- package/dist/tools/toolHandler.js +508 -0
- package/dist/tools/toolHandler.js.map +1 -0
- package/dist/tools/undoLastModification.d.ts +15 -0
- package/dist/tools/undoLastModification.d.ts.map +1 -0
- package/dist/tools/undoLastModification.js +147 -0
- package/dist/tools/undoLastModification.js.map +1 -0
- package/dist/tools/updateSymbolIndex.d.ts +15 -0
- package/dist/tools/updateSymbolIndex.d.ts.map +1 -0
- package/dist/tools/updateSymbolIndex.js +520 -0
- package/dist/tools/updateSymbolIndex.js.map +1 -0
- package/dist/tools/validateCode.d.ts +24 -0
- package/dist/tools/validateCode.d.ts.map +1 -0
- package/dist/tools/validateCode.js +201 -0
- package/dist/tools/validateCode.js.map +1 -0
- package/dist/tools/validateFormPattern.d.ts +51 -0
- package/dist/tools/validateFormPattern.d.ts.map +1 -0
- package/dist/tools/validateFormPattern.js +201 -0
- package/dist/tools/validateFormPattern.js.map +1 -0
- package/dist/tools/validateObjectNaming.d.ts +21 -0
- package/dist/tools/validateObjectNaming.d.ts.map +1 -0
- package/dist/tools/validateObjectNaming.js +319 -0
- package/dist/tools/validateObjectNaming.js.map +1 -0
- package/dist/tools/validateXpp.d.ts +79 -0
- package/dist/tools/validateXpp.d.ts.map +1 -0
- package/dist/tools/validateXpp.js +705 -0
- package/dist/tools/validateXpp.js.map +1 -0
- package/dist/tools/verifyD365Project.d.ts +21 -0
- package/dist/tools/verifyD365Project.d.ts.map +1 -0
- package/dist/tools/verifyD365Project.js +299 -0
- package/dist/tools/verifyD365Project.js.map +1 -0
- package/dist/tools/viewInfo.d.ts +17 -0
- package/dist/tools/viewInfo.d.ts.map +1 -0
- package/dist/tools/viewInfo.js +46 -0
- package/dist/tools/viewInfo.js.map +1 -0
- package/dist/tools/xppKnowledge.d.ts +45 -0
- package/dist/tools/xppKnowledge.d.ts.map +1 -0
- package/dist/tools/xppKnowledge.js +2815 -0
- package/dist/tools/xppKnowledge.js.map +1 -0
- package/dist/types/context.d.ts +56 -0
- package/dist/types/context.d.ts.map +1 -0
- package/dist/types/context.js +5 -0
- package/dist/types/context.js.map +1 -0
- package/dist/utils/callDedup.d.ts +29 -0
- package/dist/utils/callDedup.d.ts.map +1 -0
- package/dist/utils/callDedup.js +87 -0
- package/dist/utils/callDedup.js.map +1 -0
- package/dist/utils/configManager.d.ts +307 -0
- package/dist/utils/configManager.d.ts.map +1 -0
- package/dist/utils/configManager.js +1169 -0
- package/dist/utils/configManager.js.map +1 -0
- package/dist/utils/d365XmlNormalizer.d.ts +9 -0
- package/dist/utils/d365XmlNormalizer.d.ts.map +1 -0
- package/dist/utils/d365XmlNormalizer.js +24 -0
- package/dist/utils/d365XmlNormalizer.js.map +1 -0
- package/dist/utils/edtExtensionValidator.d.ts +110 -0
- package/dist/utils/edtExtensionValidator.d.ts.map +1 -0
- package/dist/utils/edtExtensionValidator.js +367 -0
- package/dist/utils/edtExtensionValidator.js.map +1 -0
- package/dist/utils/eolUtils.d.ts +15 -0
- package/dist/utils/eolUtils.d.ts.map +1 -0
- package/dist/utils/eolUtils.js +21 -0
- package/dist/utils/eolUtils.js.map +1 -0
- package/dist/utils/extractManifest.d.ts +34 -0
- package/dist/utils/extractManifest.d.ts.map +1 -0
- package/dist/utils/extractManifest.js +43 -0
- package/dist/utils/extractManifest.js.map +1 -0
- package/dist/utils/fieldControlTypes.d.ts +44 -0
- package/dist/utils/fieldControlTypes.d.ts.map +1 -0
- package/dist/utils/fieldControlTypes.js +97 -0
- package/dist/utils/fieldControlTypes.js.map +1 -0
- package/dist/utils/formCloner.d.ts +77 -0
- package/dist/utils/formCloner.d.ts.map +1 -0
- package/dist/utils/formCloner.js +364 -0
- package/dist/utils/formCloner.js.map +1 -0
- package/dist/utils/formControlExpander.d.ts +68 -0
- package/dist/utils/formControlExpander.d.ts.map +1 -0
- package/dist/utils/formControlExpander.js +207 -0
- package/dist/utils/formControlExpander.js.map +1 -0
- package/dist/utils/formControlRepair.d.ts +81 -0
- package/dist/utils/formControlRepair.d.ts.map +1 -0
- package/dist/utils/formControlRepair.js +203 -0
- package/dist/utils/formControlRepair.js.map +1 -0
- package/dist/utils/formExtensionShapeValidator.d.ts +44 -0
- package/dist/utils/formExtensionShapeValidator.d.ts.map +1 -0
- package/dist/utils/formExtensionShapeValidator.js +99 -0
- package/dist/utils/formExtensionShapeValidator.js.map +1 -0
- package/dist/utils/formPatternTemplates.d.ts +77 -0
- package/dist/utils/formPatternTemplates.d.ts.map +1 -0
- package/dist/utils/formPatternTemplates.js +1917 -0
- package/dist/utils/formPatternTemplates.js.map +1 -0
- package/dist/utils/fsExtensionScanner.d.ts +76 -0
- package/dist/utils/fsExtensionScanner.d.ts.map +1 -0
- package/dist/utils/fsExtensionScanner.js +271 -0
- package/dist/utils/fsExtensionScanner.js.map +1 -0
- package/dist/utils/fuzzyMatching.d.ts +41 -0
- package/dist/utils/fuzzyMatching.d.ts.map +1 -0
- package/dist/utils/fuzzyMatching.js +186 -0
- package/dist/utils/fuzzyMatching.js.map +1 -0
- package/dist/utils/indexStaleness.d.ts +30 -0
- package/dist/utils/indexStaleness.d.ts.map +1 -0
- package/dist/utils/indexStaleness.js +104 -0
- package/dist/utils/indexStaleness.js.map +1 -0
- package/dist/utils/loadEnv.d.ts +32 -0
- package/dist/utils/loadEnv.d.ts.map +1 -0
- package/dist/utils/loadEnv.js +83 -0
- package/dist/utils/loadEnv.js.map +1 -0
- package/dist/utils/logger.d.ts +4 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +11 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/metadataResolver.d.ts +155 -0
- package/dist/utils/metadataResolver.d.ts.map +1 -0
- package/dist/utils/metadataResolver.js +277 -0
- package/dist/utils/metadataResolver.js.map +1 -0
- package/dist/utils/modelClassifier.d.ts +180 -0
- package/dist/utils/modelClassifier.d.ts.map +1 -0
- package/dist/utils/modelClassifier.js +373 -0
- package/dist/utils/modelClassifier.js.map +1 -0
- package/dist/utils/operationLocks.d.ts +26 -0
- package/dist/utils/operationLocks.d.ts.map +1 -0
- package/dist/utils/operationLocks.js +182 -0
- package/dist/utils/operationLocks.js.map +1 -0
- package/dist/utils/packageResolver.d.ts +52 -0
- package/dist/utils/packageResolver.d.ts.map +1 -0
- package/dist/utils/packageResolver.js +174 -0
- package/dist/utils/packageResolver.js.map +1 -0
- package/dist/utils/pathContainment.d.ts +60 -0
- package/dist/utils/pathContainment.d.ts.map +1 -0
- package/dist/utils/pathContainment.js +270 -0
- package/dist/utils/pathContainment.js.map +1 -0
- package/dist/utils/projectUtils.d.ts +14 -0
- package/dist/utils/projectUtils.d.ts.map +1 -0
- package/dist/utils/projectUtils.js +48 -0
- package/dist/utils/projectUtils.js.map +1 -0
- package/dist/utils/provenanceStore.d.ts +54 -0
- package/dist/utils/provenanceStore.d.ts.map +1 -0
- package/dist/utils/provenanceStore.js +203 -0
- package/dist/utils/provenanceStore.js.map +1 -0
- package/dist/utils/richContext.d.ts +45 -0
- package/dist/utils/richContext.d.ts.map +1 -0
- package/dist/utils/richContext.js +316 -0
- package/dist/utils/richContext.js.map +1 -0
- package/dist/utils/smartXmlBuilder.d.ts +187 -0
- package/dist/utils/smartXmlBuilder.d.ts.map +1 -0
- package/dist/utils/smartXmlBuilder.js +504 -0
- package/dist/utils/smartXmlBuilder.js.map +1 -0
- package/dist/utils/stdioSessionInfo.d.ts +53 -0
- package/dist/utils/stdioSessionInfo.d.ts.map +1 -0
- package/dist/utils/stdioSessionInfo.js +47 -0
- package/dist/utils/stdioSessionInfo.js.map +1 -0
- package/dist/utils/suggestionEngine.d.ts +20 -0
- package/dist/utils/suggestionEngine.d.ts.map +1 -0
- package/dist/utils/suggestionEngine.js +145 -0
- package/dist/utils/suggestionEngine.js.map +1 -0
- package/dist/utils/symbolLookup.d.ts +60 -0
- package/dist/utils/symbolLookup.d.ts.map +1 -0
- package/dist/utils/symbolLookup.js +0 -0
- package/dist/utils/symbolLookup.js.map +1 -0
- package/dist/utils/terminalUi.d.ts +85 -0
- package/dist/utils/terminalUi.d.ts.map +1 -0
- package/dist/utils/terminalUi.js +182 -0
- package/dist/utils/terminalUi.js.map +1 -0
- package/dist/utils/toolMetrics.d.ts +32 -0
- package/dist/utils/toolMetrics.d.ts.map +1 -0
- package/dist/utils/toolMetrics.js +89 -0
- package/dist/utils/toolMetrics.js.map +1 -0
- package/dist/utils/toolProgressMessage.d.ts +8 -0
- package/dist/utils/toolProgressMessage.d.ts.map +1 -0
- package/dist/utils/toolProgressMessage.js +182 -0
- package/dist/utils/toolProgressMessage.js.map +1 -0
- package/dist/utils/workspaceDetector.d.ts +51 -0
- package/dist/utils/workspaceDetector.d.ts.map +1 -0
- package/dist/utils/workspaceDetector.js +328 -0
- package/dist/utils/workspaceDetector.js.map +1 -0
- package/dist/utils/xppConfigProvider.d.ts +48 -0
- package/dist/utils/xppConfigProvider.d.ts.map +1 -0
- package/dist/utils/xppConfigProvider.js +121 -0
- package/dist/utils/xppConfigProvider.js.map +1 -0
- package/dist/utils/xppDocGen.d.ts +39 -0
- package/dist/utils/xppDocGen.d.ts.map +1 -0
- package/dist/utils/xppDocGen.js +518 -0
- package/dist/utils/xppDocGen.js.map +1 -0
- package/dist/utils/xppFormat.d.ts +21 -0
- package/dist/utils/xppFormat.d.ts.map +1 -0
- package/dist/utils/xppFormat.js +102 -0
- package/dist/utils/xppFormat.js.map +1 -0
- package/dist/utils/xppSelectLint.d.ts +18 -0
- package/dist/utils/xppSelectLint.d.ts.map +1 -0
- package/dist/utils/xppSelectLint.js +80 -0
- package/dist/utils/xppSelectLint.js.map +1 -0
- package/dist/validation/formPatternValidator.d.ts +53 -0
- package/dist/validation/formPatternValidator.d.ts.map +1 -0
- package/dist/validation/formPatternValidator.js +454 -0
- package/dist/validation/formPatternValidator.js.map +1 -0
- package/dist/workspace/contextRanker.d.ts +58 -0
- package/dist/workspace/contextRanker.d.ts.map +1 -0
- package/dist/workspace/contextRanker.js +216 -0
- package/dist/workspace/contextRanker.js.map +1 -0
- package/dist/workspace/contextSnapshot.d.ts +68 -0
- package/dist/workspace/contextSnapshot.d.ts.map +1 -0
- package/dist/workspace/contextSnapshot.js +193 -0
- package/dist/workspace/contextSnapshot.js.map +1 -0
- package/dist/workspace/hybridSearch.d.ts +39 -0
- package/dist/workspace/hybridSearch.d.ts.map +1 -0
- package/dist/workspace/hybridSearch.js +96 -0
- package/dist/workspace/hybridSearch.js.map +1 -0
- package/dist/workspace/workspaceScanner.d.ts +95 -0
- package/dist/workspace/workspaceScanner.d.ts.map +1 -0
- package/dist/workspace/workspaceScanner.js +247 -0
- package/dist/workspace/workspaceScanner.js.map +1 -0
- package/dist/workspace/workspaceUtils.d.ts +23 -0
- package/dist/workspace/workspaceUtils.d.ts.map +1 -0
- package/dist/workspace/workspaceUtils.js +77 -0
- package/dist/workspace/workspaceUtils.js.map +1 -0
- package/package.json +94 -0
|
@@ -0,0 +1,1956 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* X++ Code Generation Tool
|
|
3
|
+
* Generate X++ code templates for common patterns
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { resolveObjectPrefix, applyObjectPrefix, deriveExtensionInfix, getObjectSuffix, applyObjectSuffix } from '../utils/modelClassifier.js';
|
|
7
|
+
import { getConfigManager } from '../utils/configManager.js';
|
|
8
|
+
import { enforceGrounding } from '../utils/provenanceStore.js';
|
|
9
|
+
const CodeGenArgsSchema = z.object({
|
|
10
|
+
pattern: z
|
|
11
|
+
.enum(['class', 'runnable', 'form-handler', 'data-entity', 'batch-job', 'table-extension',
|
|
12
|
+
'sysoperation', 'event-handler', 'security-privilege', 'menu-item', 'class-extension',
|
|
13
|
+
'ssrs-report-full', 'lookup-form',
|
|
14
|
+
'dialog-box', 'dimension-controller', 'number-seq-handler',
|
|
15
|
+
'display-menu-controller', 'data-entity-staging', 'service-class-ais',
|
|
16
|
+
'form-datasource-extension', 'form-control-extension', 'map-extension',
|
|
17
|
+
'business-event', 'custom-telemetry', 'feature-class',
|
|
18
|
+
'composite-entity', 'custom-service', 'er-custom-function'])
|
|
19
|
+
.describe('Code pattern to generate'),
|
|
20
|
+
name: z.string().describe('For NEW objects (class, runnable, data-entity, batch-job, sysoperation): the object name WITHOUT prefix — prefix is auto-applied from EXTENSION_PREFIX env var or modelName. ' +
|
|
21
|
+
'For EXTENSIONS (table-extension, form-handler, class-extension, map-extension): the BASE element name to extend (e.g. "CustTable", "SalesTable"). ' +
|
|
22
|
+
'For form-datasource-extension and form-control-extension: the FORM name (e.g. "CustTable"). ' +
|
|
23
|
+
'For XML patterns (security-privilege, menu-item): the name for the generated XML object.'),
|
|
24
|
+
modelName: z.string().optional().describe('Actual model name from .mcp.json — used to derive the naming infix when EXTENSION_PREFIX env var is not set (e.g. "ContosoExt", "WHSExt", "ApplicationSuite"). ' +
|
|
25
|
+
'Required for extension patterns when EXTENSION_PREFIX is not configured. ' +
|
|
26
|
+
'NEVER pass generic placeholders like "MyModel" — always use the real model name from .mcp.json.'),
|
|
27
|
+
menuItemType: z.enum(['display', 'action', 'output']).optional()
|
|
28
|
+
.describe('For menu-item pattern: type of menu item (display=form, action=class, output=report)'),
|
|
29
|
+
baseName: z.string().optional()
|
|
30
|
+
.describe('For event-handler pattern: base class or table name whose events to handle. ' +
|
|
31
|
+
'For form-datasource-extension: data source name within the form (e.g. "CustTable"). Defaults to form name if omitted. ' +
|
|
32
|
+
'For form-control-extension: control name within the form (e.g. "AccountNum", "CustAccount").'),
|
|
33
|
+
targetObject: z.string().optional()
|
|
34
|
+
.describe('For menu-item pattern: target form/class/report name'),
|
|
35
|
+
serviceMethod: z.string().optional()
|
|
36
|
+
.describe('For sysoperation pattern: the name of the method on the Service class that the Controller will call. ' +
|
|
37
|
+
'Defaults to "process" when omitted. ' +
|
|
38
|
+
'Example: serviceMethod="processOrders" → generates processOrders() on the Service class.'),
|
|
39
|
+
groundingToken: z.string().optional()
|
|
40
|
+
.describe('Provenance token from prepare(mode="change"). Required for extension patterns when ' +
|
|
41
|
+
'GROUNDING_ENFORCE=true. Proves the AI queried the real D365FO codebase before generating code.'),
|
|
42
|
+
});
|
|
43
|
+
// Templates for NEW elements (name already includes prefix)
|
|
44
|
+
const newElementTemplates = {
|
|
45
|
+
class: (name) => `
|
|
46
|
+
/// <summary>
|
|
47
|
+
/// Implements business logic and operations for the ${name} process.
|
|
48
|
+
/// TODO: Add a more specific description of what this class is responsible for.
|
|
49
|
+
/// </summary>
|
|
50
|
+
public class ${name}
|
|
51
|
+
{
|
|
52
|
+
public void run()
|
|
53
|
+
{
|
|
54
|
+
// TODO: Implement
|
|
55
|
+
}
|
|
56
|
+
}`,
|
|
57
|
+
runnable: (name) => `
|
|
58
|
+
/// <summary>
|
|
59
|
+
/// Runnable entry point that executes the ${name} operation directly.
|
|
60
|
+
/// </summary>
|
|
61
|
+
internal final class ${name}
|
|
62
|
+
{
|
|
63
|
+
/// <summary>
|
|
64
|
+
/// Entry point called by the menu item. Creates an instance and calls run().
|
|
65
|
+
/// </summary>
|
|
66
|
+
public static void main(Args _args)
|
|
67
|
+
{
|
|
68
|
+
${name} instance = new ${name}();
|
|
69
|
+
instance.run();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/// <summary>
|
|
73
|
+
/// Executes the ${name} business logic.
|
|
74
|
+
/// TODO: Add a description of what this method processes.
|
|
75
|
+
/// </summary>
|
|
76
|
+
public void run()
|
|
77
|
+
{
|
|
78
|
+
// TODO: Implement logic
|
|
79
|
+
info(strFmt("Executing %1", classStr(${name})));
|
|
80
|
+
}
|
|
81
|
+
}`,
|
|
82
|
+
'data-entity': (name) => `
|
|
83
|
+
// ══════════════════════════════════════════════════════════════════
|
|
84
|
+
// D365FO Data Entity: ${name}Entity
|
|
85
|
+
// ══════════════════════════════════════════════════════════════════
|
|
86
|
+
// Data entities are AxDataEntityView XML objects (NOT X++ classes).
|
|
87
|
+
// Use create_d365fo_file(objectType="view") or the VS designer.
|
|
88
|
+
//
|
|
89
|
+
// Key properties to set in XML:
|
|
90
|
+
// PublicEntityName: "${name}" (OData singular name)
|
|
91
|
+
// PublicCollectionName: "${name}s" (OData plural name)
|
|
92
|
+
// IsPublic: Yes (expose via OData)
|
|
93
|
+
// DataManagementEnabled: Yes (enable DMF import/export)
|
|
94
|
+
// EntityCategory: Master | Transaction | Document | Reference | Parameter
|
|
95
|
+
// PrimaryKey: EntityKey (natural key index, NOT RecId)
|
|
96
|
+
//
|
|
97
|
+
// Datasource config:
|
|
98
|
+
// Root datasource: ${name} table (IsReadOnly = No for read-write entity)
|
|
99
|
+
// Join datasources: Additional tables via inner/outer joins
|
|
100
|
+
//
|
|
101
|
+
// Example computed column (for cross-datasource or calculated fields):
|
|
102
|
+
// private static server str computeDisplayName()
|
|
103
|
+
// {
|
|
104
|
+
// return SysComputedColumn::returnField(
|
|
105
|
+
// tableStr(DirPartyTable), identifierStr(Name));
|
|
106
|
+
// }
|
|
107
|
+
//
|
|
108
|
+
// Workflow:
|
|
109
|
+
// 1. get_object_info(objectType="data-entity", name="similar entity") → study structure
|
|
110
|
+
// 2. generate_d365fo_xml(objectType="data-entity", ...) → preview XML
|
|
111
|
+
// 3. create_d365fo_file(objectType="view", ...) → create file
|
|
112
|
+
// 4. After deployment: refresh entity list in Data Management workspace
|
|
113
|
+
`,
|
|
114
|
+
'batch-job': (name) => `
|
|
115
|
+
/// <summary>
|
|
116
|
+
/// Controller that orchestrates the ${name} batch operation.
|
|
117
|
+
/// Extends SysOperationServiceController — handles dialog, pack/unpack, and execution mode.
|
|
118
|
+
/// </summary>
|
|
119
|
+
class ${name}Controller extends SysOperationServiceController
|
|
120
|
+
{
|
|
121
|
+
/// <summary>
|
|
122
|
+
/// Entry point called by the menu item action. Launches the SysOperation dialog.
|
|
123
|
+
/// </summary>
|
|
124
|
+
public static void main(Args _args)
|
|
125
|
+
{
|
|
126
|
+
${name}Controller controller = new ${name}Controller();
|
|
127
|
+
controller.parmArgs(_args);
|
|
128
|
+
controller.parmDialogCaption("${name}");
|
|
129
|
+
controller.startOperation();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/// <summary>
|
|
133
|
+
/// Constructor — wires up the service class and method.
|
|
134
|
+
/// SysOperationServiceController handles pack/unpack automatically via DataContract.
|
|
135
|
+
/// </summary>
|
|
136
|
+
protected void new()
|
|
137
|
+
{
|
|
138
|
+
super();
|
|
139
|
+
this.parmClassName(classStr(${name}Service));
|
|
140
|
+
this.parmMethodName(methodStr(${name}Service, process));
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/// <summary>
|
|
145
|
+
/// Service class that implements the ${name} batch processing logic.
|
|
146
|
+
/// Called by the controller via the SysOperation framework.
|
|
147
|
+
/// </summary>
|
|
148
|
+
class ${name}Service extends SysOperationServiceBase
|
|
149
|
+
{
|
|
150
|
+
/// <summary>
|
|
151
|
+
/// Processes the ${name} batch operation. Called by the controller.
|
|
152
|
+
/// TODO: Add a description of what records or data this processes.
|
|
153
|
+
/// </summary>
|
|
154
|
+
public void process()
|
|
155
|
+
{
|
|
156
|
+
// TODO: Implement batch processing logic
|
|
157
|
+
ttsbegin;
|
|
158
|
+
|
|
159
|
+
// Your logic here
|
|
160
|
+
|
|
161
|
+
ttscommit;
|
|
162
|
+
|
|
163
|
+
info(strFmt("${name} completed successfully"));
|
|
164
|
+
}
|
|
165
|
+
}`,
|
|
166
|
+
// sysoperation handled specially in codeGenTool (needs serviceMethod param)
|
|
167
|
+
'ssrs-report-full': ssrsReportFullTemplate,
|
|
168
|
+
'lookup-form': lookupFormTemplate,
|
|
169
|
+
'dialog-box': dialogBoxTemplate,
|
|
170
|
+
'dimension-controller': dimensionControllerTemplate,
|
|
171
|
+
'number-seq-handler': numberSeqHandlerTemplate,
|
|
172
|
+
'display-menu-controller': displayMenuControllerTemplate,
|
|
173
|
+
'data-entity-staging': dataEntityStagingTemplate,
|
|
174
|
+
'service-class-ais': serviceClassAisTemplate,
|
|
175
|
+
'business-event': businessEventTemplate,
|
|
176
|
+
'custom-telemetry': customTelemetryTemplate,
|
|
177
|
+
'feature-class': featureClassTemplate,
|
|
178
|
+
'composite-entity': compositeEntityTemplate,
|
|
179
|
+
'custom-service': customServiceTemplate,
|
|
180
|
+
'er-custom-function': erCustomFunctionTemplate,
|
|
181
|
+
};
|
|
182
|
+
// Templates for EXTENSION elements: (baseName = element being extended, prefix = model/ISV infix)
|
|
183
|
+
// Naming rules per https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/extensibility/naming-guidelines-extensions:
|
|
184
|
+
// table-extension class : {BaseTable}{Prefix}_Extension (e.g. CustTableWHS_Extension)
|
|
185
|
+
// form-handler class : {BaseForm}{Prefix}Form_Extension (e.g. SalesTableWHSForm_Extension)
|
|
186
|
+
function formHandlerTemplate(baseName, prefix) {
|
|
187
|
+
// Class name: {BaseForm}{Prefix}Form_Extension
|
|
188
|
+
const className = baseName + prefix + 'Form_Extension';
|
|
189
|
+
return `
|
|
190
|
+
/// <summary>
|
|
191
|
+
/// Form extension class for ${baseName} (prefix: ${prefix})
|
|
192
|
+
/// Naming: {BaseForm}{Prefix}Form_Extension per MS naming guidelines
|
|
193
|
+
/// </summary>
|
|
194
|
+
[ExtensionOf(formStr(${baseName}))]
|
|
195
|
+
final class ${className}
|
|
196
|
+
{
|
|
197
|
+
/// <summary>
|
|
198
|
+
/// Form initialization
|
|
199
|
+
/// </summary>
|
|
200
|
+
public void init()
|
|
201
|
+
{
|
|
202
|
+
next init();
|
|
203
|
+
// TODO: Add custom initialization logic
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/// <summary>
|
|
207
|
+
/// Form close
|
|
208
|
+
/// </summary>
|
|
209
|
+
public void close()
|
|
210
|
+
{
|
|
211
|
+
// TODO: Add cleanup logic
|
|
212
|
+
next close();
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/// <summary>
|
|
216
|
+
/// Data source active event handler
|
|
217
|
+
/// </summary>
|
|
218
|
+
[FormDataSourceEventHandler(formDataSourceStr(${baseName}, DataSourceName), FormDataSourceEventType::Activated)]
|
|
219
|
+
public static void DataSourceName_OnActivated(FormDataSource sender, FormDataSourceEventArgs e)
|
|
220
|
+
{
|
|
221
|
+
// TODO: Handle data source activation
|
|
222
|
+
}
|
|
223
|
+
}`;
|
|
224
|
+
}
|
|
225
|
+
function tableExtensionTemplate(baseName, prefix) {
|
|
226
|
+
// Class name: {BaseTable}{Prefix}_Extension
|
|
227
|
+
const className = baseName + prefix + '_Extension';
|
|
228
|
+
return `
|
|
229
|
+
/// <summary>
|
|
230
|
+
/// Table extension class for ${baseName} (prefix: ${prefix})
|
|
231
|
+
/// Naming: {BaseTable}{Prefix}_Extension per MS naming guidelines
|
|
232
|
+
/// </summary>
|
|
233
|
+
[ExtensionOf(tableStr(${baseName}))]
|
|
234
|
+
final class ${className}
|
|
235
|
+
{
|
|
236
|
+
/// <summary>
|
|
237
|
+
/// Validate write
|
|
238
|
+
/// </summary>
|
|
239
|
+
public boolean validateWrite()
|
|
240
|
+
{
|
|
241
|
+
boolean ret = next validateWrite();
|
|
242
|
+
|
|
243
|
+
// TODO: Add custom validation
|
|
244
|
+
|
|
245
|
+
return ret;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/// <summary>
|
|
249
|
+
/// Insert event
|
|
250
|
+
/// </summary>
|
|
251
|
+
public void insert()
|
|
252
|
+
{
|
|
253
|
+
// TODO: Add pre-insert logic
|
|
254
|
+
|
|
255
|
+
next insert();
|
|
256
|
+
|
|
257
|
+
// TODO: Add post-insert logic
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/// <summary>
|
|
261
|
+
/// Update event
|
|
262
|
+
/// </summary>
|
|
263
|
+
public void update()
|
|
264
|
+
{
|
|
265
|
+
// TODO: Add pre-update logic
|
|
266
|
+
|
|
267
|
+
next update();
|
|
268
|
+
|
|
269
|
+
// TODO: Add post-update logic
|
|
270
|
+
}
|
|
271
|
+
}`;
|
|
272
|
+
}
|
|
273
|
+
function classExtensionTemplate(baseName, prefix) {
|
|
274
|
+
// Class name: {BaseClass}{Prefix}_Extension per MS naming guidelines
|
|
275
|
+
const className = baseName + prefix + '_Extension';
|
|
276
|
+
return `
|
|
277
|
+
/// <summary>
|
|
278
|
+
/// Extension class for ${baseName} (prefix: ${prefix})
|
|
279
|
+
/// Naming: {BaseClass}{Prefix}_Extension per MS naming guidelines
|
|
280
|
+
/// </summary>
|
|
281
|
+
[ExtensionOf(classStr(${baseName}))]
|
|
282
|
+
final class ${className}
|
|
283
|
+
{
|
|
284
|
+
// ⚠️ DO NOT add CoC methods before checking the original signature:
|
|
285
|
+
// get_method_signature("${baseName}", "methodName")
|
|
286
|
+
//
|
|
287
|
+
// X++ does NOT support method overloading — two methods with the same name
|
|
288
|
+
// will always cause a compile error, even with different signatures.
|
|
289
|
+
//
|
|
290
|
+
// Instance method CoC template:
|
|
291
|
+
// public ReturnType methodName(ParamType _param)
|
|
292
|
+
// {
|
|
293
|
+
// ReturnType result = next methodName(_param);
|
|
294
|
+
// return result;
|
|
295
|
+
// }
|
|
296
|
+
//
|
|
297
|
+
// Static method CoC template:
|
|
298
|
+
// public static ReturnType methodName(ParamType _param)
|
|
299
|
+
// {
|
|
300
|
+
// ReturnType result = next methodName(_param);
|
|
301
|
+
// return result;
|
|
302
|
+
// }
|
|
303
|
+
}`;
|
|
304
|
+
}
|
|
305
|
+
function formDataSourceExtensionTemplate(formName, prefix, dataSourceName) {
|
|
306
|
+
// Class name: {FormName}_{DataSourceName}{Prefix}DS_Extension per MS naming guidelines
|
|
307
|
+
const dsName = dataSourceName || formName;
|
|
308
|
+
const className = `${formName}_${dsName}${prefix}DS_Extension`;
|
|
309
|
+
return `
|
|
310
|
+
/// <summary>
|
|
311
|
+
/// Form data source extension class for ${formName}.${dsName} (prefix: ${prefix})
|
|
312
|
+
/// Naming: {FormName}_{DataSourceName}{Prefix}DS_Extension per MS naming guidelines
|
|
313
|
+
/// Use this to wrap data source methods (init, executeQuery, write, delete, validateWrite, active).
|
|
314
|
+
/// </summary>
|
|
315
|
+
[ExtensionOf(formDataSourceStr(${formName}, ${dsName}))]
|
|
316
|
+
final class ${className}
|
|
317
|
+
{
|
|
318
|
+
/// <summary>
|
|
319
|
+
/// Data source initialization — runs after the form and data source are ready.
|
|
320
|
+
/// Call next init() first to preserve standard behaviour.
|
|
321
|
+
/// </summary>
|
|
322
|
+
public void init()
|
|
323
|
+
{
|
|
324
|
+
next init();
|
|
325
|
+
// TODO: Add custom data source initialization (e.g. add ranges, set filters)
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/// <summary>
|
|
329
|
+
/// Override the query executed when the data source refreshes.
|
|
330
|
+
/// </summary>
|
|
331
|
+
public void executeQuery()
|
|
332
|
+
{
|
|
333
|
+
// TODO: Modify this.query() before calling next, if needed
|
|
334
|
+
next executeQuery();
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/// <summary>
|
|
338
|
+
/// Called when the active (selected) record changes.
|
|
339
|
+
/// </summary>
|
|
340
|
+
public int active()
|
|
341
|
+
{
|
|
342
|
+
int ret = next active();
|
|
343
|
+
// TODO: React to record selection change
|
|
344
|
+
return ret;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/// <summary>
|
|
348
|
+
/// Write event — runs when a record is saved from the form.
|
|
349
|
+
/// </summary>
|
|
350
|
+
public void write()
|
|
351
|
+
{
|
|
352
|
+
next write();
|
|
353
|
+
// TODO: Add post-save logic
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/// <summary>
|
|
357
|
+
/// Validate write — add custom business rules before save.
|
|
358
|
+
/// </summary>
|
|
359
|
+
public boolean validateWrite()
|
|
360
|
+
{
|
|
361
|
+
boolean ret = next validateWrite();
|
|
362
|
+
// TODO: if (ret) { /* custom validation */ }
|
|
363
|
+
return ret;
|
|
364
|
+
}
|
|
365
|
+
}`;
|
|
366
|
+
}
|
|
367
|
+
function formControlExtensionTemplate(formName, prefix, controlName) {
|
|
368
|
+
// Class name: {FormName}_{ControlName}{Prefix}Ctrl_Extension per MS naming guidelines
|
|
369
|
+
const ctrlName = controlName || 'ControlName';
|
|
370
|
+
const className = `${formName}_${ctrlName}${prefix}Ctrl_Extension`;
|
|
371
|
+
return `
|
|
372
|
+
/// <summary>
|
|
373
|
+
/// Form control extension class for ${formName}.${ctrlName} (prefix: ${prefix})
|
|
374
|
+
/// Naming: {FormName}_{ControlName}{Prefix}Ctrl_Extension per MS naming guidelines
|
|
375
|
+
/// Use this to wrap a specific control's methods (modified, validate, lookup, gotFocus, …).
|
|
376
|
+
/// IMPORTANT: Use get_object_info(objectType="form", name="${formName}", options={searchControl:"${ctrlName}"}) first to verify the exact control name.
|
|
377
|
+
/// </summary>
|
|
378
|
+
[ExtensionOf(formControlStr(${formName}, ${ctrlName}))]
|
|
379
|
+
final class ${className}
|
|
380
|
+
{
|
|
381
|
+
/// <summary>
|
|
382
|
+
/// Fires when the control value is changed by the user.
|
|
383
|
+
/// </summary>
|
|
384
|
+
public void modified()
|
|
385
|
+
{
|
|
386
|
+
next modified();
|
|
387
|
+
// TODO: Add logic that reacts to the new value
|
|
388
|
+
// e.g. filter another field, refresh a data source, trigger a calculation
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/// <summary>
|
|
392
|
+
/// Validate the control value before save.
|
|
393
|
+
/// Return false + error() to block saving.
|
|
394
|
+
/// </summary>
|
|
395
|
+
public boolean validate()
|
|
396
|
+
{
|
|
397
|
+
boolean ret = next validate();
|
|
398
|
+
|
|
399
|
+
// TODO: if (ret) { str val = this.valueStr(); /* validate */ }
|
|
400
|
+
|
|
401
|
+
return ret;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/// <summary>
|
|
405
|
+
/// Override the lookup drop-down for this control.
|
|
406
|
+
/// Use SysTableLookup or a custom query.
|
|
407
|
+
/// </summary>
|
|
408
|
+
public void lookup()
|
|
409
|
+
{
|
|
410
|
+
// TODO: Replace with custom lookup, or call next lookup() for standard behaviour
|
|
411
|
+
next lookup();
|
|
412
|
+
}
|
|
413
|
+
}`;
|
|
414
|
+
}
|
|
415
|
+
function mapExtensionTemplate(baseName, prefix) {
|
|
416
|
+
// Class name: {MapName}{Prefix}_Extension per MS naming guidelines
|
|
417
|
+
const className = `${baseName}${prefix}_Extension`;
|
|
418
|
+
return `
|
|
419
|
+
/// <summary>
|
|
420
|
+
/// Map extension class for ${baseName} (prefix: ${prefix})
|
|
421
|
+
/// Naming: {MapName}{Prefix}_Extension per MS naming guidelines
|
|
422
|
+
/// Use this to add or wrap methods on an X++ Map (InventItemOrdered, LogisticsPostalAddress, …).
|
|
423
|
+
/// </summary>
|
|
424
|
+
[ExtensionOf(mapStr(${baseName}))]
|
|
425
|
+
final class ${className}
|
|
426
|
+
{
|
|
427
|
+
// ⚠️ Always call get_method_signature("${baseName}", "methodName") before adding a CoC method.
|
|
428
|
+
// X++ does NOT support method overloading — duplicate method names always cause compile errors.
|
|
429
|
+
//
|
|
430
|
+
// Instance CoC example:
|
|
431
|
+
// public str myMethod(str _param)
|
|
432
|
+
// {
|
|
433
|
+
// str ret = next myMethod(_param);
|
|
434
|
+
// // Custom logic here
|
|
435
|
+
// return ret;
|
|
436
|
+
// }
|
|
437
|
+
//
|
|
438
|
+
// New helper method (no next required — purely additive):
|
|
439
|
+
// public str myNewHelper()
|
|
440
|
+
// {
|
|
441
|
+
// return this.SomeMapField;
|
|
442
|
+
// }
|
|
443
|
+
}`;
|
|
444
|
+
}
|
|
445
|
+
const extensionTemplates = {
|
|
446
|
+
'form-handler': formHandlerTemplate,
|
|
447
|
+
'table-extension': tableExtensionTemplate,
|
|
448
|
+
'event-handler': eventHandlerTemplate,
|
|
449
|
+
'class-extension': classExtensionTemplate,
|
|
450
|
+
'map-extension': mapExtensionTemplate,
|
|
451
|
+
};
|
|
452
|
+
// SysOperation pattern: 3 classes (DataContract + Controller + Service)
|
|
453
|
+
function sysOperationTemplate(name, serviceMethod = 'process') {
|
|
454
|
+
return `
|
|
455
|
+
// ── 1. DataContract ─────────────────────────────────────────────────────
|
|
456
|
+
/// <summary>
|
|
457
|
+
/// Data contract for the ${name} SysOperation. Stores user-supplied parameters
|
|
458
|
+
/// that are serialized between the dialog and the service class.
|
|
459
|
+
/// </summary>
|
|
460
|
+
[DataContractAttribute]
|
|
461
|
+
public final class ${name}DataContract
|
|
462
|
+
{
|
|
463
|
+
TransDate transDate;
|
|
464
|
+
|
|
465
|
+
[DataMemberAttribute('TransDate'),
|
|
466
|
+
SysOperationLabelAttribute(literalStr("Transaction date"))]
|
|
467
|
+
public TransDate parmTransDate(TransDate _transDate = transDate)
|
|
468
|
+
{
|
|
469
|
+
transDate = _transDate;
|
|
470
|
+
return transDate;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// ── 2. Controller ────────────────────────────────────────────────────────
|
|
475
|
+
/// <summary>
|
|
476
|
+
/// Controller for ${name} — wires service class and method via new() override.
|
|
477
|
+
/// This is the standard D365FO pattern (used in ApplicationSuite).
|
|
478
|
+
/// </summary>
|
|
479
|
+
class ${name}Controller extends SysOperationServiceController
|
|
480
|
+
{
|
|
481
|
+
/// <summary>
|
|
482
|
+
/// Wires up the service class and method. The parent class SysOperationServiceController
|
|
483
|
+
/// handles dialog building, pack/unpack, and execution mode automatically.
|
|
484
|
+
/// </summary>
|
|
485
|
+
protected void new()
|
|
486
|
+
{
|
|
487
|
+
super();
|
|
488
|
+
this.parmClassName(classStr(${name}Service));
|
|
489
|
+
this.parmMethodName(methodStr(${name}Service, ${serviceMethod}));
|
|
490
|
+
this.parmExecutionMode(SysOperationExecutionMode::Synchronous);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
protected ClassDescription defaultCaption()
|
|
494
|
+
{
|
|
495
|
+
return "${name}";
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
public static void main(Args _args)
|
|
499
|
+
{
|
|
500
|
+
${name}Controller controller = new ${name}Controller();
|
|
501
|
+
controller.parmArgs(_args);
|
|
502
|
+
controller.startOperation();
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// ── 3. Service ───────────────────────────────────────────────────────────
|
|
507
|
+
/// <summary>
|
|
508
|
+
/// Service class that contains the business logic for the ${name} operation.
|
|
509
|
+
/// The method marked [SysEntryPointAttribute] is called by the controller.
|
|
510
|
+
/// TODO: Add a description of what data or records this operation processes.
|
|
511
|
+
/// </summary>
|
|
512
|
+
class ${name}Service extends SysOperationServiceBase
|
|
513
|
+
{
|
|
514
|
+
/// <summary>
|
|
515
|
+
/// Business logic entry point called by the controller.
|
|
516
|
+
/// </summary>
|
|
517
|
+
[SysEntryPointAttribute(true)]
|
|
518
|
+
public void ${serviceMethod}(${name}DataContract _contract)
|
|
519
|
+
{
|
|
520
|
+
TransDate transDate = _contract.parmTransDate();
|
|
521
|
+
|
|
522
|
+
// TODO: Implement business logic
|
|
523
|
+
ttsbegin;
|
|
524
|
+
|
|
525
|
+
ttscommit;
|
|
526
|
+
}
|
|
527
|
+
}`;
|
|
528
|
+
}
|
|
529
|
+
// Event handler pattern: class with SubscribesTo handlers
|
|
530
|
+
function eventHandlerTemplate(baseName, _prefix) {
|
|
531
|
+
return `
|
|
532
|
+
/// <summary>
|
|
533
|
+
/// Event handler class for ${baseName} data events.
|
|
534
|
+
/// Uses [DataEventHandler] for standard table events (onInserted, onValidatedWrite, etc.).
|
|
535
|
+
/// For custom delegates, use [SubscribesTo(tableStr(X), delegateStr(X, myDelegate))] instead.
|
|
536
|
+
/// </summary>
|
|
537
|
+
public final class ${baseName}EventHandler
|
|
538
|
+
{
|
|
539
|
+
/// <summary>
|
|
540
|
+
/// Handles the onInserted data event of ${baseName}.
|
|
541
|
+
/// </summary>
|
|
542
|
+
[DataEventHandler(tableStr(${baseName}), DataEventType::Inserted)]
|
|
543
|
+
public static void ${baseName}_onInserted(Common _sender, DataEventArgs _e)
|
|
544
|
+
{
|
|
545
|
+
${baseName} record = _sender;
|
|
546
|
+
|
|
547
|
+
// TODO: Add event handling logic
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/// <summary>
|
|
551
|
+
/// Handles the onValidatedWrite data event of ${baseName}.
|
|
552
|
+
/// </summary>
|
|
553
|
+
[DataEventHandler(tableStr(${baseName}), DataEventType::ValidatedWrite)]
|
|
554
|
+
public static void ${baseName}_onValidatedWrite(Common _sender, DataEventArgs _e)
|
|
555
|
+
{
|
|
556
|
+
${baseName} record = _sender;
|
|
557
|
+
ValidateEventArgs validateArgs = _e;
|
|
558
|
+
boolean result = validateArgs.parmValidateResult();
|
|
559
|
+
|
|
560
|
+
if (result)
|
|
561
|
+
{
|
|
562
|
+
// TODO: Add validation logic
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
validateArgs.parmValidateResult(result);
|
|
566
|
+
}
|
|
567
|
+
}`;
|
|
568
|
+
}
|
|
569
|
+
// Security privilege XML pattern
|
|
570
|
+
function securityPrivilegeXmlTemplate(name, targetMenuItemName) {
|
|
571
|
+
const viewName = name.endsWith('View') ? name : `${name}View`;
|
|
572
|
+
const maintainName = name.endsWith('Maintain') ? name : `${name}Maintain`;
|
|
573
|
+
// File 1: ViewName.xml
|
|
574
|
+
const viewXml = `<?xml version="1.0" encoding="utf-8"?>
|
|
575
|
+
<AxSecurityPrivilege xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
|
|
576
|
+
\t<Name>${viewName}</Name>
|
|
577
|
+
\t<Label>@TODO:LabelId_View</Label>
|
|
578
|
+
\t<DataEntityPermissions />
|
|
579
|
+
\t<DirectAccessPermissions />
|
|
580
|
+
\t<EntryPoints>
|
|
581
|
+
\t\t<AxSecurityEntryPointReference>
|
|
582
|
+
\t\t\t<Name>${targetMenuItemName}</Name>
|
|
583
|
+
\t\t\t<Grant>
|
|
584
|
+
\t\t\t\t<Read>Allow</Read>
|
|
585
|
+
\t\t\t</Grant>
|
|
586
|
+
\t\t\t<ObjectName>${targetMenuItemName}</ObjectName>
|
|
587
|
+
\t\t\t<ObjectType>MenuItemDisplay</ObjectType>
|
|
588
|
+
\t\t\t<Forms />
|
|
589
|
+
\t\t</AxSecurityEntryPointReference>
|
|
590
|
+
\t</EntryPoints>
|
|
591
|
+
\t<FormControlOverrides />
|
|
592
|
+
</AxSecurityPrivilege>`;
|
|
593
|
+
// File 2: MaintainName.xml
|
|
594
|
+
const maintainXml = `<?xml version="1.0" encoding="utf-8"?>
|
|
595
|
+
<AxSecurityPrivilege xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
|
|
596
|
+
\t<Name>${maintainName}</Name>
|
|
597
|
+
\t<Label>@TODO:LabelId_Maintain</Label>
|
|
598
|
+
\t<DataEntityPermissions />
|
|
599
|
+
\t<DirectAccessPermissions />
|
|
600
|
+
\t<EntryPoints>
|
|
601
|
+
\t\t<AxSecurityEntryPointReference>
|
|
602
|
+
\t\t\t<Name>${targetMenuItemName}</Name>
|
|
603
|
+
\t\t\t<Grant>
|
|
604
|
+
\t\t\t\t<Read>Allow</Read>
|
|
605
|
+
\t\t\t\t<Update>Allow</Update>
|
|
606
|
+
\t\t\t\t<Create>Allow</Create>
|
|
607
|
+
\t\t\t\t<Delete>Allow</Delete>
|
|
608
|
+
\t\t\t</Grant>
|
|
609
|
+
\t\t\t<ObjectName>${targetMenuItemName}</ObjectName>
|
|
610
|
+
\t\t\t<ObjectType>MenuItemDisplay</ObjectType>
|
|
611
|
+
\t\t\t<Forms />
|
|
612
|
+
\t\t</AxSecurityEntryPointReference>
|
|
613
|
+
\t</EntryPoints>
|
|
614
|
+
\t<FormControlOverrides />
|
|
615
|
+
</AxSecurityPrivilege>`;
|
|
616
|
+
return `<!-- FILE 1: ${viewName}.xml (Read access) -->\n${viewXml}\n\n<!-- FILE 2: ${maintainName}.xml (Update/Create/Delete access) -->\n${maintainXml}`;
|
|
617
|
+
}
|
|
618
|
+
// Menu item XML pattern
|
|
619
|
+
function menuItemXmlTemplate(name, itemType, targetObject) {
|
|
620
|
+
const elemName = itemType === 'action' ? 'AxMenuItemAction'
|
|
621
|
+
: itemType === 'output' ? 'AxMenuItemOutput'
|
|
622
|
+
: 'AxMenuItemDisplay';
|
|
623
|
+
// ObjectType rules (from real D365FO XML files):
|
|
624
|
+
// action → always "Class"
|
|
625
|
+
// output → "Class" (default for controller pattern) or "SSRSReport"; never "Report"
|
|
626
|
+
// display → OMIT when targeting a Form (implicit default); use "Class" for analytics/class targets
|
|
627
|
+
let objectTypeXml;
|
|
628
|
+
if (itemType === 'action') {
|
|
629
|
+
objectTypeXml = '\n\t<ObjectType>Class</ObjectType>';
|
|
630
|
+
}
|
|
631
|
+
else if (itemType === 'output') {
|
|
632
|
+
objectTypeXml = '\n\t<ObjectType>Class</ObjectType>';
|
|
633
|
+
}
|
|
634
|
+
else {
|
|
635
|
+
// display — omit ObjectType (targets a form by default)
|
|
636
|
+
objectTypeXml = '';
|
|
637
|
+
}
|
|
638
|
+
return `<?xml version="1.0" encoding="utf-8"?>
|
|
639
|
+
<${elemName} xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="Microsoft.Dynamics.AX.Metadata.V1">
|
|
640
|
+
\t<Name>${name}</Name>
|
|
641
|
+
\t<Label>@TODO:LabelId</Label>
|
|
642
|
+
\t<Object>${targetObject}</Object>${objectTypeXml}
|
|
643
|
+
</${elemName}>`;
|
|
644
|
+
}
|
|
645
|
+
// SSRS Report Full pattern: DataContract + DP + Controller + TmpTable note
|
|
646
|
+
function ssrsReportFullTemplate(name) {
|
|
647
|
+
return `// ══════════════════════════════════════════════════════════════════
|
|
648
|
+
// SSRS Report: ${name}
|
|
649
|
+
// 5 objects required (use create_d365fo_file for each):
|
|
650
|
+
// 1. ${name}TmpTable — TempDB table (objectType="table", tableType="TempDB")
|
|
651
|
+
// 2. ${name}Contract — DataContract class (below)
|
|
652
|
+
// 3. ${name}DP — Data Provider class (below)
|
|
653
|
+
// 4. ${name}Controller — Report controller (below)
|
|
654
|
+
// 5. ${name}.xml — AxReport with RDL design (use generate_smart)
|
|
655
|
+
// ══════════════════════════════════════════════════════════════════
|
|
656
|
+
|
|
657
|
+
// ── 1. DataContract ─────────────────────────────────────────────────────────
|
|
658
|
+
/// <summary>
|
|
659
|
+
/// Data contract for the ${name} SSRS report. Holds filter parameters shown in the dialog.
|
|
660
|
+
/// </summary>
|
|
661
|
+
[DataContractAttribute]
|
|
662
|
+
public final class ${name}Contract
|
|
663
|
+
{
|
|
664
|
+
FromDate fromDate;
|
|
665
|
+
ToDate toDate;
|
|
666
|
+
|
|
667
|
+
[DataMemberAttribute('FromDate'),
|
|
668
|
+
SysOperationLabelAttribute(literalStr("From date"))]
|
|
669
|
+
public FromDate parmFromDate(FromDate _fromDate = fromDate)
|
|
670
|
+
{
|
|
671
|
+
fromDate = _fromDate;
|
|
672
|
+
return fromDate;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
[DataMemberAttribute('ToDate'),
|
|
676
|
+
SysOperationLabelAttribute(literalStr("To date"))]
|
|
677
|
+
public ToDate parmToDate(ToDate _toDate = toDate)
|
|
678
|
+
{
|
|
679
|
+
toDate = _toDate;
|
|
680
|
+
return toDate;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// ── 2. Data Provider ────────────────────────────────────────────────────────
|
|
685
|
+
/// <summary>
|
|
686
|
+
/// Data provider for the ${name} SSRS report. Fills the TmpTable used as the report dataset.
|
|
687
|
+
/// </summary>
|
|
688
|
+
[SRSReportParameterAttribute(classStr(${name}Contract))]
|
|
689
|
+
public class ${name}DP extends SRSReportDataProviderBase
|
|
690
|
+
{
|
|
691
|
+
${name}TmpTable tmpTable;
|
|
692
|
+
|
|
693
|
+
[SRSReportDataSetAttribute(tableStr(${name}TmpTable))]
|
|
694
|
+
public ${name}TmpTable get${name}TmpTable()
|
|
695
|
+
{
|
|
696
|
+
select * from tmpTable;
|
|
697
|
+
return tmpTable;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
public void processReport()
|
|
701
|
+
{
|
|
702
|
+
${name}Contract contract = this.parmDataContract() as ${name}Contract;
|
|
703
|
+
// ✅ Assign filter values to variables before using in WHERE
|
|
704
|
+
FromDate fromDate = contract.parmFromDate();
|
|
705
|
+
ToDate toDate = contract.parmToDate();
|
|
706
|
+
|
|
707
|
+
delete_from tmpTable;
|
|
708
|
+
|
|
709
|
+
insert_recordset tmpTable (Field1, Field2)
|
|
710
|
+
select Field1, Field2
|
|
711
|
+
from SourceTable
|
|
712
|
+
where SourceTable.TransDate >= fromDate
|
|
713
|
+
&& SourceTable.TransDate <= toDate;
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
// ── 3. Controller ────────────────────────────────────────────────────────────
|
|
718
|
+
/// <summary>
|
|
719
|
+
/// Controller that binds the ${name} SSRS report to its contract and launches the dialog.
|
|
720
|
+
/// </summary>
|
|
721
|
+
public class ${name}Controller extends SrsReportRunController
|
|
722
|
+
{
|
|
723
|
+
public static void main(Args _args)
|
|
724
|
+
{
|
|
725
|
+
${name}Controller controller = new ${name}Controller();
|
|
726
|
+
controller.parmReportName(ssrsReportStr(${name}, Design));
|
|
727
|
+
controller.parmArgs(_args);
|
|
728
|
+
controller.startOperation();
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
protected void preRunModifyContract()
|
|
732
|
+
{
|
|
733
|
+
super();
|
|
734
|
+
// Modify contract defaults here if needed
|
|
735
|
+
}
|
|
736
|
+
}`;
|
|
737
|
+
}
|
|
738
|
+
// SysTableLookup pattern
|
|
739
|
+
function lookupFormTemplate(name) {
|
|
740
|
+
return `/// <summary>
|
|
741
|
+
/// Lookup for ${name} field.
|
|
742
|
+
/// Shows records from ${name} table with a filtered list.
|
|
743
|
+
/// Call this method from the field's lookup() override or a form extension.
|
|
744
|
+
/// </summary>
|
|
745
|
+
/// <param name="_formControl">The form string control that triggered the lookup.</param>
|
|
746
|
+
public static void lookup${name}(FormStringControl _formControl)
|
|
747
|
+
{
|
|
748
|
+
SysTableLookup sysTableLookup = SysTableLookup::newParameters(
|
|
749
|
+
tableNum(${name}),
|
|
750
|
+
_formControl);
|
|
751
|
+
|
|
752
|
+
// Add fields to display in the lookup grid
|
|
753
|
+
sysTableLookup.addLookupfield(fieldNum(${name}, Id)); // key field first
|
|
754
|
+
sysTableLookup.addLookupfield(fieldNum(${name}, Name)); // descriptive field
|
|
755
|
+
|
|
756
|
+
// Optional: add a filter range
|
|
757
|
+
// Query query = new Query();
|
|
758
|
+
// QueryBuildDataSource qbds = query.addDataSource(tableNum(${name}));
|
|
759
|
+
// SysQuery::findOrCreateRange(qbds, fieldNum(${name}, Active)).value('1');
|
|
760
|
+
// sysTableLookup.parmQuery(query);
|
|
761
|
+
|
|
762
|
+
sysTableLookup.performFormLookup();
|
|
763
|
+
}`;
|
|
764
|
+
}
|
|
765
|
+
// Dialog Box pattern
|
|
766
|
+
function dialogBoxTemplate(name) {
|
|
767
|
+
return `/// <summary>
|
|
768
|
+
/// Dialog for ${name}. Uses D365FO Dialog API without a dedicated form.
|
|
769
|
+
/// Call ${name}Dialog::prompt() to show the dialog and retrieve user input.
|
|
770
|
+
/// </summary>
|
|
771
|
+
public class ${name}Dialog
|
|
772
|
+
{
|
|
773
|
+
private Dialog dialog;
|
|
774
|
+
private DialogField dlgField1;
|
|
775
|
+
private DialogField dlgField2;
|
|
776
|
+
|
|
777
|
+
// ── Constructor ─────────────────────────────────────────────────────
|
|
778
|
+
private void new()
|
|
779
|
+
{
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
public static ${name}Dialog construct()
|
|
783
|
+
{
|
|
784
|
+
${name}Dialog d = new ${name}Dialog();
|
|
785
|
+
d.initDialog();
|
|
786
|
+
return d;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
private void initDialog()
|
|
790
|
+
{
|
|
791
|
+
dialog = new Dialog("@MyModel:${name}DialogCaption");
|
|
792
|
+
dialog.addText("@MyModel:${name}DialogDescription");
|
|
793
|
+
|
|
794
|
+
// Add fields — use EDT names for automatic lookup/validation
|
|
795
|
+
dlgField1 = dialog.addField(extendedTypeStr(TransDate), "@MyModel:DateLabel");
|
|
796
|
+
dlgField2 = dialog.addField(extendedTypeStr(Description), "@MyModel:DescriptionLabel");
|
|
797
|
+
|
|
798
|
+
// Set defaults
|
|
799
|
+
dlgField1.value(systemDateGet());
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
/// <summary>
|
|
803
|
+
/// Shows the dialog. Returns true if the user clicked OK.
|
|
804
|
+
/// </summary>
|
|
805
|
+
public boolean prompt()
|
|
806
|
+
{
|
|
807
|
+
return dialog.run();
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
/// <summary>Gets the date the user selected.</summary>
|
|
811
|
+
public TransDate parmDate()
|
|
812
|
+
{
|
|
813
|
+
return dlgField1.value();
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
/// <summary>Gets the description the user entered.</summary>
|
|
817
|
+
public Description parmDescription()
|
|
818
|
+
{
|
|
819
|
+
return dlgField2.value();
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
/// <summary>
|
|
823
|
+
/// Convenience method: show dialog and return true if user confirmed.
|
|
824
|
+
/// </summary>
|
|
825
|
+
public static boolean run${name}(TransDate _date, Description _desc)
|
|
826
|
+
{
|
|
827
|
+
${name}Dialog d = ${name}Dialog::construct();
|
|
828
|
+
if (d.prompt())
|
|
829
|
+
{
|
|
830
|
+
// Process d.parmDate() / d.parmDescription()
|
|
831
|
+
return true;
|
|
832
|
+
}
|
|
833
|
+
return false;
|
|
834
|
+
}
|
|
835
|
+
}`;
|
|
836
|
+
}
|
|
837
|
+
// DimensionDefaultingController pattern
|
|
838
|
+
function dimensionControllerTemplate(name) {
|
|
839
|
+
return `/// <summary>
|
|
840
|
+
/// Handles financial dimension defaulting for ${name} form.
|
|
841
|
+
/// Add this to the form's init() and datasource active() methods.
|
|
842
|
+
/// </summary>
|
|
843
|
+
public class ${name}DimensionController
|
|
844
|
+
{
|
|
845
|
+
private DimensionDefaultingController dimensionDefaultingController;
|
|
846
|
+
private FormRun formRun;
|
|
847
|
+
private ${name} callerRecord;
|
|
848
|
+
|
|
849
|
+
private void new()
|
|
850
|
+
{
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
public static ${name}DimensionController construct(
|
|
854
|
+
FormRun _formRun,
|
|
855
|
+
${name} _record)
|
|
856
|
+
{
|
|
857
|
+
${name}DimensionController ctrl = new ${name}DimensionController();
|
|
858
|
+
ctrl.formRun = _formRun;
|
|
859
|
+
ctrl.callerRecord = _record;
|
|
860
|
+
ctrl.initController();
|
|
861
|
+
return ctrl;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
private void initController()
|
|
865
|
+
{
|
|
866
|
+
// Create controller bound to the DefaultDimension field on the datasource
|
|
867
|
+
dimensionDefaultingController =
|
|
868
|
+
DimensionDefaultingController::constructInTabWithValues(
|
|
869
|
+
true, // show account
|
|
870
|
+
true, // show dimensions
|
|
871
|
+
0, // location (0 = auto)
|
|
872
|
+
formRun,
|
|
873
|
+
formDataSourceStr(${name}, DefaultDimension), // datasource field binding
|
|
874
|
+
formControlStr(${name}Form, DimensionDefaultingControl)); // segment control
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
/// <summary>
|
|
878
|
+
/// Call from datasource active() to refresh dimension values when record changes.
|
|
879
|
+
/// </summary>
|
|
880
|
+
public void datasourceActive()
|
|
881
|
+
{
|
|
882
|
+
dimensionDefaultingController.activated();
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
/// <summary>
|
|
886
|
+
/// Call from form close() to clean up resources.
|
|
887
|
+
/// </summary>
|
|
888
|
+
public void formClosing()
|
|
889
|
+
{
|
|
890
|
+
dimensionDefaultingController.deleted();
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
// ── Usage in form classDeclaration / init() ──────────────────────────────
|
|
895
|
+
// [Form]
|
|
896
|
+
// public class ${name}Form extends FormRun
|
|
897
|
+
// {
|
|
898
|
+
// ${name}DimensionController dimCtrl;
|
|
899
|
+
//
|
|
900
|
+
// public void init()
|
|
901
|
+
// {
|
|
902
|
+
// super();
|
|
903
|
+
// dimCtrl = ${name}DimensionController::construct(this, ${name}_ds.getFirst());
|
|
904
|
+
// }
|
|
905
|
+
// }
|
|
906
|
+
//
|
|
907
|
+
// ── Usage in datasource active() ────────────────────────────────────────
|
|
908
|
+
// public int active()
|
|
909
|
+
// {
|
|
910
|
+
// int ret = super();
|
|
911
|
+
// dimCtrl.datasourceActive();
|
|
912
|
+
// return ret;
|
|
913
|
+
// }`;
|
|
914
|
+
}
|
|
915
|
+
// NumberSeqFormHandler pattern
|
|
916
|
+
function numberSeqHandlerTemplate(name) {
|
|
917
|
+
return `/// <summary>
|
|
918
|
+
/// Integrates number sequence auto-generation into the ${name} form.
|
|
919
|
+
/// This class handles the NumberSeqFormHandler setup in the form.
|
|
920
|
+
/// Add init() call to form init(), and numSeqFormHandler reference to classDeclaration.
|
|
921
|
+
/// </summary>
|
|
922
|
+
// ── Step 1: Form classDeclaration ───────────────────────────────────────
|
|
923
|
+
// [Form]
|
|
924
|
+
// public class ${name}Form extends FormRun
|
|
925
|
+
// {
|
|
926
|
+
// NumberSeqFormHandler numSeqFormHandler;
|
|
927
|
+
// }
|
|
928
|
+
|
|
929
|
+
// ── Step 2: Form init() ─────────────────────────────────────────────────
|
|
930
|
+
// public void init()
|
|
931
|
+
// {
|
|
932
|
+
// super();
|
|
933
|
+
// // Hook number sequence handler to the ${name}Id field
|
|
934
|
+
// numSeqFormHandler = NumberSeqFormHandler::newForm(
|
|
935
|
+
// ${name}Parameters::numRef${name}Id().NumberSequenceId, // number sequence reference (RefRecId)
|
|
936
|
+
// element, // FormRun
|
|
937
|
+
// tableNum(${name}), // table
|
|
938
|
+
// fieldNum(${name}, ${name}Id)); // field to fill
|
|
939
|
+
// }
|
|
940
|
+
|
|
941
|
+
// ── Step 3: datasource create() override ────────────────────────────────
|
|
942
|
+
// public void create(boolean _append = false)
|
|
943
|
+
// {
|
|
944
|
+
// super(_append);
|
|
945
|
+
// numSeqFormHandler.formMethodDataSourceCreatePre();
|
|
946
|
+
// }
|
|
947
|
+
// public void write()
|
|
948
|
+
// {
|
|
949
|
+
// super();
|
|
950
|
+
// numSeqFormHandler.formMethodDataSourceWrite();
|
|
951
|
+
// }
|
|
952
|
+
// public void delete()
|
|
953
|
+
// {
|
|
954
|
+
// super();
|
|
955
|
+
// numSeqFormHandler.formMethodDataSourceDelete();
|
|
956
|
+
// }
|
|
957
|
+
|
|
958
|
+
// ── Step 4: NumberSeqApplicationModule subclass (the module class) ────────
|
|
959
|
+
/// <summary>
|
|
960
|
+
/// Subclass of NumberSeqApplicationModule that registers the ${name}Id number sequence.
|
|
961
|
+
/// Add a NumberSeqModule enum value for ${name} and register this class via an event
|
|
962
|
+
/// handler on NumberSeqGlobal.initModules() so loadModule() is called at startup.
|
|
963
|
+
/// </summary>
|
|
964
|
+
public class NumberSeqModule${name} extends NumberSeqApplicationModule
|
|
965
|
+
{
|
|
966
|
+
protected void loadModule()
|
|
967
|
+
{
|
|
968
|
+
NumberSeqDatatype datatype = NumberSeqDatatype::construct();
|
|
969
|
+
datatype.parmDatatypeId(extendedTypeNum(${name}Id));
|
|
970
|
+
datatype.parmReferenceHelp(literalStr("${name} identifier"));
|
|
971
|
+
datatype.parmWizardIsContinuous(false);
|
|
972
|
+
datatype.parmWizardIsManual(NoYes::No);
|
|
973
|
+
datatype.parmWizardIsChangeDownAllowed(NoYes::Yes);
|
|
974
|
+
datatype.parmWizardIsChangeUpAllowed(NoYes::Yes);
|
|
975
|
+
datatype.parmWizardHighest(0);
|
|
976
|
+
datatype.parmSortField(1);
|
|
977
|
+
datatype.addParameterType(NumberSeqParameterType::DataArea, true, false);
|
|
978
|
+
this.create(datatype);
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
public NumberSeqModule numberSeqModule()
|
|
982
|
+
{
|
|
983
|
+
return NumberSeqModule::${name};
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
// ── Step 5: CompanyInfo.numRef${name}Id() static method via CoC ──────────
|
|
988
|
+
[ExtensionOf(tableStr(CompanyInfo))]
|
|
989
|
+
final class CompanyInfo_${name}_Extension
|
|
990
|
+
{
|
|
991
|
+
/// <summary>Gets the number sequence reference for ${name}Id.</summary>
|
|
992
|
+
public static NumberSequenceReference numRef${name}Id()
|
|
993
|
+
{
|
|
994
|
+
return NumberSeqReference::findReference(extendedTypeNum(${name}Id));
|
|
995
|
+
}
|
|
996
|
+
}`;
|
|
997
|
+
}
|
|
998
|
+
// Display Menu Controller pattern
|
|
999
|
+
function displayMenuControllerTemplate(name) {
|
|
1000
|
+
return `/// <summary>
|
|
1001
|
+
/// Menu controller for ${name}. Handles Args-based routing when a menu item
|
|
1002
|
+
/// points to this class instead of directly to a form or report.
|
|
1003
|
+
/// </summary>
|
|
1004
|
+
public class ${name}Controller extends MenuFunction
|
|
1005
|
+
{
|
|
1006
|
+
Args args;
|
|
1007
|
+
MenuFunction menuFunction;
|
|
1008
|
+
|
|
1009
|
+
/// <summary>
|
|
1010
|
+
/// Entry point — called by the menu item.
|
|
1011
|
+
/// </summary>
|
|
1012
|
+
public static void main(Args _args)
|
|
1013
|
+
{
|
|
1014
|
+
${name}Controller controller = new ${name}Controller();
|
|
1015
|
+
controller.args = _args;
|
|
1016
|
+
controller.run();
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
private void run()
|
|
1020
|
+
{
|
|
1021
|
+
// Determine which form/report to open based on caller context
|
|
1022
|
+
FormName targetForm;
|
|
1023
|
+
|
|
1024
|
+
// Example: route based on record type or calling context
|
|
1025
|
+
if (args && args.record() && args.record().TableId == tableNum(SalesTable))
|
|
1026
|
+
{
|
|
1027
|
+
targetForm = formStr(SalesTable);
|
|
1028
|
+
}
|
|
1029
|
+
else
|
|
1030
|
+
{
|
|
1031
|
+
targetForm = formStr(${name}Form);
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
menuFunction = new MenuFunction(targetForm, MenuItemType::Display);
|
|
1035
|
+
menuFunction.run(args);
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
/// <summary>
|
|
1039
|
+
/// Override canRun() to control when this menu item is available.
|
|
1040
|
+
/// </summary>
|
|
1041
|
+
public boolean canRun(Args _args)
|
|
1042
|
+
{
|
|
1043
|
+
// Return false to disable the menu item in certain contexts
|
|
1044
|
+
if (!_args || !_args.record())
|
|
1045
|
+
{
|
|
1046
|
+
return false;
|
|
1047
|
+
}
|
|
1048
|
+
return true;
|
|
1049
|
+
}
|
|
1050
|
+
}`;
|
|
1051
|
+
}
|
|
1052
|
+
// Data Entity with Staging (DMF import) pattern
|
|
1053
|
+
function dataEntityStagingTemplate(name) {
|
|
1054
|
+
return `// ══════════════════════════════════════════════════════════════════════════
|
|
1055
|
+
// Data Entity with Staging Table: ${name}
|
|
1056
|
+
// 3 objects required (use create_d365fo_file for each):
|
|
1057
|
+
// 1. ${name}StagingTable — TempDB staging table
|
|
1058
|
+
// 2. ${name}Entity — Data entity (AxDataEntityView)
|
|
1059
|
+
// 3. ${name}EntityService — Optional: AIF service class
|
|
1060
|
+
// ══════════════════════════════════════════════════════════════════════════
|
|
1061
|
+
|
|
1062
|
+
// ── Object 1: Staging table ${name}Staging ─────────────────────────────────
|
|
1063
|
+
// create_d365fo_file(objectType="table", objectName="${name}Staging", xmlContent=...)
|
|
1064
|
+
// Set: TableType=TempDB (NOT RegularTable), TableGroup=Main
|
|
1065
|
+
// Fields mirror the entity's public fields exactly (same names, same EDTs)
|
|
1066
|
+
|
|
1067
|
+
// ── Object 2: Data entity ${name}Entity ──────────────────────────────────
|
|
1068
|
+
// AxDataEntityView XML — key properties:
|
|
1069
|
+
// <IsPublic>Yes</IsPublic>
|
|
1070
|
+
// <PublicEntityName>${name}</PublicEntityName>
|
|
1071
|
+
// <PublicCollectionName>${name}s</PublicCollectionName>
|
|
1072
|
+
// <StagingTable>${name}Staging</StagingTable>
|
|
1073
|
+
// <DataManagementEnabled>Yes</DataManagementEnabled>
|
|
1074
|
+
// <DataManagementStagingTable>${name}Staging</DataManagementStagingTable>
|
|
1075
|
+
|
|
1076
|
+
// ── Object 3: Entity class (copyCustomStagingToTarget override) ───────────
|
|
1077
|
+
/// <summary>
|
|
1078
|
+
/// ${name} data entity. Handles DMF import via staging table.
|
|
1079
|
+
/// </summary>
|
|
1080
|
+
public class ${name}EntityClass extends DMFEntityBase
|
|
1081
|
+
{
|
|
1082
|
+
/// <summary>
|
|
1083
|
+
/// Maps staging table records to the target table during DMF import.
|
|
1084
|
+
/// Called for each staging record after validation.
|
|
1085
|
+
/// </summary>
|
|
1086
|
+
public boolean copyCustomStagingToTarget(DMFDefinitionGroupExecution _dmfDefinitionGroupExecution)
|
|
1087
|
+
{
|
|
1088
|
+
${name}Staging staging;
|
|
1089
|
+
${name} target;
|
|
1090
|
+
boolean ret = true;
|
|
1091
|
+
|
|
1092
|
+
// Process each staging record
|
|
1093
|
+
while select staging
|
|
1094
|
+
where staging.DefinitionGroup == _dmfDefinitionGroupExecution.DefinitionGroup
|
|
1095
|
+
&& staging.ExecutionId == _dmfDefinitionGroupExecution.ExecutionId
|
|
1096
|
+
&& staging.TransferStatus == DMFTransferStatus::NotStarted
|
|
1097
|
+
{
|
|
1098
|
+
try
|
|
1099
|
+
{
|
|
1100
|
+
ttsbegin;
|
|
1101
|
+
|
|
1102
|
+
// Map staging → target
|
|
1103
|
+
target.clear();
|
|
1104
|
+
target.initValue();
|
|
1105
|
+
target.${name}Id = staging.${name}Id;
|
|
1106
|
+
target.Description = staging.Description;
|
|
1107
|
+
// ... map remaining fields
|
|
1108
|
+
|
|
1109
|
+
if (!target.validateWrite())
|
|
1110
|
+
{
|
|
1111
|
+
staging.TransferStatus = DMFTransferStatus::Error;
|
|
1112
|
+
}
|
|
1113
|
+
else
|
|
1114
|
+
{
|
|
1115
|
+
target.write();
|
|
1116
|
+
staging.TransferStatus = DMFTransferStatus::Completed;
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
staging.update();
|
|
1120
|
+
ttscommit;
|
|
1121
|
+
}
|
|
1122
|
+
catch (Exception::UpdateConflict)
|
|
1123
|
+
{
|
|
1124
|
+
if (appl.ttsLevel() == 0)
|
|
1125
|
+
{
|
|
1126
|
+
retry;
|
|
1127
|
+
}
|
|
1128
|
+
staging.TransferStatus = DMFTransferStatus::Error;
|
|
1129
|
+
staging.update();
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
return ret;
|
|
1133
|
+
}
|
|
1134
|
+
}`;
|
|
1135
|
+
}
|
|
1136
|
+
// AIF/OData Service class pattern
|
|
1137
|
+
function serviceClassAisTemplate(name) {
|
|
1138
|
+
return `/// <summary>
|
|
1139
|
+
/// OData/AIF service class for ${name}.
|
|
1140
|
+
/// Exposes CRUD operations consumable via OData v4 (D365FO standard endpoint).
|
|
1141
|
+
/// Register in Services node of the model's AxService XML.
|
|
1142
|
+
/// </summary>
|
|
1143
|
+
public class ${name}Service
|
|
1144
|
+
{
|
|
1145
|
+
/// <summary>
|
|
1146
|
+
/// Creates a new ${name} record.
|
|
1147
|
+
/// </summary>
|
|
1148
|
+
[SysEntryPointAttribute(true)]
|
|
1149
|
+
public ${name}Id create(${name}Contract _contract)
|
|
1150
|
+
{
|
|
1151
|
+
${name} record;
|
|
1152
|
+
|
|
1153
|
+
ttsbegin;
|
|
1154
|
+
record.initValue();
|
|
1155
|
+
record.${name}Id = _contract.parm${name}Id();
|
|
1156
|
+
record.Description = _contract.parmDescription();
|
|
1157
|
+
|
|
1158
|
+
if (!record.validateWrite())
|
|
1159
|
+
{
|
|
1160
|
+
throw error("@MyModel:ValidationFailed");
|
|
1161
|
+
}
|
|
1162
|
+
record.insert();
|
|
1163
|
+
ttscommit;
|
|
1164
|
+
|
|
1165
|
+
return record.${name}Id;
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
/// <summary>
|
|
1169
|
+
/// Updates an existing ${name} record.
|
|
1170
|
+
/// </summary>
|
|
1171
|
+
[SysEntryPointAttribute(true)]
|
|
1172
|
+
public void update(${name}Contract _contract)
|
|
1173
|
+
{
|
|
1174
|
+
${name} record;
|
|
1175
|
+
${name}Id recordId = _contract.parm${name}Id();
|
|
1176
|
+
|
|
1177
|
+
select forupdate record
|
|
1178
|
+
where record.${name}Id == recordId;
|
|
1179
|
+
|
|
1180
|
+
if (!record.RecId)
|
|
1181
|
+
{
|
|
1182
|
+
throw error(strFmt("@SYS23771", recordId)); // "Record %1 not found"
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
ttsbegin;
|
|
1186
|
+
record.Description = _contract.parmDescription();
|
|
1187
|
+
record.update();
|
|
1188
|
+
ttscommit;
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
/// <summary>
|
|
1192
|
+
/// Deletes a ${name} record.
|
|
1193
|
+
/// </summary>
|
|
1194
|
+
[SysEntryPointAttribute(true)]
|
|
1195
|
+
public void delete(${name}Id _id)
|
|
1196
|
+
{
|
|
1197
|
+
${name} record;
|
|
1198
|
+
|
|
1199
|
+
select forupdate record
|
|
1200
|
+
where record.${name}Id == _id;
|
|
1201
|
+
|
|
1202
|
+
if (record.RecId)
|
|
1203
|
+
{
|
|
1204
|
+
ttsbegin;
|
|
1205
|
+
record.delete();
|
|
1206
|
+
ttscommit;
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
/// <summary>
|
|
1211
|
+
/// Reads a ${name} record and returns a contract.
|
|
1212
|
+
/// </summary>
|
|
1213
|
+
[SysEntryPointAttribute(false)]
|
|
1214
|
+
public ${name}Contract read(${name}Id _id)
|
|
1215
|
+
{
|
|
1216
|
+
${name} record = ${name}::find(_id);
|
|
1217
|
+
${name}Contract contract = new ${name}Contract();
|
|
1218
|
+
|
|
1219
|
+
if (!record.RecId)
|
|
1220
|
+
{
|
|
1221
|
+
throw error(strFmt("@SYS23771", _id));
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
contract.parm${name}Id(record.${name}Id);
|
|
1225
|
+
contract.parmDescription(record.Description);
|
|
1226
|
+
return contract;
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
// ── Contract class for the service ─────────────────────────────────────────
|
|
1231
|
+
/// <summary>
|
|
1232
|
+
/// Data contract for ${name} service operations.
|
|
1233
|
+
/// </summary>
|
|
1234
|
+
[DataContractAttribute]
|
|
1235
|
+
public class ${name}Contract
|
|
1236
|
+
{
|
|
1237
|
+
private ${name}Id ${name}Id;
|
|
1238
|
+
private Description description;
|
|
1239
|
+
|
|
1240
|
+
[DataMemberAttribute('${name}Id')]
|
|
1241
|
+
public ${name}Id parm${name}Id(${name}Id _v = ${name}Id)
|
|
1242
|
+
{
|
|
1243
|
+
${name}Id = _v;
|
|
1244
|
+
return ${name}Id;
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
[DataMemberAttribute('Description')]
|
|
1248
|
+
public Description parmDescription(Description _v = description)
|
|
1249
|
+
{
|
|
1250
|
+
description = _v;
|
|
1251
|
+
return description;
|
|
1252
|
+
}
|
|
1253
|
+
}`;
|
|
1254
|
+
}
|
|
1255
|
+
// Business Event pattern: contract + event class
|
|
1256
|
+
function businessEventTemplate(name) {
|
|
1257
|
+
return `// ══════════════════════════════════════════════════════════════════
|
|
1258
|
+
// Business Event: ${name}
|
|
1259
|
+
// 2 classes: Contract (payload) + Event (trigger).
|
|
1260
|
+
// After deployment, appears in: System Admin > Set up > Business events > Catalog
|
|
1261
|
+
// ══════════════════════════════════════════════════════════════════
|
|
1262
|
+
|
|
1263
|
+
// ── 1. Business Event Contract (payload definition) ─────────────────────
|
|
1264
|
+
/// <summary>
|
|
1265
|
+
/// Contract defining the payload for the ${name} business event.
|
|
1266
|
+
/// Properties here become the JSON schema available to Power Automate / Service Bus subscribers.
|
|
1267
|
+
/// </summary>
|
|
1268
|
+
[DataContractAttribute]
|
|
1269
|
+
public final class ${name}BusinessEventContract extends BusinessEventsContract
|
|
1270
|
+
{
|
|
1271
|
+
private CustAccount custAccount;
|
|
1272
|
+
private Name custName;
|
|
1273
|
+
private str documentId;
|
|
1274
|
+
|
|
1275
|
+
/// <summary>
|
|
1276
|
+
/// Creates a new contract from a source record.
|
|
1277
|
+
/// </summary>
|
|
1278
|
+
public static ${name}BusinessEventContract newFromRecord(/* SourceTable _record */)
|
|
1279
|
+
{
|
|
1280
|
+
${name}BusinessEventContract contract = new ${name}BusinessEventContract();
|
|
1281
|
+
|
|
1282
|
+
// Map source record fields to contract properties
|
|
1283
|
+
// contract.parmCustAccount(_record.CustAccount);
|
|
1284
|
+
// contract.parmCustName(_record.custName());
|
|
1285
|
+
// contract.parmDocumentId(_record.DocumentId);
|
|
1286
|
+
|
|
1287
|
+
return contract;
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
[DataMemberAttribute('CustAccount'),
|
|
1291
|
+
BusinessEventsDataMemberAttribute('@AccountsReceivable:CustAccount')]
|
|
1292
|
+
public CustAccount parmCustAccount(CustAccount _v = custAccount)
|
|
1293
|
+
{
|
|
1294
|
+
custAccount = _v;
|
|
1295
|
+
return custAccount;
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
[DataMemberAttribute('CustName'),
|
|
1299
|
+
BusinessEventsDataMemberAttribute('@SYS7399')] // Customer name
|
|
1300
|
+
public Name parmCustName(Name _v = custName)
|
|
1301
|
+
{
|
|
1302
|
+
custName = _v;
|
|
1303
|
+
return custName;
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
[DataMemberAttribute('DocumentId'),
|
|
1307
|
+
BusinessEventsDataMemberAttribute('@SYS3252')]
|
|
1308
|
+
public str parmDocumentId(str _v = documentId)
|
|
1309
|
+
{
|
|
1310
|
+
documentId = _v;
|
|
1311
|
+
return documentId;
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
// ── 2. Business Event class (trigger) ───────────────────────────────────
|
|
1316
|
+
/// <summary>
|
|
1317
|
+
/// Business event triggered when ${name} occurs.
|
|
1318
|
+
/// Activate in: System Admin > Set up > Business events > Catalog.
|
|
1319
|
+
/// </summary>
|
|
1320
|
+
[BusinessEventsAttribute('${name}BusinessEvent',
|
|
1321
|
+
'@MyModel:${name}BusinessEventDescription',
|
|
1322
|
+
ModuleAxapta::SalesOrder)] // ← change to your module
|
|
1323
|
+
public final class ${name}BusinessEvent extends BusinessEventsBase
|
|
1324
|
+
{
|
|
1325
|
+
private /* SourceTable */ Common sourceRecord;
|
|
1326
|
+
|
|
1327
|
+
/// <summary>
|
|
1328
|
+
/// Constructs the business event from a source record.
|
|
1329
|
+
/// </summary>
|
|
1330
|
+
public static ${name}BusinessEvent newFromRecord(/* SourceTable */ Common _record)
|
|
1331
|
+
{
|
|
1332
|
+
${name}BusinessEvent businessEvent = new ${name}BusinessEvent();
|
|
1333
|
+
businessEvent.sourceRecord = _record;
|
|
1334
|
+
return businessEvent;
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
/// <summary>
|
|
1338
|
+
/// Builds the contract payload sent to subscribers.
|
|
1339
|
+
/// </summary>
|
|
1340
|
+
protected BusinessEventsContract buildContract()
|
|
1341
|
+
{
|
|
1342
|
+
return ${name}BusinessEventContract::newFromRecord(this.sourceRecord);
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
// ── How to trigger this event ────────────────────────────────────
|
|
1346
|
+
// In your business logic (e.g. after posting, confirmation, etc.):
|
|
1347
|
+
//
|
|
1348
|
+
// ${name}BusinessEvent businessEvent =
|
|
1349
|
+
// ${name}BusinessEvent::newFromRecord(myRecord);
|
|
1350
|
+
// businessEvent.send(); // ← sends to all activated endpoints
|
|
1351
|
+
}`;
|
|
1352
|
+
}
|
|
1353
|
+
// Custom Telemetry pattern
|
|
1354
|
+
function customTelemetryTemplate(name) {
|
|
1355
|
+
return `/// <summary>
|
|
1356
|
+
/// Custom telemetry signal for ${name}.
|
|
1357
|
+
/// Emits events to Application Insights via the monitoring framework.
|
|
1358
|
+
/// </summary>
|
|
1359
|
+
/// <remarks>
|
|
1360
|
+
/// Prerequisites:
|
|
1361
|
+
/// 1. Enable Monitoring and telemetry in Feature management
|
|
1362
|
+
/// 2. Configure Application Insights connection string in LCS / Power Platform admin
|
|
1363
|
+
/// 3. After deployment, signals appear in App Insights → customEvents / traces
|
|
1364
|
+
/// </remarks>
|
|
1365
|
+
public final class ${name}Telemetry
|
|
1366
|
+
{
|
|
1367
|
+
/// <summary>
|
|
1368
|
+
/// Emits a custom event to Application Insights with structured properties.
|
|
1369
|
+
/// </summary>
|
|
1370
|
+
public static void emitEvent(
|
|
1371
|
+
str _eventName,
|
|
1372
|
+
str _contextId = '',
|
|
1373
|
+
str _detail = '')
|
|
1374
|
+
{
|
|
1375
|
+
SysApplicationInsightsEventLogger logger =
|
|
1376
|
+
SysApplicationInsightsEventLogger::construct();
|
|
1377
|
+
|
|
1378
|
+
// Set custom properties (appear as customDimensions in KQL)
|
|
1379
|
+
Map customProperties = new Map(Types::String, Types::String);
|
|
1380
|
+
customProperties.insert('EventName', _eventName);
|
|
1381
|
+
customProperties.insert('ContextId', _contextId);
|
|
1382
|
+
customProperties.insert('Detail', _detail);
|
|
1383
|
+
customProperties.insert('UserId', curUserId());
|
|
1384
|
+
customProperties.insert('Company', curExt());
|
|
1385
|
+
|
|
1386
|
+
logger.logCustomEvent('${name}', customProperties);
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
/// <summary>
|
|
1390
|
+
/// Emits a custom metric (numeric measurement) to Application Insights.
|
|
1391
|
+
/// </summary>
|
|
1392
|
+
public static void emitMetric(
|
|
1393
|
+
str _metricName,
|
|
1394
|
+
real _value,
|
|
1395
|
+
str _dimension = '')
|
|
1396
|
+
{
|
|
1397
|
+
SysApplicationInsightsMetricLogger metricLogger =
|
|
1398
|
+
SysApplicationInsightsMetricLogger::construct();
|
|
1399
|
+
|
|
1400
|
+
Map customDimensions = new Map(Types::String, Types::String);
|
|
1401
|
+
customDimensions.insert('Dimension', _dimension);
|
|
1402
|
+
customDimensions.insert('Company', curExt());
|
|
1403
|
+
|
|
1404
|
+
metricLogger.logMetricValue(_metricName, _value, customDimensions);
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
// ── Usage examples ──────────────────────────────────────────────────────
|
|
1409
|
+
// After a batch job completes:
|
|
1410
|
+
// ${name}Telemetry::emitEvent('BatchCompleted', batchId, strFmt('%1 records processed', count));
|
|
1411
|
+
//
|
|
1412
|
+
// Track processing duration:
|
|
1413
|
+
// ${name}Telemetry::emitMetric('ProcessingDurationMs', durationMs, 'OrderImport');
|
|
1414
|
+
//
|
|
1415
|
+
// KQL query to find events in Application Insights:
|
|
1416
|
+
// customEvents
|
|
1417
|
+
// | where name == "${name}"
|
|
1418
|
+
// | extend EventName = tostring(customDimensions.EventName)
|
|
1419
|
+
// | where EventName == "BatchCompleted"
|
|
1420
|
+
// | project timestamp, EventName, tostring(customDimensions.ContextId)`;
|
|
1421
|
+
}
|
|
1422
|
+
// Feature Class pattern
|
|
1423
|
+
function featureClassTemplate(name) {
|
|
1424
|
+
return `/// <summary>
|
|
1425
|
+
/// Feature management class for ${name}.
|
|
1426
|
+
/// Registers in the Feature Management workspace automatically.
|
|
1427
|
+
/// Enable/disable at runtime without redeployment.
|
|
1428
|
+
/// </summary>
|
|
1429
|
+
[FeatureClassAttribute]
|
|
1430
|
+
public final class ${name}Feature
|
|
1431
|
+
{
|
|
1432
|
+
private static ${name}Feature instance = new ${name}Feature();
|
|
1433
|
+
|
|
1434
|
+
/// <summary>
|
|
1435
|
+
/// Display label shown in Feature Management workspace.
|
|
1436
|
+
/// </summary>
|
|
1437
|
+
public static str label()
|
|
1438
|
+
{
|
|
1439
|
+
return "@MyModel:${name}FeatureLabel";
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
/// <summary>
|
|
1443
|
+
/// Detailed description shown when expanding the feature in the workspace.
|
|
1444
|
+
/// </summary>
|
|
1445
|
+
public static str description()
|
|
1446
|
+
{
|
|
1447
|
+
return "@MyModel:${name}FeatureDescription";
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
/// <summary>
|
|
1451
|
+
/// Module this feature belongs to (shown as category in Feature Management).
|
|
1452
|
+
/// </summary>
|
|
1453
|
+
public static str module()
|
|
1454
|
+
{
|
|
1455
|
+
return "@MyModel:ModuleName";
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
/// <summary>
|
|
1459
|
+
/// Whether this feature is enabled by default for new environments.
|
|
1460
|
+
/// Return false for features that need explicit opt-in.
|
|
1461
|
+
/// </summary>
|
|
1462
|
+
public static boolean isEnabledByDefault()
|
|
1463
|
+
{
|
|
1464
|
+
return false;
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
// ── Usage in X++ code ───────────────────────────────────────────────
|
|
1468
|
+
// Cache the check result — never call isFeatureEnabled in a loop:
|
|
1469
|
+
//
|
|
1470
|
+
// boolean featureEnabled = FeatureStateProvider::isFeatureEnabled(
|
|
1471
|
+
// classStr(${name}Feature));
|
|
1472
|
+
//
|
|
1473
|
+
// if (featureEnabled)
|
|
1474
|
+
// {
|
|
1475
|
+
// // New behavior
|
|
1476
|
+
// }
|
|
1477
|
+
// else
|
|
1478
|
+
// {
|
|
1479
|
+
// // Legacy behavior
|
|
1480
|
+
// }
|
|
1481
|
+
}`;
|
|
1482
|
+
}
|
|
1483
|
+
// Composite Entity pattern
|
|
1484
|
+
function compositeEntityTemplate(name) {
|
|
1485
|
+
return `// ══════════════════════════════════════════════════════════════════
|
|
1486
|
+
// Composite Data Entity: ${name}
|
|
1487
|
+
// Combines header + line entities for hierarchical data import/export.
|
|
1488
|
+
//
|
|
1489
|
+
// Prerequisites:
|
|
1490
|
+
// 1. ${name}HeaderEntity — AxDataEntityView for header table
|
|
1491
|
+
// 2. ${name}LineEntity — AxDataEntityView for line table
|
|
1492
|
+
// Then create the composite entity in the VS designer.
|
|
1493
|
+
// ══════════════════════════════════════════════════════════════════
|
|
1494
|
+
|
|
1495
|
+
// ── Composite Entity XML (AxCompositeDataEntity - create via VS designer) ──
|
|
1496
|
+
// Key properties:
|
|
1497
|
+
// <Name>${name}CompositeEntity</Name>
|
|
1498
|
+
// <PublicEntityName>${name}Composite</PublicEntityName>
|
|
1499
|
+
// <IsPublic>Yes</IsPublic>
|
|
1500
|
+
// <RootDataEntity>${name}HeaderEntity</RootDataEntity>
|
|
1501
|
+
//
|
|
1502
|
+
// Mapping:
|
|
1503
|
+
// Header → ${name}HeaderEntity (root)
|
|
1504
|
+
// └── Lines → ${name}LineEntity (child, linked by foreign key)
|
|
1505
|
+
|
|
1506
|
+
// ── Header Entity class adjustments ─────────────────────────────────────
|
|
1507
|
+
/// <summary>
|
|
1508
|
+
/// Header entity for ${name} composite import.
|
|
1509
|
+
/// Ensure natural key is defined (NOT RecId) for DMF matching.
|
|
1510
|
+
/// </summary>
|
|
1511
|
+
// Key XML for ${name}HeaderEntity:
|
|
1512
|
+
// <IsPublic>Yes</IsPublic>
|
|
1513
|
+
// <PublicEntityName>${name}Header</PublicEntityName>
|
|
1514
|
+
// <PublicCollectionName>${name}Headers</PublicCollectionName>
|
|
1515
|
+
// <DataManagementEnabled>Yes</DataManagementEnabled>
|
|
1516
|
+
// <EntityCategory>Document</EntityCategory>
|
|
1517
|
+
// <PrimaryKey>EntityKey</PrimaryKey> ← natural key (e.g. OrderId)
|
|
1518
|
+
|
|
1519
|
+
// ── Line Entity class adjustments ───────────────────────────────────────
|
|
1520
|
+
/// <summary>
|
|
1521
|
+
/// Line entity for ${name} composite import.
|
|
1522
|
+
/// MUST have a relation to the header entity for composite linking.
|
|
1523
|
+
/// </summary>
|
|
1524
|
+
// Key XML for ${name}LineEntity:
|
|
1525
|
+
// <IsPublic>Yes</IsPublic>
|
|
1526
|
+
// <PublicEntityName>${name}Line</PublicEntityName>
|
|
1527
|
+
// <PublicCollectionName>${name}Lines</PublicCollectionName>
|
|
1528
|
+
// <DataManagementEnabled>Yes</DataManagementEnabled>
|
|
1529
|
+
// <EntityCategory>Document</EntityCategory>
|
|
1530
|
+
//
|
|
1531
|
+
// Relation (in line entity datasource):
|
|
1532
|
+
// <AxDataEntityViewRelation>
|
|
1533
|
+
// <Name>${name}Header</Name>
|
|
1534
|
+
// <Cardinality>ZeroMore</Cardinality>
|
|
1535
|
+
// <RelatedDataEntity>${name}HeaderEntity</RelatedDataEntity>
|
|
1536
|
+
// <RelatedDataEntityCardinality>ZeroOne</RelatedDataEntityCardinality>
|
|
1537
|
+
// <RelatedDataEntityRole>Header</RelatedDataEntityRole>
|
|
1538
|
+
// <Role>Lines</Role>
|
|
1539
|
+
// <Constraints>
|
|
1540
|
+
// <AxDataEntityViewRelationConstraint>
|
|
1541
|
+
// <Name>OrderId</Name>
|
|
1542
|
+
// <Field>OrderId</Field>
|
|
1543
|
+
// <RelatedField>OrderId</RelatedField>
|
|
1544
|
+
// </AxDataEntityViewRelationConstraint>
|
|
1545
|
+
// </Constraints>
|
|
1546
|
+
// </AxDataEntityViewRelation>
|
|
1547
|
+
|
|
1548
|
+
// ── DMF import workflow ─────────────────────────────────────────────────
|
|
1549
|
+
// 1. Create a Data Project in Data Management workspace
|
|
1550
|
+
// 2. Add the composite entity (${name}CompositeEntity)
|
|
1551
|
+
// 3. Import file format: XML or JSON (composite entities do NOT support CSV)
|
|
1552
|
+
// 4. Header/Line records are imported together in correct order
|
|
1553
|
+
// 5. After import: check staging table for errors (DMFTransferStatus)`;
|
|
1554
|
+
}
|
|
1555
|
+
// Custom Service pattern: Service Group + Operations
|
|
1556
|
+
function customServiceTemplate(name) {
|
|
1557
|
+
return `// ══════════════════════════════════════════════════════════════════
|
|
1558
|
+
// Custom Service: ${name}
|
|
1559
|
+
// Exposes custom X++ logic as a SOAP/JSON web service.
|
|
1560
|
+
// 3 objects: Service class + Service XML (AxService) + Service Group XML
|
|
1561
|
+
// ══════════════════════════════════════════════════════════════════
|
|
1562
|
+
|
|
1563
|
+
// ── 1. Service Contract (request/response) ──────────────────────────────
|
|
1564
|
+
[DataContractAttribute]
|
|
1565
|
+
public final class ${name}ServiceRequest
|
|
1566
|
+
{
|
|
1567
|
+
private str recordId;
|
|
1568
|
+
private str operation;
|
|
1569
|
+
|
|
1570
|
+
[DataMemberAttribute('RecordId')]
|
|
1571
|
+
public str parmRecordId(str _v = recordId)
|
|
1572
|
+
{
|
|
1573
|
+
recordId = _v;
|
|
1574
|
+
return recordId;
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1577
|
+
[DataMemberAttribute('Operation')]
|
|
1578
|
+
public str parmOperation(str _v = operation)
|
|
1579
|
+
{
|
|
1580
|
+
operation = _v;
|
|
1581
|
+
return operation;
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
[DataContractAttribute]
|
|
1586
|
+
public final class ${name}ServiceResponse
|
|
1587
|
+
{
|
|
1588
|
+
private boolean success;
|
|
1589
|
+
private str message;
|
|
1590
|
+
private str resultData;
|
|
1591
|
+
|
|
1592
|
+
[DataMemberAttribute('Success')]
|
|
1593
|
+
public boolean parmSuccess(boolean _v = success)
|
|
1594
|
+
{
|
|
1595
|
+
success = _v;
|
|
1596
|
+
return success;
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
[DataMemberAttribute('Message')]
|
|
1600
|
+
public str parmMessage(str _v = message)
|
|
1601
|
+
{
|
|
1602
|
+
message = _v;
|
|
1603
|
+
return message;
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1606
|
+
[DataMemberAttribute('ResultData')]
|
|
1607
|
+
public str parmResultData(str _v = resultData)
|
|
1608
|
+
{
|
|
1609
|
+
resultData = _v;
|
|
1610
|
+
return resultData;
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1614
|
+
// ── 2. Service class ────────────────────────────────────────────────────
|
|
1615
|
+
/// <summary>
|
|
1616
|
+
/// Custom service operations for ${name}.
|
|
1617
|
+
/// Each public method with [SysEntryPointAttribute] becomes a service operation.
|
|
1618
|
+
/// </summary>
|
|
1619
|
+
public class ${name}Service
|
|
1620
|
+
{
|
|
1621
|
+
/// <summary>
|
|
1622
|
+
/// Processes the request and returns a response.
|
|
1623
|
+
/// </summary>
|
|
1624
|
+
[SysEntryPointAttribute(true)]
|
|
1625
|
+
public ${name}ServiceResponse processRequest(${name}ServiceRequest _request)
|
|
1626
|
+
{
|
|
1627
|
+
${name}ServiceResponse response = new ${name}ServiceResponse();
|
|
1628
|
+
|
|
1629
|
+
try
|
|
1630
|
+
{
|
|
1631
|
+
str recordId = _request.parmRecordId();
|
|
1632
|
+
str operation = _request.parmOperation();
|
|
1633
|
+
|
|
1634
|
+
// TODO: Implement business logic based on operation
|
|
1635
|
+
ttsbegin;
|
|
1636
|
+
|
|
1637
|
+
// Process...
|
|
1638
|
+
|
|
1639
|
+
ttscommit;
|
|
1640
|
+
|
|
1641
|
+
response.parmSuccess(true);
|
|
1642
|
+
response.parmMessage('Operation completed successfully.');
|
|
1643
|
+
}
|
|
1644
|
+
catch (Exception::Error)
|
|
1645
|
+
{
|
|
1646
|
+
response.parmSuccess(false);
|
|
1647
|
+
response.parmMessage(infolog.text());
|
|
1648
|
+
}
|
|
1649
|
+
|
|
1650
|
+
return response;
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
/// <summary>
|
|
1654
|
+
/// Returns a health check / ping response.
|
|
1655
|
+
/// </summary>
|
|
1656
|
+
[SysEntryPointAttribute(false)]
|
|
1657
|
+
public str ping()
|
|
1658
|
+
{
|
|
1659
|
+
return 'OK';
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
// ── 3. AOT objects (create via create_d365fo_file) ──────────────────────
|
|
1664
|
+
// Verify the result afterwards with get_object_info(objectType="service", name="${name}Service").
|
|
1665
|
+
// a) AxService XML (real schema: ServiceOperations / AxServiceOperation / Method):
|
|
1666
|
+
// <AxService xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
|
|
1667
|
+
// <Name>${name}Service</Name>
|
|
1668
|
+
// <Class>${name}Service</Class>
|
|
1669
|
+
// <ExternalName>${name}Service</ExternalName>
|
|
1670
|
+
// <Namespace>http://schemas.microsoft.com/dynamics/2011/01/services</Namespace>
|
|
1671
|
+
// <ServiceOperations>
|
|
1672
|
+
// <AxServiceOperation>
|
|
1673
|
+
// <Name>processRequest</Name>
|
|
1674
|
+
// <EnableIdempotence>Yes</EnableIdempotence>
|
|
1675
|
+
// <Method>processRequest</Method>
|
|
1676
|
+
// </AxServiceOperation>
|
|
1677
|
+
// <AxServiceOperation>
|
|
1678
|
+
// <Name>ping</Name>
|
|
1679
|
+
// <EnableIdempotence>Yes</EnableIdempotence>
|
|
1680
|
+
// <Method>ping</Method>
|
|
1681
|
+
// </AxServiceOperation>
|
|
1682
|
+
// </ServiceOperations>
|
|
1683
|
+
// </AxService>
|
|
1684
|
+
//
|
|
1685
|
+
// b) AxServiceGroup XML (real schema: Services / AxServiceGroupService):
|
|
1686
|
+
// <AxServiceGroup xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
|
|
1687
|
+
// <Name>${name}ServiceGroup</Name>
|
|
1688
|
+
// <AutoDeploy>Yes</AutoDeploy>
|
|
1689
|
+
// <Services>
|
|
1690
|
+
// <AxServiceGroupService>
|
|
1691
|
+
// <Name>${name}Service</Name>
|
|
1692
|
+
// <Service>${name}Service</Service>
|
|
1693
|
+
// </AxServiceGroupService>
|
|
1694
|
+
// </Services>
|
|
1695
|
+
// </AxServiceGroup>
|
|
1696
|
+
//
|
|
1697
|
+
// JSON request body wraps the payload in the operation parameter name (_request):
|
|
1698
|
+
// { "_request": { "RecordId": "...", "Operation": "..." } }
|
|
1699
|
+
// Endpoint URL after deploy:
|
|
1700
|
+
// https://{env}.operations.dynamics.com/api/services/${name}ServiceGroup/${name}Service/processRequest`;
|
|
1701
|
+
}
|
|
1702
|
+
// ER Custom Function pattern
|
|
1703
|
+
function erCustomFunctionTemplate(name) {
|
|
1704
|
+
return `/// <summary>
|
|
1705
|
+
/// Electronic Reporting custom function provider for ${name}.
|
|
1706
|
+
/// Extends the ER formula designer with custom functions usable in ER configurations.
|
|
1707
|
+
/// </summary>
|
|
1708
|
+
/// <remarks>
|
|
1709
|
+
/// After deployment, the function appears in the ER formula designer
|
|
1710
|
+
/// under the "Functions" list and can be used in ER format/model mappings.
|
|
1711
|
+
///
|
|
1712
|
+
/// Registration: The class is auto-discovered via [ERExpressionCustomFunctionProvider].
|
|
1713
|
+
/// </remarks>
|
|
1714
|
+
[ERExpressionCustomFunctionProvider]
|
|
1715
|
+
public final class ${name}ERFunctions
|
|
1716
|
+
{
|
|
1717
|
+
/// <summary>
|
|
1718
|
+
/// Custom string formatting function usable from ER formula designer.
|
|
1719
|
+
/// ER formula usage: ${name}.FormatValue(value, format)
|
|
1720
|
+
/// </summary>
|
|
1721
|
+
[ERExpressionCustomFunction('FormatValue',
|
|
1722
|
+
'@MyModel:${name}FormatValueDescription')]
|
|
1723
|
+
public static str formatValue(str _value, str _format)
|
|
1724
|
+
{
|
|
1725
|
+
// TODO: Implement custom formatting logic
|
|
1726
|
+
if (_format == 'upper')
|
|
1727
|
+
{
|
|
1728
|
+
return strUpr(_value);
|
|
1729
|
+
}
|
|
1730
|
+
else if (_format == 'trim')
|
|
1731
|
+
{
|
|
1732
|
+
return strLTrim(strRTrim(_value));
|
|
1733
|
+
}
|
|
1734
|
+
return _value;
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
/// <summary>
|
|
1738
|
+
/// Custom lookup function — retrieves a value from D365FO tables.
|
|
1739
|
+
/// ER formula usage: ${name}.LookupDescription(id)
|
|
1740
|
+
/// </summary>
|
|
1741
|
+
[ERExpressionCustomFunction('LookupDescription',
|
|
1742
|
+
'@MyModel:${name}LookupDescDescription')]
|
|
1743
|
+
public static str lookupDescription(str _id)
|
|
1744
|
+
{
|
|
1745
|
+
// TODO: Replace with actual table lookup
|
|
1746
|
+
// Example: return InventTable::find(_id).itemName();
|
|
1747
|
+
return '';
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1750
|
+
/// <summary>
|
|
1751
|
+
/// Custom validation function returning boolean.
|
|
1752
|
+
/// ER formula usage: ${name}.IsValid(value)
|
|
1753
|
+
/// </summary>
|
|
1754
|
+
[ERExpressionCustomFunction('IsValid',
|
|
1755
|
+
'@MyModel:${name}IsValidDescription')]
|
|
1756
|
+
public static boolean isValid(str _value)
|
|
1757
|
+
{
|
|
1758
|
+
// TODO: Implement validation logic
|
|
1759
|
+
return _value != '';
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
|
|
1763
|
+
// ── Usage in ER formula designer ────────────────────────────────────────
|
|
1764
|
+
// After deployment:
|
|
1765
|
+
// 1. Open Organizational administration > Electronic reporting > Configurations
|
|
1766
|
+
// 2. In format/model mapping designer, open the formula editor
|
|
1767
|
+
// 3. Find ${name}.FormatValue in the functions list
|
|
1768
|
+
// 4. Apply: ${name}.FormatValue(model.CustomerName, "upper")`;
|
|
1769
|
+
}
|
|
1770
|
+
const EXTENSION_PATTERNS = new Set([
|
|
1771
|
+
'table-extension', 'form-handler', 'event-handler', 'class-extension', 'map-extension',
|
|
1772
|
+
'form-datasource-extension', 'form-control-extension',
|
|
1773
|
+
]);
|
|
1774
|
+
const XML_PATTERNS = new Set(['security-privilege', 'menu-item']);
|
|
1775
|
+
export async function codeGenTool(request) {
|
|
1776
|
+
try {
|
|
1777
|
+
const args = CodeGenArgsSchema.parse(request.params.arguments);
|
|
1778
|
+
// Resolve prefix: EXTENSION_PREFIX env var (stripped of trailing '_') or modelName arg → mcp.json → empty
|
|
1779
|
+
const resolvedModelName = args.modelName || getConfigManager().getModelName() || '';
|
|
1780
|
+
const prefix = resolveObjectPrefix(resolvedModelName);
|
|
1781
|
+
// Extension infix: PascalCase form without underscore (e.g. "XY" → "Xy" when env has "XY_")
|
|
1782
|
+
const extensionInfix = deriveExtensionInfix(prefix);
|
|
1783
|
+
let code;
|
|
1784
|
+
let displayName;
|
|
1785
|
+
let namingNote;
|
|
1786
|
+
if (XML_PATTERNS.has(args.pattern)) {
|
|
1787
|
+
// XML generation patterns (security-privilege, menu-item)
|
|
1788
|
+
let xml;
|
|
1789
|
+
let xmlNote;
|
|
1790
|
+
if (args.pattern === 'security-privilege') {
|
|
1791
|
+
const targetMenuItem = args.targetObject || args.name;
|
|
1792
|
+
xml = securityPrivilegeXmlTemplate(args.name, targetMenuItem);
|
|
1793
|
+
xmlNote = `📌 Creates two privilege objects: ${args.name}View (Read) and ${args.name}Maintain (Update/Create/Delete)\n` +
|
|
1794
|
+
` Linked to entry point: ${targetMenuItem}\n\n` +
|
|
1795
|
+
`💡 Next steps:\n` +
|
|
1796
|
+
`1. Replace @TODO:LabelId_View and @TODO:LabelId_Maintain with actual label IDs\n` +
|
|
1797
|
+
`2. Create a duty referencing both privileges\n` +
|
|
1798
|
+
`3. Assign the duty to an appropriate role`;
|
|
1799
|
+
}
|
|
1800
|
+
else {
|
|
1801
|
+
// menu-item
|
|
1802
|
+
const targetObject = args.targetObject || args.name;
|
|
1803
|
+
const itemType = args.menuItemType || 'display';
|
|
1804
|
+
xml = menuItemXmlTemplate(args.name, itemType, targetObject);
|
|
1805
|
+
xmlNote = `📌 Creates AxMenuItem${itemType === 'action' ? 'Action' : itemType === 'output' ? 'Output' : 'Display'}: ${args.name}\n` +
|
|
1806
|
+
` Target ${itemType === 'action' ? 'class' : itemType === 'output' ? 'report' : 'form'}: ${targetObject}\n\n` +
|
|
1807
|
+
`💡 Next steps:\n` +
|
|
1808
|
+
`1. Replace @TODO:LabelId with actual label ID\n` +
|
|
1809
|
+
`2. Create security privilege referencing this menu item\n` +
|
|
1810
|
+
`3. Add menu item to the appropriate menu`;
|
|
1811
|
+
}
|
|
1812
|
+
return {
|
|
1813
|
+
content: [{
|
|
1814
|
+
type: 'text',
|
|
1815
|
+
text: `Generated ${args.pattern} XML for "${args.name}":\n\n` +
|
|
1816
|
+
`\`\`\`xml\n${xml}\n\`\`\`\n\n---\n\n${xmlNote}`,
|
|
1817
|
+
}],
|
|
1818
|
+
};
|
|
1819
|
+
}
|
|
1820
|
+
else if (EXTENSION_PATTERNS.has(args.pattern)) {
|
|
1821
|
+
// Extension pattern — args.name is the BASE element; prefix becomes the infix
|
|
1822
|
+
// Grounding enforcement: extension patterns require proof that the AI looked at the
|
|
1823
|
+
// real codebase (via prepare_change) before generating extension code.
|
|
1824
|
+
const groundingError = enforceGrounding(args.groundingToken, `generate_code(pattern="${args.pattern}", name="${args.name}")`, args.name);
|
|
1825
|
+
if (groundingError)
|
|
1826
|
+
return groundingError;
|
|
1827
|
+
// ── form-datasource-extension / form-control-extension (3-param templates) ──
|
|
1828
|
+
if (args.pattern === 'form-datasource-extension') {
|
|
1829
|
+
const formName = args.name;
|
|
1830
|
+
const dsName = args.baseName || args.name;
|
|
1831
|
+
code = formDataSourceExtensionTemplate(formName, extensionInfix, dsName);
|
|
1832
|
+
displayName = formName;
|
|
1833
|
+
const className = `${formName}_${dsName}${extensionInfix}DS_Extension`;
|
|
1834
|
+
namingNote = extensionInfix
|
|
1835
|
+
? `📌 **Naming (MS guidelines):** Generated class: \`${className}\`\n Form: \`${formName}\`, DataSource: \`${dsName}\`, Prefix infix: \`${extensionInfix}\``
|
|
1836
|
+
: `⚠️ **No prefix resolved** — pass \`modelName\` or set \`EXTENSION_PREFIX\` env var.\n Generated bare name: \`${formName}_${dsName}DS_Extension\` (not MS-compliant without infix).`;
|
|
1837
|
+
}
|
|
1838
|
+
else if (args.pattern === 'form-control-extension') {
|
|
1839
|
+
const formName = args.name;
|
|
1840
|
+
const ctrlName = args.baseName || 'ControlName';
|
|
1841
|
+
code = formControlExtensionTemplate(formName, extensionInfix, ctrlName);
|
|
1842
|
+
displayName = formName;
|
|
1843
|
+
const className = `${formName}_${ctrlName}${extensionInfix}Ctrl_Extension`;
|
|
1844
|
+
namingNote = extensionInfix
|
|
1845
|
+
? `📌 **Naming (MS guidelines):** Generated class: \`${className}\`\n Form: \`${formName}\`, Control: \`${ctrlName}\`, Prefix infix: \`${extensionInfix}\``
|
|
1846
|
+
: `⚠️ **No prefix resolved** — pass \`modelName\` or set \`EXTENSION_PREFIX\` env var.\n Generated bare name: \`${formName}_${ctrlName}Ctrl_Extension\` (not MS-compliant without infix).`;
|
|
1847
|
+
}
|
|
1848
|
+
else {
|
|
1849
|
+
// Generic 2-param extension templates
|
|
1850
|
+
const baseName = args.pattern === 'event-handler' ? (args.baseName || args.name) : args.name;
|
|
1851
|
+
const extTemplate = extensionTemplates[args.pattern];
|
|
1852
|
+
if (!extTemplate) {
|
|
1853
|
+
return {
|
|
1854
|
+
content: [{ type: 'text', text: `Unknown extension pattern: ${args.pattern}` }],
|
|
1855
|
+
isError: true,
|
|
1856
|
+
};
|
|
1857
|
+
}
|
|
1858
|
+
code = extTemplate(baseName, extensionInfix);
|
|
1859
|
+
displayName = baseName;
|
|
1860
|
+
if (args.pattern === 'event-handler') {
|
|
1861
|
+
namingNote = `📌 **Generated class:** \`${baseName}EventHandler\`\n` +
|
|
1862
|
+
` Handles onInserted and onValidatedWrite events of \`${baseName}\`\n` +
|
|
1863
|
+
` Add more handlers by repeating the [SubscribesTo] pattern.`;
|
|
1864
|
+
}
|
|
1865
|
+
else if (args.pattern === 'class-extension') {
|
|
1866
|
+
const exampleClass = `${baseName}${extensionInfix}_Extension`;
|
|
1867
|
+
const namingLine = extensionInfix
|
|
1868
|
+
? `📌 **Naming (MS guidelines):** Generated class: \`${exampleClass}\`\n Base class: \`${baseName}\`, Prefix infix: \`${extensionInfix}\``
|
|
1869
|
+
: `⚠️ **No prefix resolved** — set \`EXTENSION_PREFIX\` env var or pass \`modelName\` argument.\n Generated bare name without prefix infix (e.g. \`${baseName}_Extension\`) which is **not MS-compliant**.`;
|
|
1870
|
+
namingNote = namingLine + '\n\n' +
|
|
1871
|
+
`🚨 **REQUIRED before adding CoC methods:**\n` +
|
|
1872
|
+
` Call \`get_method(include="signature", "${baseName}", "methodName")\` for EACH method you want to wrap.\n` +
|
|
1873
|
+
` X++ does NOT support method overloading — adding both \`public boolean foo()\` and \`public static boolean foo()\`\n` +
|
|
1874
|
+
` in the same class will always cause a compile error.\n` +
|
|
1875
|
+
` The signature tool tells you whether the original is \`static\` or instance, so you generate exactly ONE CoC method.`;
|
|
1876
|
+
}
|
|
1877
|
+
else {
|
|
1878
|
+
const exampleClass = args.pattern === 'table-extension' ? `${baseName}${extensionInfix}_Extension`
|
|
1879
|
+
: args.pattern === 'map-extension' ? `${baseName}${extensionInfix}_Extension`
|
|
1880
|
+
: `${baseName}${extensionInfix}Form_Extension`;
|
|
1881
|
+
namingNote = extensionInfix
|
|
1882
|
+
? `📌 **Naming (MS guidelines):** Generated class: \`${exampleClass}\`\n Base element: \`${baseName}\`, Prefix infix: \`${extensionInfix}\``
|
|
1883
|
+
: `⚠️ **No prefix resolved** — set \`EXTENSION_PREFIX\` env var or pass \`modelName\` argument.\n Generated bare name without prefix infix (e.g. \`${baseName}_Extension\`) which is **not MS-compliant**.`;
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
else if (args.pattern === 'sysoperation') {
|
|
1888
|
+
// sysoperation is handled separately so we can pass the optional serviceMethod param
|
|
1889
|
+
let finalName = applyObjectPrefix(args.name, prefix);
|
|
1890
|
+
const suffix = getObjectSuffix();
|
|
1891
|
+
finalName = applyObjectSuffix(finalName, suffix);
|
|
1892
|
+
const serviceMethod = args.serviceMethod?.trim() || 'process';
|
|
1893
|
+
code = sysOperationTemplate(finalName, serviceMethod);
|
|
1894
|
+
displayName = finalName;
|
|
1895
|
+
namingNote = prefix
|
|
1896
|
+
? `📌 **Naming (MS guidelines):** Object prefix: \`${prefix}\` → generates \`${finalName}DataContract\`, \`${finalName}Controller\`, \`${finalName}Service\`\n` +
|
|
1897
|
+
` Service method: \`${serviceMethod}(${finalName}DataContract _contract)\``
|
|
1898
|
+
: `⚠️ **No prefix resolved** — set \`EXTENSION_PREFIX\` env var or pass \`modelName\`.\n` +
|
|
1899
|
+
` Service method: \`${serviceMethod}(${finalName}DataContract _contract)\``;
|
|
1900
|
+
}
|
|
1901
|
+
else {
|
|
1902
|
+
// New element pattern — apply prefix to the name
|
|
1903
|
+
const newTemplate = newElementTemplates[args.pattern];
|
|
1904
|
+
if (!newTemplate) {
|
|
1905
|
+
return {
|
|
1906
|
+
content: [{ type: 'text', text: `Unknown pattern: ${args.pattern}` }],
|
|
1907
|
+
isError: true,
|
|
1908
|
+
};
|
|
1909
|
+
}
|
|
1910
|
+
let finalName = applyObjectPrefix(args.name, prefix);
|
|
1911
|
+
const suffix = getObjectSuffix();
|
|
1912
|
+
finalName = applyObjectSuffix(finalName, suffix);
|
|
1913
|
+
code = newTemplate(finalName);
|
|
1914
|
+
displayName = finalName;
|
|
1915
|
+
namingNote = prefix
|
|
1916
|
+
? `📌 **Naming (MS guidelines):** Object name with prefix: \`${finalName}\``
|
|
1917
|
+
: `⚠️ **No prefix resolved** — set \`EXTENSION_PREFIX\` env var or pass \`modelName\` to auto-prefix new objects.`;
|
|
1918
|
+
}
|
|
1919
|
+
return {
|
|
1920
|
+
content: [
|
|
1921
|
+
{
|
|
1922
|
+
type: 'text',
|
|
1923
|
+
text: `Generated ${args.pattern} template for "${displayName}":\n\n` +
|
|
1924
|
+
`\`\`\`xpp${code}\n\`\`\`\n\n` +
|
|
1925
|
+
`---\n\n` +
|
|
1926
|
+
`${namingNote}\n\n` +
|
|
1927
|
+
(args.pattern === 'class-extension'
|
|
1928
|
+
? `💡 **Next Steps (class-extension CoC workflow):**\n\n` +
|
|
1929
|
+
`1. 🚨 Use \`get_method(include="signature", "${displayName}", "<methodName>")\` — **REQUIRED** to get the exact signature (static vs instance, return type, parameters) before writing any CoC method\n` +
|
|
1930
|
+
`2. ✅ Use \`find_coc_extensions("${displayName}", "<methodName>")\` - See existing CoC wrappers for reference\n` +
|
|
1931
|
+
`3. ✅ Use \`analyze_code(mode="implementations", "${displayName}", "<methodName>")\` - Get real implementation examples\n` +
|
|
1932
|
+
`4. ✅ Use \`analyze_code(mode="api-usage", "<ClassName>")\` - See how to use D365FO APIs correctly\n\n` +
|
|
1933
|
+
`⚠️ Never guess static vs instance — always use get_method(include="signature") first.`
|
|
1934
|
+
: `💡 **Next Steps for Better Code Quality:**\n\n` +
|
|
1935
|
+
`1. ✅ Use \`analyze_code(mode="patterns", "<scenario>")\` - Learn what D365FO classes are commonly used together\n` +
|
|
1936
|
+
`2. ✅ Use \`analyze_code(mode="implementations", "${displayName}", "<methodName>")\` - Get real implementation examples\n` +
|
|
1937
|
+
`3. ✅ Use \`analyze_code(mode="completeness", "${displayName}")\` - Check for missing common methods\n` +
|
|
1938
|
+
`4. ✅ Use \`analyze_code(mode="api-usage", "<ClassName>")\` - See how to use D365FO APIs correctly\n\n` +
|
|
1939
|
+
`These tools provide patterns from the actual codebase, not generic templates.`),
|
|
1940
|
+
},
|
|
1941
|
+
],
|
|
1942
|
+
};
|
|
1943
|
+
}
|
|
1944
|
+
catch (error) {
|
|
1945
|
+
return {
|
|
1946
|
+
content: [
|
|
1947
|
+
{
|
|
1948
|
+
type: 'text',
|
|
1949
|
+
text: `Error generating code: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
1950
|
+
},
|
|
1951
|
+
],
|
|
1952
|
+
isError: true,
|
|
1953
|
+
};
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
//# sourceMappingURL=codeGen.js.map
|