@peernova/cuneiform-sf 1.0.2 → 1.0.4-beta.8
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 +81 -30
- package/README.md +59 -95
- package/lib/adapters/connection-facade.d.ts +458 -0
- package/lib/adapters/connection-facade.js +379 -0
- package/lib/adapters/connection-facade.js.map +1 -0
- package/lib/adapters/errors.d.ts +547 -0
- package/lib/adapters/errors.js +937 -0
- package/lib/adapters/errors.js.map +1 -0
- package/lib/adapters/index.d.ts +33 -0
- package/lib/adapters/index.js +50 -0
- package/lib/adapters/index.js.map +1 -0
- package/lib/adapters/lifecycle.d.ts +119 -0
- package/lib/adapters/lifecycle.js +94 -0
- package/lib/adapters/lifecycle.js.map +1 -0
- package/lib/adapters/rest/cache.d.ts +69 -0
- package/lib/adapters/rest/cache.js +133 -0
- package/lib/adapters/rest/cache.js.map +1 -0
- package/lib/adapters/rest/index.d.ts +11 -0
- package/lib/adapters/rest/index.js +18 -0
- package/lib/adapters/rest/index.js.map +1 -0
- package/lib/adapters/rest/profiling-rest-client.d.ts +137 -0
- package/lib/adapters/rest/profiling-rest-client.js +115 -0
- package/lib/adapters/rest/profiling-rest-client.js.map +1 -0
- package/lib/adapters/rest/rest-api-adapter.d.ts +389 -0
- package/lib/adapters/rest/rest-api-adapter.js +747 -0
- package/lib/adapters/rest/rest-api-adapter.js.map +1 -0
- package/lib/adapters/rest/types.d.ts +34 -0
- package/lib/adapters/rest/types.js +9 -0
- package/lib/adapters/rest/types.js.map +1 -0
- package/lib/adapters/retry.d.ts +91 -0
- package/lib/adapters/retry.js +215 -0
- package/lib/adapters/retry.js.map +1 -0
- package/lib/adapters/soql/cuneiform-query-builder.d.ts +391 -0
- package/lib/adapters/soql/cuneiform-query-builder.js +559 -0
- package/lib/adapters/soql/cuneiform-query-builder.js.map +1 -0
- package/lib/adapters/soql/index.d.ts +13 -0
- package/lib/adapters/soql/index.js +21 -0
- package/lib/adapters/soql/index.js.map +1 -0
- package/lib/adapters/soql/soql-query-adapter.d.ts +141 -0
- package/lib/adapters/soql/soql-query-adapter.js +259 -0
- package/lib/adapters/soql/soql-query-adapter.js.map +1 -0
- package/lib/adapters/soql/types.d.ts +37 -0
- package/lib/adapters/soql/types.js +19 -0
- package/lib/adapters/soql/types.js.map +1 -0
- package/lib/adapters/testing/index.d.ts +37 -0
- package/lib/adapters/testing/index.js +20 -0
- package/lib/adapters/testing/index.js.map +1 -0
- package/lib/adapters/testing/mock-connection.d.ts +77 -0
- package/lib/adapters/testing/mock-connection.js +207 -0
- package/lib/adapters/testing/mock-connection.js.map +1 -0
- package/lib/adapters/testing/mock-logger.d.ts +29 -0
- package/lib/adapters/testing/mock-logger.js +57 -0
- package/lib/adapters/testing/mock-logger.js.map +1 -0
- package/lib/adapters/testing/mock-mcp-adapters.d.ts +32 -0
- package/lib/adapters/testing/mock-mcp-adapters.js +52 -0
- package/lib/adapters/testing/mock-mcp-adapters.js.map +1 -0
- package/lib/adapters/testing/mock-oclif-config.d.ts +22 -0
- package/lib/adapters/testing/mock-oclif-config.js +90 -0
- package/lib/adapters/testing/mock-oclif-config.js.map +1 -0
- package/lib/adapters/testing/mock-rest-adapter.d.ts +26 -0
- package/lib/adapters/testing/mock-rest-adapter.js +243 -0
- package/lib/adapters/testing/mock-rest-adapter.js.map +1 -0
- package/lib/adapters/testing/mock-salesforce-connection.d.ts +40 -0
- package/lib/adapters/testing/mock-salesforce-connection.js +61 -0
- package/lib/adapters/testing/mock-salesforce-connection.js.map +1 -0
- package/lib/adapters/testing/mock-soql-adapter.d.ts +30 -0
- package/lib/adapters/testing/mock-soql-adapter.js +120 -0
- package/lib/adapters/testing/mock-soql-adapter.js.map +1 -0
- package/lib/adapters/testing/mock-tooling-adapter.d.ts +24 -0
- package/lib/adapters/testing/mock-tooling-adapter.js +163 -0
- package/lib/adapters/testing/mock-tooling-adapter.js.map +1 -0
- package/lib/adapters/testing/stub-connection.d.ts +93 -0
- package/lib/adapters/testing/stub-connection.js +97 -0
- package/lib/adapters/testing/stub-connection.js.map +1 -0
- package/lib/adapters/testing/stub-rest-adapter.d.ts +52 -0
- package/lib/adapters/testing/stub-rest-adapter.js +58 -0
- package/lib/adapters/testing/stub-rest-adapter.js.map +1 -0
- package/lib/adapters/testing/stub-soql-adapter.d.ts +56 -0
- package/lib/adapters/testing/stub-soql-adapter.js +50 -0
- package/lib/adapters/testing/stub-soql-adapter.js.map +1 -0
- package/lib/adapters/testing/types.d.ts +71 -0
- package/lib/adapters/testing/types.js +9 -0
- package/lib/adapters/testing/types.js.map +1 -0
- package/lib/adapters/tooling/index.d.ts +10 -0
- package/lib/adapters/tooling/index.js +17 -0
- package/lib/adapters/tooling/index.js.map +1 -0
- package/lib/adapters/tooling/tooling-api-adapter.d.ts +157 -0
- package/lib/adapters/tooling/tooling-api-adapter.js +339 -0
- package/lib/adapters/tooling/tooling-api-adapter.js.map +1 -0
- package/lib/adapters/tooling/types.d.ts +81 -0
- package/lib/adapters/tooling/types.js +9 -0
- package/lib/adapters/tooling/types.js.map +1 -0
- package/lib/adapters/types.d.ts +112 -0
- package/lib/adapters/types.js +169 -0
- package/lib/adapters/types.js.map +1 -0
- package/lib/base/cuneiform-command.d.ts +152 -0
- package/lib/base/cuneiform-command.js +243 -0
- package/lib/base/cuneiform-command.js.map +1 -0
- package/lib/commands/cuneiform/compatibility/check.d.ts +43 -0
- package/lib/commands/cuneiform/compatibility/check.js +114 -0
- package/lib/commands/cuneiform/compatibility/check.js.map +1 -0
- package/lib/commands/cuneiform/definition/create.d.ts +119 -0
- package/lib/commands/cuneiform/definition/create.js +693 -0
- package/lib/commands/cuneiform/definition/create.js.map +1 -0
- package/lib/commands/cuneiform/definition/export.d.ts +57 -0
- package/lib/commands/cuneiform/definition/export.js +133 -0
- package/lib/commands/cuneiform/definition/export.js.map +1 -0
- package/lib/commands/cuneiform/definition/get.d.ts +86 -0
- package/lib/commands/cuneiform/definition/get.js +270 -0
- package/lib/commands/cuneiform/definition/get.js.map +1 -0
- package/lib/commands/cuneiform/definition/import.d.ts +54 -0
- package/lib/commands/cuneiform/definition/import.js +118 -0
- package/lib/commands/cuneiform/definition/import.js.map +1 -0
- package/lib/commands/cuneiform/definition/list.d.ts +110 -0
- package/lib/commands/cuneiform/definition/list.js +344 -0
- package/lib/commands/cuneiform/definition/list.js.map +1 -0
- package/lib/commands/cuneiform/definition/purge.d.ts +105 -0
- package/lib/commands/cuneiform/definition/purge.js +533 -0
- package/lib/commands/cuneiform/definition/purge.js.map +1 -0
- package/lib/commands/cuneiform/definition/update.d.ts +58 -0
- package/lib/commands/cuneiform/definition/update.js +206 -0
- package/lib/commands/cuneiform/definition/update.js.map +1 -0
- package/lib/commands/cuneiform/mcp/serve.d.ts +56 -0
- package/lib/commands/cuneiform/mcp/serve.js +109 -0
- package/lib/commands/cuneiform/mcp/serve.js.map +1 -0
- package/lib/commands/cuneiform/object/describe.d.ts +61 -0
- package/lib/commands/cuneiform/object/describe.js +461 -0
- package/lib/commands/cuneiform/object/describe.js.map +1 -0
- package/lib/commands/cuneiform/object/list.d.ts +111 -0
- package/lib/commands/cuneiform/object/list.js +239 -0
- package/lib/commands/cuneiform/object/list.js.map +1 -0
- package/lib/commands/cuneiform/org/details.d.ts +99 -0
- package/lib/commands/cuneiform/org/details.js +521 -0
- package/lib/commands/cuneiform/org/details.js.map +1 -0
- package/lib/commands/cuneiform/org/reset.d.ts +46 -0
- package/lib/commands/cuneiform/org/reset.js +135 -0
- package/lib/commands/cuneiform/org/reset.js.map +1 -0
- package/lib/commands/cuneiform/profile/request/cancel.d.ts +59 -0
- package/lib/commands/cuneiform/profile/request/cancel.js +202 -0
- package/lib/commands/cuneiform/profile/request/cancel.js.map +1 -0
- package/lib/commands/cuneiform/profile/request/delete.d.ts +59 -0
- package/lib/commands/cuneiform/profile/request/delete.js +223 -0
- package/lib/commands/cuneiform/profile/request/delete.js.map +1 -0
- package/lib/commands/cuneiform/profile/request/list.d.ts +35 -0
- package/lib/commands/cuneiform/profile/request/list.js +102 -0
- package/lib/commands/cuneiform/profile/request/list.js.map +1 -0
- package/lib/commands/cuneiform/profile.d.ts +90 -0
- package/lib/commands/cuneiform/profile.js +322 -0
- package/lib/commands/cuneiform/profile.js.map +1 -0
- package/lib/commands/cuneiform/summary/purge.d.ts +77 -0
- package/lib/commands/cuneiform/summary/purge.js +429 -0
- package/lib/commands/cuneiform/summary/purge.js.map +1 -0
- package/lib/commands/cuneiform/summary/reprofile.d.ts +60 -0
- package/lib/commands/cuneiform/summary/reprofile.js +236 -0
- package/lib/commands/cuneiform/summary/reprofile.js.map +1 -0
- package/lib/commands/cuneiform/summary/stop.d.ts +59 -0
- package/lib/commands/cuneiform/summary/stop.js +234 -0
- package/lib/commands/cuneiform/summary/stop.js.map +1 -0
- package/lib/commands/cuneiform/user/details.d.ts +73 -0
- package/lib/commands/cuneiform/user/details.js +391 -0
- package/lib/commands/cuneiform/user/details.js.map +1 -0
- package/lib/constants/index.d.ts +8 -0
- package/lib/constants/index.js +16 -0
- package/lib/constants/index.js.map +1 -0
- package/lib/constants/namespace-constants.d.ts +91 -0
- package/lib/constants/namespace-constants.js +211 -0
- package/lib/constants/namespace-constants.js.map +1 -0
- package/lib/debug/command-debug-proxy.d.ts +101 -0
- package/lib/debug/command-debug-proxy.js +171 -0
- package/lib/debug/command-debug-proxy.js.map +1 -0
- package/lib/debug/debug-logger.d.ts +85 -0
- package/lib/debug/debug-logger.js +133 -0
- package/lib/debug/debug-logger.js.map +1 -0
- package/lib/debug/index.d.ts +12 -0
- package/lib/debug/index.js +20 -0
- package/lib/debug/index.js.map +1 -0
- package/lib/debug/service-debug-proxy.d.ts +30 -0
- package/lib/debug/service-debug-proxy.js +102 -0
- package/lib/debug/service-debug-proxy.js.map +1 -0
- package/lib/hooks/prerun.d.ts +25 -0
- package/lib/hooks/prerun.js +47 -0
- package/lib/hooks/prerun.js.map +1 -0
- package/lib/mcp/config/mcp-config.d.ts +55 -0
- package/lib/mcp/config/mcp-config.js +51 -0
- package/lib/mcp/config/mcp-config.js.map +1 -0
- package/lib/mcp/config/pagination.d.ts +96 -0
- package/lib/mcp/config/pagination.js +108 -0
- package/lib/mcp/config/pagination.js.map +1 -0
- package/lib/mcp/config/system-prompts.d.ts +18 -0
- package/lib/mcp/config/system-prompts.js +92 -0
- package/lib/mcp/config/system-prompts.js.map +1 -0
- package/lib/mcp/errors.d.ts +23 -0
- package/lib/mcp/errors.js +27 -0
- package/lib/mcp/errors.js.map +1 -0
- package/lib/mcp/schemas/input-schemas.d.ts +327 -0
- package/lib/mcp/schemas/input-schemas.js +302 -0
- package/lib/mcp/schemas/input-schemas.js.map +1 -0
- package/lib/mcp/server.d.ts +40 -0
- package/lib/mcp/server.js +316 -0
- package/lib/mcp/server.js.map +1 -0
- package/lib/mcp/tools/contactpoint-tools.d.ts +14 -0
- package/lib/mcp/tools/contactpoint-tools.js +34 -0
- package/lib/mcp/tools/contactpoint-tools.js.map +1 -0
- package/lib/mcp/tools/definition-io-tools.d.ts +19 -0
- package/lib/mcp/tools/definition-io-tools.js +152 -0
- package/lib/mcp/tools/definition-io-tools.js.map +1 -0
- package/lib/mcp/tools/definition-tools.d.ts +51 -0
- package/lib/mcp/tools/definition-tools.js +199 -0
- package/lib/mcp/tools/definition-tools.js.map +1 -0
- package/lib/mcp/tools/index.d.ts +37 -0
- package/lib/mcp/tools/index.js +88 -0
- package/lib/mcp/tools/index.js.map +1 -0
- package/lib/mcp/tools/object-tools.d.ts +22 -0
- package/lib/mcp/tools/object-tools.js +306 -0
- package/lib/mcp/tools/object-tools.js.map +1 -0
- package/lib/mcp/tools/org-tools.d.ts +14 -0
- package/lib/mcp/tools/org-tools.js +177 -0
- package/lib/mcp/tools/org-tools.js.map +1 -0
- package/lib/mcp/tools/profile-tools.d.ts +59 -0
- package/lib/mcp/tools/profile-tools.js +213 -0
- package/lib/mcp/tools/profile-tools.js.map +1 -0
- package/lib/mcp/tools/summary-tools.d.ts +14 -0
- package/lib/mcp/tools/summary-tools.js +38 -0
- package/lib/mcp/tools/summary-tools.js.map +1 -0
- package/lib/mcp/tools/tool-factory.d.ts +63 -0
- package/lib/mcp/tools/tool-factory.js +146 -0
- package/lib/mcp/tools/tool-factory.js.map +1 -0
- package/lib/mcp/tools/user-tools.d.ts +25 -0
- package/lib/mcp/tools/user-tools.js +167 -0
- package/lib/mcp/tools/user-tools.js.map +1 -0
- package/lib/models/date-literal.d.ts +211 -0
- package/lib/models/date-literal.js +615 -0
- package/lib/models/date-literal.js.map +1 -0
- package/lib/models/object-describe-types.d.ts +173 -0
- package/lib/models/object-describe-types.js +9 -0
- package/lib/models/object-describe-types.js.map +1 -0
- package/lib/models/profile-request-types.d.ts +118 -0
- package/lib/models/profile-request-types.js +23 -0
- package/lib/models/profile-request-types.js.map +1 -0
- package/lib/models/profiling-execution-types.d.ts +154 -0
- package/lib/models/profiling-execution-types.js +14 -0
- package/lib/models/profiling-execution-types.js.map +1 -0
- package/lib/models/service-result.d.ts +114 -0
- package/lib/models/service-result.js +81 -0
- package/lib/models/service-result.js.map +1 -0
- package/lib/models/sfdmu-types.d.ts +53 -0
- package/lib/models/sfdmu-types.js +23 -0
- package/lib/models/sfdmu-types.js.map +1 -0
- package/lib/models/status-types.d.ts +38 -0
- package/lib/models/status-types.js +12 -0
- package/lib/models/status-types.js.map +1 -0
- package/lib/models/summary-bulk-types.d.ts +61 -0
- package/lib/models/summary-bulk-types.js +23 -0
- package/lib/models/summary-bulk-types.js.map +1 -0
- package/lib/models/user-details-types.d.ts +163 -0
- package/lib/models/user-details-types.js +9 -0
- package/lib/models/user-details-types.js.map +1 -0
- package/lib/models/year-range.d.ts +78 -0
- package/lib/models/year-range.js +153 -0
- package/lib/models/year-range.js.map +1 -0
- package/lib/operations/CompatibilityCheckOperation.d.ts +62 -0
- package/lib/operations/CompatibilityCheckOperation.js +102 -0
- package/lib/operations/CompatibilityCheckOperation.js.map +1 -0
- package/lib/operations/DefinitionCreateOperation.d.ts +411 -0
- package/lib/operations/DefinitionCreateOperation.js +1121 -0
- package/lib/operations/DefinitionCreateOperation.js.map +1 -0
- package/lib/operations/DefinitionExportOperation.d.ts +155 -0
- package/lib/operations/DefinitionExportOperation.js +281 -0
- package/lib/operations/DefinitionExportOperation.js.map +1 -0
- package/lib/operations/DefinitionImportOperation.d.ts +144 -0
- package/lib/operations/DefinitionImportOperation.js +357 -0
- package/lib/operations/DefinitionImportOperation.js.map +1 -0
- package/lib/operations/DefinitionListOperation.d.ts +66 -0
- package/lib/operations/DefinitionListOperation.js +108 -0
- package/lib/operations/DefinitionListOperation.js.map +1 -0
- package/lib/operations/DefinitionPurgeOperation.d.ts +199 -0
- package/lib/operations/DefinitionPurgeOperation.js +465 -0
- package/lib/operations/DefinitionPurgeOperation.js.map +1 -0
- package/lib/operations/DefinitionUpdateOperation.d.ts +78 -0
- package/lib/operations/DefinitionUpdateOperation.js +142 -0
- package/lib/operations/DefinitionUpdateOperation.js.map +1 -0
- package/lib/operations/OrgDetailsOperation.d.ts +253 -0
- package/lib/operations/OrgDetailsOperation.js +456 -0
- package/lib/operations/OrgDetailsOperation.js.map +1 -0
- package/lib/operations/OrgResetOperation.d.ts +114 -0
- package/lib/operations/OrgResetOperation.js +209 -0
- package/lib/operations/OrgResetOperation.js.map +1 -0
- package/lib/operations/ProfileOperation.d.ts +187 -0
- package/lib/operations/ProfileOperation.js +373 -0
- package/lib/operations/ProfileOperation.js.map +1 -0
- package/lib/operations/ProfileRequestCancelOperation.d.ts +59 -0
- package/lib/operations/ProfileRequestCancelOperation.js +137 -0
- package/lib/operations/ProfileRequestCancelOperation.js.map +1 -0
- package/lib/operations/ProfileRequestDeleteOperation.d.ts +64 -0
- package/lib/operations/ProfileRequestDeleteOperation.js +134 -0
- package/lib/operations/ProfileRequestDeleteOperation.js.map +1 -0
- package/lib/operations/ProfileRequestListOperation.d.ts +39 -0
- package/lib/operations/ProfileRequestListOperation.js +61 -0
- package/lib/operations/ProfileRequestListOperation.js.map +1 -0
- package/lib/operations/SummaryPurgeOperation.d.ts +134 -0
- package/lib/operations/SummaryPurgeOperation.js +257 -0
- package/lib/operations/SummaryPurgeOperation.js.map +1 -0
- package/lib/operations/SummaryReprofileOperation.d.ts +88 -0
- package/lib/operations/SummaryReprofileOperation.js +174 -0
- package/lib/operations/SummaryReprofileOperation.js.map +1 -0
- package/lib/operations/SummaryStopOperation.d.ts +87 -0
- package/lib/operations/SummaryStopOperation.js +175 -0
- package/lib/operations/SummaryStopOperation.js.map +1 -0
- package/lib/services/BulkExecutionService.d.ts +120 -0
- package/lib/services/BulkExecutionService.js +535 -0
- package/lib/services/BulkExecutionService.js.map +1 -0
- package/lib/services/CompatibilityService.d.ts +81 -0
- package/lib/services/CompatibilityService.js +118 -0
- package/lib/services/CompatibilityService.js.map +1 -0
- package/lib/services/ConfigureMode.d.ts +85 -0
- package/lib/services/ConfigureMode.js +390 -0
- package/lib/services/ConfigureMode.js.map +1 -0
- package/lib/services/ContactPointService.d.ts +111 -0
- package/lib/services/ContactPointService.js +286 -0
- package/lib/services/ContactPointService.js.map +1 -0
- package/lib/services/DataAvailabilityService.d.ts +81 -0
- package/lib/services/DataAvailabilityService.js +128 -0
- package/lib/services/DataAvailabilityService.js.map +1 -0
- package/lib/services/DefinitionFieldGenerationService.d.ts +309 -0
- package/lib/services/DefinitionFieldGenerationService.js +795 -0
- package/lib/services/DefinitionFieldGenerationService.js.map +1 -0
- package/lib/services/DefinitionQueryBuilder.d.ts +59 -0
- package/lib/services/DefinitionQueryBuilder.js +234 -0
- package/lib/services/DefinitionQueryBuilder.js.map +1 -0
- package/lib/services/ObjectDescribeService.d.ts +436 -0
- package/lib/services/ObjectDescribeService.js +869 -0
- package/lib/services/ObjectDescribeService.js.map +1 -0
- package/lib/services/ObjectFilteringService.d.ts +400 -0
- package/lib/services/ObjectFilteringService.js +878 -0
- package/lib/services/ObjectFilteringService.js.map +1 -0
- package/lib/services/ObjectListCommandService.d.ts +429 -0
- package/lib/services/ObjectListCommandService.js +873 -0
- package/lib/services/ObjectListCommandService.js.map +1 -0
- package/lib/services/ObjectListService.d.ts +201 -0
- package/lib/services/ObjectListService.js +345 -0
- package/lib/services/ObjectListService.js.map +1 -0
- package/lib/services/OrgInfoService.d.ts +485 -0
- package/lib/services/OrgInfoService.js +1122 -0
- package/lib/services/OrgInfoService.js.map +1 -0
- package/lib/services/PollingService.d.ts +105 -0
- package/lib/services/PollingService.js +117 -0
- package/lib/services/PollingService.js.map +1 -0
- package/lib/services/ProfileRequestService.d.ts +186 -0
- package/lib/services/ProfileRequestService.js +555 -0
- package/lib/services/ProfileRequestService.js.map +1 -0
- package/lib/services/ProfilingDefinitionService.d.ts +535 -0
- package/lib/services/ProfilingDefinitionService.js +981 -0
- package/lib/services/ProfilingDefinitionService.js.map +1 -0
- package/lib/services/ProfilingExecutionService.d.ts +122 -0
- package/lib/services/ProfilingExecutionService.js +320 -0
- package/lib/services/ProfilingExecutionService.js.map +1 -0
- package/lib/services/ProfilingSummaryService.d.ts +292 -0
- package/lib/services/ProfilingSummaryService.js +685 -0
- package/lib/services/ProfilingSummaryService.js.map +1 -0
- package/lib/services/RecordTypeService.d.ts +129 -0
- package/lib/services/RecordTypeService.js +284 -0
- package/lib/services/RecordTypeService.js.map +1 -0
- package/lib/services/SFDMUService.d.ts +133 -0
- package/lib/services/SFDMUService.js +295 -0
- package/lib/services/SFDMUService.js.map +1 -0
- package/lib/services/TabDetectionService.d.ts +105 -0
- package/lib/services/TabDetectionService.js +206 -0
- package/lib/services/TabDetectionService.js.map +1 -0
- package/lib/services/UnconfigureMode.d.ts +74 -0
- package/lib/services/UnconfigureMode.js +378 -0
- package/lib/services/UnconfigureMode.js.map +1 -0
- package/lib/services/UserConfigurationService.d.ts +155 -0
- package/lib/services/UserConfigurationService.js +573 -0
- package/lib/services/UserConfigurationService.js.map +1 -0
- package/lib/services/UserConfigurationTypes.d.ts +181 -0
- package/lib/services/UserConfigurationTypes.js +14 -0
- package/lib/services/UserConfigurationTypes.js.map +1 -0
- package/lib/services/UserReadinessService.d.ts +330 -0
- package/lib/services/UserReadinessService.js +831 -0
- package/lib/services/UserReadinessService.js.map +1 -0
- package/lib/services/constants.d.ts +53 -0
- package/lib/services/constants.js +71 -0
- package/lib/services/constants.js.map +1 -0
- package/lib/services/namespace-constants.d.ts +1 -0
- package/lib/services/namespace-constants.js +11 -0
- package/lib/services/namespace-constants.js.map +1 -0
- package/lib/services/validation.d.ts +47 -0
- package/lib/services/validation.js +119 -0
- package/lib/services/validation.js.map +1 -0
- package/lib/utils/batch-processor.d.ts +13 -0
- package/lib/utils/batch-processor.js +39 -0
- package/lib/utils/batch-processor.js.map +1 -0
- package/lib/utils/formatting/availability-grid.d.ts +81 -0
- package/lib/utils/formatting/availability-grid.js +94 -0
- package/lib/utils/formatting/availability-grid.js.map +1 -0
- package/lib/utils/formatting/business-process-grid.d.ts +51 -0
- package/lib/utils/formatting/business-process-grid.js +58 -0
- package/lib/utils/formatting/business-process-grid.js.map +1 -0
- package/lib/utils/formatting/command-display.d.ts +154 -0
- package/lib/utils/formatting/command-display.js +154 -0
- package/lib/utils/formatting/command-display.js.map +1 -0
- package/lib/utils/formatting/definition-create-display.d.ts +118 -0
- package/lib/utils/formatting/definition-create-display.js +231 -0
- package/lib/utils/formatting/definition-create-display.js.map +1 -0
- package/lib/utils/formatting/empty-states.d.ts +35 -0
- package/lib/utils/formatting/empty-states.js +70 -0
- package/lib/utils/formatting/empty-states.js.map +1 -0
- package/lib/utils/formatting/errors.d.ts +33 -0
- package/lib/utils/formatting/errors.js +72 -0
- package/lib/utils/formatting/errors.js.map +1 -0
- package/lib/utils/formatting/field-types.d.ts +32 -0
- package/lib/utils/formatting/field-types.js +88 -0
- package/lib/utils/formatting/field-types.js.map +1 -0
- package/lib/utils/formatting/index.d.ts +29 -0
- package/lib/utils/formatting/index.js +28 -0
- package/lib/utils/formatting/index.js.map +1 -0
- package/lib/utils/formatting/indicators.d.ts +113 -0
- package/lib/utils/formatting/indicators.js +161 -0
- package/lib/utils/formatting/indicators.js.map +1 -0
- package/lib/utils/formatting/loading-messages.d.ts +37 -0
- package/lib/utils/formatting/loading-messages.js +50 -0
- package/lib/utils/formatting/loading-messages.js.map +1 -0
- package/lib/utils/formatting/namespace-display.d.ts +31 -0
- package/lib/utils/formatting/namespace-display.js +64 -0
- package/lib/utils/formatting/namespace-display.js.map +1 -0
- package/lib/utils/formatting/numbers.d.ts +73 -0
- package/lib/utils/formatting/numbers.js +187 -0
- package/lib/utils/formatting/numbers.js.map +1 -0
- package/lib/utils/formatting/object-describe-display.d.ts +114 -0
- package/lib/utils/formatting/object-describe-display.js +440 -0
- package/lib/utils/formatting/object-describe-display.js.map +1 -0
- package/lib/utils/formatting/object-list-display.d.ts +213 -0
- package/lib/utils/formatting/object-list-display.js +672 -0
- package/lib/utils/formatting/object-list-display.js.map +1 -0
- package/lib/utils/formatting/org-identity.d.ts +15 -0
- package/lib/utils/formatting/org-identity.js +28 -0
- package/lib/utils/formatting/org-identity.js.map +1 -0
- package/lib/utils/formatting/record-age-grid.d.ts +41 -0
- package/lib/utils/formatting/record-age-grid.js +56 -0
- package/lib/utils/formatting/record-age-grid.js.map +1 -0
- package/lib/utils/formatting/sections.d.ts +108 -0
- package/lib/utils/formatting/sections.js +150 -0
- package/lib/utils/formatting/sections.js.map +1 -0
- package/lib/utils/formatting/tables.d.ts +90 -0
- package/lib/utils/formatting/tables.js +113 -0
- package/lib/utils/formatting/tables.js.map +1 -0
- package/lib/utils/formatting/user-details-display.d.ts +101 -0
- package/lib/utils/formatting/user-details-display.js +425 -0
- package/lib/utils/formatting/user-details-display.js.map +1 -0
- package/lib/utils/pagination/index.d.ts +11 -0
- package/lib/utils/pagination/index.js +18 -0
- package/lib/utils/pagination/index.js.map +1 -0
- package/lib/utils/pagination/keypress-reader.d.ts +20 -0
- package/lib/utils/pagination/keypress-reader.js +63 -0
- package/lib/utils/pagination/keypress-reader.js.map +1 -0
- package/lib/utils/pagination/paginate-output.d.ts +48 -0
- package/lib/utils/pagination/paginate-output.js +136 -0
- package/lib/utils/pagination/paginate-output.js.map +1 -0
- package/messages/compatibility.check.md +71 -0
- package/messages/cuneiform.access.md +138 -0
- package/messages/definition.create.md +511 -0
- package/messages/definition.export.md +84 -0
- package/messages/definition.get.md +147 -0
- package/messages/definition.import.md +65 -0
- package/messages/definition.list.md +264 -0
- package/messages/definition.purge.md +318 -0
- package/messages/definition.update.md +118 -0
- package/messages/mcp.serve.md +66 -0
- package/messages/object.describe.md +201 -0
- package/messages/object.list.md +443 -0
- package/messages/org.details.md +386 -0
- package/messages/org.reset.md +71 -0
- package/messages/profile.md +231 -0
- package/messages/profile.request.cancel.md +143 -0
- package/messages/profile.request.delete.md +139 -0
- package/messages/profile.request.list.md +89 -0
- package/messages/summary.purge.md +218 -0
- package/messages/summary.reprofile.md +150 -0
- package/messages/summary.stop.md +157 -0
- package/messages/user.details.md +501 -0
- package/oclif.lock +2887 -2149
- package/oclif.manifest.json +2813 -31
- package/package.json +94 -19
- package/lib/commands/cuneiform/about.d.ts +0 -13
- package/lib/commands/cuneiform/about.js +0 -26
- package/lib/commands/cuneiform/about.js.map +0 -1
- package/lib/commands/hello/world.d.ts +0 -14
- package/lib/commands/hello/world.js +0 -27
- package/lib/commands/hello/world.js.map +0 -1
- package/lib/index.d.ts +0 -2
- package/lib/index.js +0 -2
- package/lib/index.js.map +0 -1
- package/messages/cuneiform.about.md +0 -19
- package/messages/hello.world.md +0 -29
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import type { IRestApiAdapter } from '../adapters/rest/rest-api-adapter.js';
|
|
2
|
+
import type { ServiceResult } from '../models/service-result.js';
|
|
3
|
+
/**
|
|
4
|
+
* Classification type for a contact point field.
|
|
5
|
+
*/
|
|
6
|
+
export type ContactPointType = 'email' | 'phone' | 'name' | 'social' | 'url' | 'other';
|
|
7
|
+
/**
|
|
8
|
+
* Represents a field identified as a contact point.
|
|
9
|
+
*/
|
|
10
|
+
export type ContactPointField = {
|
|
11
|
+
/** API name of the field */
|
|
12
|
+
fieldName: string;
|
|
13
|
+
/** User-friendly label */
|
|
14
|
+
fieldLabel: string;
|
|
15
|
+
/** Salesforce field type (string, email, phone, textarea, etc.) */
|
|
16
|
+
fieldType: string;
|
|
17
|
+
/** Classified contact point type */
|
|
18
|
+
contactPointType: ContactPointType;
|
|
19
|
+
/** Classification confidence level */
|
|
20
|
+
confidence: 'high' | 'medium' | 'low';
|
|
21
|
+
/** Reason for classification */
|
|
22
|
+
reason: string;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Result of analyzing an object's fields for contact points.
|
|
26
|
+
*/
|
|
27
|
+
export type ContactPointAnalysis = {
|
|
28
|
+
/** API name of the analyzed object */
|
|
29
|
+
objectName: string;
|
|
30
|
+
/** Total number of fields on the object */
|
|
31
|
+
totalFields: number;
|
|
32
|
+
/** Fields identified as contact points */
|
|
33
|
+
contactPointFields: ContactPointField[];
|
|
34
|
+
/** Number of contact point fields found */
|
|
35
|
+
contactPointCount: number;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Configuration for ContactPointService.
|
|
39
|
+
*/
|
|
40
|
+
export type IContactPointServiceConfig = {
|
|
41
|
+
/** REST API adapter for describing objects */
|
|
42
|
+
restApiAdapter: IRestApiAdapter;
|
|
43
|
+
/** Optional logger for debug output */
|
|
44
|
+
logger?: Console;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Service for analyzing Salesforce object fields to identify contact points.
|
|
48
|
+
*
|
|
49
|
+
* Contact points are fields that likely contain personal or contact information
|
|
50
|
+
* such as email addresses, phone numbers, names, and social media identifiers.
|
|
51
|
+
* This service uses field metadata (type and name) to classify fields with
|
|
52
|
+
* high, medium, or low confidence.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* const service = new ContactPointService({ restApiAdapter });
|
|
57
|
+
* const result = await service.analyzeContactPoints('Contact');
|
|
58
|
+
* if (result.success) {
|
|
59
|
+
* result.data.contactPointFields.forEach(f => console.log(f.fieldName, f.contactPointType));
|
|
60
|
+
* }
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare class ContactPointService {
|
|
64
|
+
private readonly restApiAdapter;
|
|
65
|
+
private readonly logger?;
|
|
66
|
+
constructor(config: IContactPointServiceConfig);
|
|
67
|
+
/**
|
|
68
|
+
* Checks whether a field is a system field that should be excluded from analysis.
|
|
69
|
+
*
|
|
70
|
+
* @param fieldName - The API name of the field
|
|
71
|
+
* @returns true if the field is a system field
|
|
72
|
+
*/
|
|
73
|
+
private static isSystemField;
|
|
74
|
+
/**
|
|
75
|
+
* Attempts to classify a field by its Salesforce field type (high confidence).
|
|
76
|
+
*
|
|
77
|
+
* @param field - The field metadata to classify
|
|
78
|
+
* @returns ContactPointField if classified, or undefined if no match
|
|
79
|
+
*/
|
|
80
|
+
private static classifyByFieldType;
|
|
81
|
+
/**
|
|
82
|
+
* Attempts to classify a field by its name using heuristic patterns (medium/low confidence).
|
|
83
|
+
*
|
|
84
|
+
* @param field - The field metadata to classify
|
|
85
|
+
* @returns ContactPointField if classified, or undefined if no match
|
|
86
|
+
*/
|
|
87
|
+
private static classifyByFieldName;
|
|
88
|
+
/**
|
|
89
|
+
* Classifies a single field as a contact point, if applicable.
|
|
90
|
+
*
|
|
91
|
+
* Applies classification in priority order:
|
|
92
|
+
* 1. Skip system fields
|
|
93
|
+
* 2. High confidence: field type matching (email, phone, url)
|
|
94
|
+
* 3. Medium/Low confidence: field name heuristics
|
|
95
|
+
*
|
|
96
|
+
* @param field - The field metadata to classify
|
|
97
|
+
* @returns ContactPointField if classified, or undefined if not a contact point
|
|
98
|
+
*/
|
|
99
|
+
private static classifyField;
|
|
100
|
+
/**
|
|
101
|
+
* Analyzes a Salesforce object's fields to identify contact point fields.
|
|
102
|
+
*
|
|
103
|
+
* Uses the REST API describe endpoint to retrieve field metadata, then
|
|
104
|
+
* classifies each field based on its type and name to identify fields
|
|
105
|
+
* that likely contain personal or contact information.
|
|
106
|
+
*
|
|
107
|
+
* @param objectName - The Salesforce object API name (e.g., 'Contact', 'Account')
|
|
108
|
+
* @returns ServiceResult containing the ContactPointAnalysis
|
|
109
|
+
*/
|
|
110
|
+
analyzeContactPoints(objectName: string): Promise<ServiceResult<ContactPointAnalysis>>;
|
|
111
|
+
}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026, PeerNova, Inc. All Rights Reserved.
|
|
3
|
+
* PROPRIETARY AND CONFIDENTIAL. Unauthorized copying, modification,
|
|
4
|
+
* or distribution is strictly prohibited. Use is governed by the
|
|
5
|
+
* Master Subscription Agreement (MSA) between PeerNova, Inc. and the
|
|
6
|
+
* licensee. See LICENSE file in the repo root.
|
|
7
|
+
*/
|
|
8
|
+
import { createSuccessResult, createFailureResult } from '../models/service-result.js';
|
|
9
|
+
import { ServiceErrorCodes } from '../adapters/errors.js';
|
|
10
|
+
import { validateRequiredString, validateObjectName } from './validation.js';
|
|
11
|
+
/**
|
|
12
|
+
* Service for identifying contact point fields within Salesforce objects.
|
|
13
|
+
*
|
|
14
|
+
* Analyzes object field metadata to detect fields that likely contain
|
|
15
|
+
* contact information (email, phone, name, social handles). Uses a
|
|
16
|
+
* combination of field type analysis and naming pattern matching.
|
|
17
|
+
*
|
|
18
|
+
* @design
|
|
19
|
+
* **Classification Strategy**: Uses a two-pass approach:
|
|
20
|
+
* 1. Field type detection (email, phone types are high confidence)
|
|
21
|
+
* 2. Name pattern matching (e.g., fields containing "email", "phone")
|
|
22
|
+
*
|
|
23
|
+
* This dual approach catches both explicitly typed fields and custom
|
|
24
|
+
* text fields that follow naming conventions for contact data.
|
|
25
|
+
*
|
|
26
|
+
* @design
|
|
27
|
+
* **System Field Exclusion**: Excludes audit fields (CreatedById, OwnerId, etc.)
|
|
28
|
+
* to prevent false positives. These are references to users, not contact points.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const service = new ContactPointService({ restApiAdapter, logger: console });
|
|
33
|
+
* const result = await service.analyzeContactPoints('Contact');
|
|
34
|
+
* if (result.success) {
|
|
35
|
+
* console.log(`Found ${result.data.contactPointCount} contact fields`);
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
/**
|
|
40
|
+
* System fields to exclude from contact point analysis.
|
|
41
|
+
*
|
|
42
|
+
* These are audit/metadata fields managed by Salesforce that:
|
|
43
|
+
* - Cannot contain user-provided contact information
|
|
44
|
+
* - Are auto-populated by the platform (not editable by users)
|
|
45
|
+
* - Exist on every object regardless of its purpose
|
|
46
|
+
*
|
|
47
|
+
* Excluding them prevents false positives (e.g., "OwnerId" is not a contact point).
|
|
48
|
+
*/
|
|
49
|
+
const SYSTEM_FIELDS = new Set([
|
|
50
|
+
'Id', // Record identifier (auto-generated)
|
|
51
|
+
'IsDeleted', // Soft delete flag (system-managed)
|
|
52
|
+
'CreatedDate', // Audit timestamp (auto-populated)
|
|
53
|
+
'CreatedById', // Audit user reference (auto-populated)
|
|
54
|
+
'LastModifiedDate', // Audit timestamp (auto-populated)
|
|
55
|
+
'LastModifiedById', // Audit user reference (auto-populated)
|
|
56
|
+
'SystemModstamp', // System timestamp (auto-populated)
|
|
57
|
+
'OwnerId', // Record owner reference (not contact info)
|
|
58
|
+
'RecordTypeId', // Record type reference (not contact info)
|
|
59
|
+
]);
|
|
60
|
+
/**
|
|
61
|
+
* Field name patterns for medium-confidence phone detection.
|
|
62
|
+
*/
|
|
63
|
+
const PHONE_PATTERNS = ['phone', 'fax', 'mobile'];
|
|
64
|
+
/**
|
|
65
|
+
* Field name patterns for low-confidence social media detection.
|
|
66
|
+
*/
|
|
67
|
+
const SOCIAL_PATTERNS = ['twitter', 'facebook', 'linkedin', 'social'];
|
|
68
|
+
/**
|
|
69
|
+
* Field name patterns for medium-confidence URL detection.
|
|
70
|
+
*/
|
|
71
|
+
const URL_PATTERNS = ['website', 'url', 'homepage', 'link'];
|
|
72
|
+
/**
|
|
73
|
+
* Service for analyzing Salesforce object fields to identify contact points.
|
|
74
|
+
*
|
|
75
|
+
* Contact points are fields that likely contain personal or contact information
|
|
76
|
+
* such as email addresses, phone numbers, names, and social media identifiers.
|
|
77
|
+
* This service uses field metadata (type and name) to classify fields with
|
|
78
|
+
* high, medium, or low confidence.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* const service = new ContactPointService({ restApiAdapter });
|
|
83
|
+
* const result = await service.analyzeContactPoints('Contact');
|
|
84
|
+
* if (result.success) {
|
|
85
|
+
* result.data.contactPointFields.forEach(f => console.log(f.fieldName, f.contactPointType));
|
|
86
|
+
* }
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export class ContactPointService {
|
|
90
|
+
restApiAdapter;
|
|
91
|
+
logger;
|
|
92
|
+
constructor(config) {
|
|
93
|
+
this.restApiAdapter = config.restApiAdapter;
|
|
94
|
+
this.logger = config.logger;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Checks whether a field is a system field that should be excluded from analysis.
|
|
98
|
+
*
|
|
99
|
+
* @param fieldName - The API name of the field
|
|
100
|
+
* @returns true if the field is a system field
|
|
101
|
+
*/
|
|
102
|
+
static isSystemField(fieldName) {
|
|
103
|
+
return SYSTEM_FIELDS.has(fieldName);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Attempts to classify a field by its Salesforce field type (high confidence).
|
|
107
|
+
*
|
|
108
|
+
* @param field - The field metadata to classify
|
|
109
|
+
* @returns ContactPointField if classified, or undefined if no match
|
|
110
|
+
*/
|
|
111
|
+
static classifyByFieldType(field) {
|
|
112
|
+
const typeMap = {
|
|
113
|
+
email: 'email',
|
|
114
|
+
phone: 'phone',
|
|
115
|
+
url: 'url',
|
|
116
|
+
};
|
|
117
|
+
const contactPointType = typeMap[field.type];
|
|
118
|
+
if (contactPointType) {
|
|
119
|
+
return {
|
|
120
|
+
fieldName: field.name,
|
|
121
|
+
fieldLabel: field.label,
|
|
122
|
+
fieldType: field.type,
|
|
123
|
+
contactPointType,
|
|
124
|
+
confidence: 'high',
|
|
125
|
+
reason: `Field type is ${field.type}`,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Attempts to classify a field by its name using heuristic patterns (medium/low confidence).
|
|
132
|
+
*
|
|
133
|
+
* @param field - The field metadata to classify
|
|
134
|
+
* @returns ContactPointField if classified, or undefined if no match
|
|
135
|
+
*/
|
|
136
|
+
static classifyByFieldName(field) {
|
|
137
|
+
const lowerName = field.name.toLowerCase();
|
|
138
|
+
// Medium confidence: email by name
|
|
139
|
+
if (lowerName.includes('email')) {
|
|
140
|
+
return {
|
|
141
|
+
fieldName: field.name,
|
|
142
|
+
fieldLabel: field.label,
|
|
143
|
+
fieldType: field.type,
|
|
144
|
+
contactPointType: 'email',
|
|
145
|
+
confidence: 'medium',
|
|
146
|
+
reason: "Field name contains 'email'",
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
// Medium confidence: phone by name
|
|
150
|
+
const phoneMatch = PHONE_PATTERNS.find((pattern) => lowerName.includes(pattern));
|
|
151
|
+
if (phoneMatch) {
|
|
152
|
+
return {
|
|
153
|
+
fieldName: field.name,
|
|
154
|
+
fieldLabel: field.label,
|
|
155
|
+
fieldType: field.type,
|
|
156
|
+
contactPointType: 'phone',
|
|
157
|
+
confidence: 'medium',
|
|
158
|
+
reason: `Field name contains '${phoneMatch}'`,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
// Medium confidence: name fields (must be string type)
|
|
162
|
+
// Check patterns in specificity order: firstname/lastname are more specific than 'name'
|
|
163
|
+
const namePatterns = ['firstname', 'lastname', 'name'];
|
|
164
|
+
const nameMatch = namePatterns.find((pattern) => lowerName.includes(pattern));
|
|
165
|
+
if (nameMatch && field.type === 'string') {
|
|
166
|
+
return {
|
|
167
|
+
fieldName: field.name,
|
|
168
|
+
fieldLabel: field.label,
|
|
169
|
+
fieldType: field.type,
|
|
170
|
+
contactPointType: 'name',
|
|
171
|
+
confidence: 'medium',
|
|
172
|
+
reason: `Field name contains '${nameMatch}'`,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
// Low confidence: social media (check before URL since 'linkedin' contains 'link')
|
|
176
|
+
const socialMatch = SOCIAL_PATTERNS.find((pattern) => lowerName.includes(pattern));
|
|
177
|
+
if (socialMatch) {
|
|
178
|
+
return {
|
|
179
|
+
fieldName: field.name,
|
|
180
|
+
fieldLabel: field.label,
|
|
181
|
+
fieldType: field.type,
|
|
182
|
+
contactPointType: 'social',
|
|
183
|
+
confidence: 'low',
|
|
184
|
+
reason: `Field name contains '${socialMatch}'`,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
// Medium confidence: URL by name
|
|
188
|
+
const urlMatch = URL_PATTERNS.find((pattern) => lowerName.includes(pattern));
|
|
189
|
+
if (urlMatch) {
|
|
190
|
+
return {
|
|
191
|
+
fieldName: field.name,
|
|
192
|
+
fieldLabel: field.label,
|
|
193
|
+
fieldType: field.type,
|
|
194
|
+
contactPointType: 'url',
|
|
195
|
+
confidence: 'medium',
|
|
196
|
+
reason: `Field name contains '${urlMatch}'`,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
return undefined;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Classifies a single field as a contact point, if applicable.
|
|
203
|
+
*
|
|
204
|
+
* Applies classification in priority order:
|
|
205
|
+
* 1. Skip system fields
|
|
206
|
+
* 2. High confidence: field type matching (email, phone, url)
|
|
207
|
+
* 3. Medium/Low confidence: field name heuristics
|
|
208
|
+
*
|
|
209
|
+
* @param field - The field metadata to classify
|
|
210
|
+
* @returns ContactPointField if classified, or undefined if not a contact point
|
|
211
|
+
*/
|
|
212
|
+
static classifyField(field) {
|
|
213
|
+
if (ContactPointService.isSystemField(field.name)) {
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
216
|
+
return ContactPointService.classifyByFieldType(field) ?? ContactPointService.classifyByFieldName(field);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Analyzes a Salesforce object's fields to identify contact point fields.
|
|
220
|
+
*
|
|
221
|
+
* Uses the REST API describe endpoint to retrieve field metadata, then
|
|
222
|
+
* classifies each field based on its type and name to identify fields
|
|
223
|
+
* that likely contain personal or contact information.
|
|
224
|
+
*
|
|
225
|
+
* @param objectName - The Salesforce object API name (e.g., 'Contact', 'Account')
|
|
226
|
+
* @returns ServiceResult containing the ContactPointAnalysis
|
|
227
|
+
*/
|
|
228
|
+
async analyzeContactPoints(objectName) {
|
|
229
|
+
const startTime = Date.now();
|
|
230
|
+
const emptyResult = {
|
|
231
|
+
objectName: objectName ?? '',
|
|
232
|
+
totalFields: 0,
|
|
233
|
+
contactPointFields: [],
|
|
234
|
+
contactPointCount: 0,
|
|
235
|
+
};
|
|
236
|
+
// Validate required
|
|
237
|
+
const requiredError = validateRequiredString(objectName, 'Object name');
|
|
238
|
+
if (requiredError) {
|
|
239
|
+
return createFailureResult(emptyResult, ServiceErrorCodes.CONTACT_POINT_OBJECT_NAME_REQUIRED, requiredError, {
|
|
240
|
+
metadata: { duration: Date.now() - startTime },
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
// Validate format
|
|
244
|
+
const formatError = validateObjectName(objectName);
|
|
245
|
+
if (formatError) {
|
|
246
|
+
return createFailureResult(emptyResult, ServiceErrorCodes.CONTACT_POINT_INVALID_OBJECT_NAME, formatError, {
|
|
247
|
+
metadata: { duration: Date.now() - startTime },
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
try {
|
|
251
|
+
this.logger?.log(`Analyzing contact points for: ${objectName}`);
|
|
252
|
+
const describeResult = await this.restApiAdapter.describeObject(objectName);
|
|
253
|
+
if (!describeResult.success) {
|
|
254
|
+
return createFailureResult(emptyResult, ServiceErrorCodes.CONTACT_POINT_ANALYSIS_FAILED, describeResult.message ?? 'Object describe failed', { metadata: { duration: Date.now() - startTime } });
|
|
255
|
+
}
|
|
256
|
+
const fields = describeResult.data.fields;
|
|
257
|
+
const contactPointFields = [];
|
|
258
|
+
for (const field of fields) {
|
|
259
|
+
const classified = ContactPointService.classifyField(field);
|
|
260
|
+
if (classified) {
|
|
261
|
+
contactPointFields.push(classified);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
const analysis = {
|
|
265
|
+
objectName,
|
|
266
|
+
totalFields: fields.length,
|
|
267
|
+
contactPointFields,
|
|
268
|
+
contactPointCount: contactPointFields.length,
|
|
269
|
+
};
|
|
270
|
+
const duration = Date.now() - startTime;
|
|
271
|
+
this.logger?.log(`Found ${contactPointFields.length} contact point fields out of ${fields.length} total for ${objectName}`);
|
|
272
|
+
return createSuccessResult(analysis, {
|
|
273
|
+
message: `Found ${contactPointFields.length} contact point fields for ${objectName}`,
|
|
274
|
+
metadata: { duration },
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
279
|
+
this.logger?.log(`Contact point analysis failed: ${errorMessage}`);
|
|
280
|
+
return createFailureResult(emptyResult, ServiceErrorCodes.CONTACT_POINT_ANALYSIS_FAILED, errorMessage, {
|
|
281
|
+
metadata: { duration: Date.now() - startTime },
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
//# sourceMappingURL=ContactPointService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContactPointService.js","sourceRoot":"","sources":["../../src/services/ContactPointService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { type ServiceResult } from '../models/service-result.js';
|
|
2
|
+
import type { YearRange } from '../models/year-range.js';
|
|
3
|
+
import type { ISoqlQueryAdapter } from '../adapters/soql/soql-query-adapter.js';
|
|
4
|
+
/**
|
|
5
|
+
* Per-object availability result for a single year.
|
|
6
|
+
*/
|
|
7
|
+
export type YearAvailability = {
|
|
8
|
+
/** The year checked */
|
|
9
|
+
readonly year: number;
|
|
10
|
+
/** Whether data exists in this year (records created in this calendar year) */
|
|
11
|
+
readonly hasData: boolean;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Per-object availability row in the grid.
|
|
15
|
+
*/
|
|
16
|
+
export type AvailabilityRow = {
|
|
17
|
+
/** Salesforce object API name */
|
|
18
|
+
readonly objectApiName: string;
|
|
19
|
+
/** Oldest record year (minimum CALENDAR_YEAR from GROUP BY results), or null if no records exist */
|
|
20
|
+
readonly oldestYear: number | null;
|
|
21
|
+
/** Per-year data availability flags */
|
|
22
|
+
readonly years: readonly YearAvailability[];
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Complete availability grid result.
|
|
26
|
+
*/
|
|
27
|
+
export type AvailabilityGrid = {
|
|
28
|
+
/** Column headers: the years checked (from YearRange entries) */
|
|
29
|
+
readonly yearColumns: readonly number[];
|
|
30
|
+
/** Per-object rows */
|
|
31
|
+
readonly rows: readonly AvailabilityRow[];
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Configuration for DataAvailabilityService.
|
|
35
|
+
*/
|
|
36
|
+
export type DataAvailabilityServiceConfig = {
|
|
37
|
+
/** SOQL query adapter for executing probes */
|
|
38
|
+
readonly soqlAdapter: ISoqlQueryAdapter;
|
|
39
|
+
/** Number of objects to process concurrently per batch (default: 5) */
|
|
40
|
+
readonly concurrencyLimit?: number;
|
|
41
|
+
/** Optional logger */
|
|
42
|
+
readonly logger?: Console;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Service that builds a data availability grid for objects across a year range.
|
|
46
|
+
*
|
|
47
|
+
* Uses a single CALENDAR_YEAR(CreatedDate) GROUP BY query per object, which returns
|
|
48
|
+
* all years with data in one round-trip. This replaces the previous approach of
|
|
49
|
+
* Y+1 queries per object (one probe per year + one MIN(CreatedDate) for oldest).
|
|
50
|
+
*
|
|
51
|
+
* Objects are processed in batched parallel groups (default: 5 concurrent).
|
|
52
|
+
* API call count: 1 per object (vs. N×(Y+1) in the sequential pre-fix approach).
|
|
53
|
+
*/
|
|
54
|
+
export declare class DataAvailabilityService {
|
|
55
|
+
private readonly soqlAdapter;
|
|
56
|
+
private readonly concurrencyLimit;
|
|
57
|
+
private readonly logger?;
|
|
58
|
+
constructor(config: DataAvailabilityServiceConfig);
|
|
59
|
+
/**
|
|
60
|
+
* Builds a data availability grid for the given objects and year range.
|
|
61
|
+
*
|
|
62
|
+
* @param objectNames - Salesforce object API names to check
|
|
63
|
+
* @param yearRange - The year range to check (from resolveYearRange)
|
|
64
|
+
* @returns Grid with per-object, per-year presence flags and oldest record year
|
|
65
|
+
*/
|
|
66
|
+
buildGrid(objectNames: string[], yearRange: YearRange): Promise<ServiceResult<AvailabilityGrid>>;
|
|
67
|
+
/**
|
|
68
|
+
* Builds a single row for one object using a single CALENDAR_YEAR GROUP BY query.
|
|
69
|
+
* Derives both per-year presence flags and the oldest year from one round-trip.
|
|
70
|
+
*/
|
|
71
|
+
private buildRowForObject;
|
|
72
|
+
/**
|
|
73
|
+
* Issues a single CALENDAR_YEAR(CreatedDate) GROUP BY query for an object.
|
|
74
|
+
*
|
|
75
|
+
* Returns a year → hasData map and the oldest year (minimum year in results).
|
|
76
|
+
* Returns empty map and null oldestYear when no records exist or query fails.
|
|
77
|
+
*
|
|
78
|
+
* Single query replaces Y+1 separate probes per object (CLI-1513 optimization).
|
|
79
|
+
*/
|
|
80
|
+
private queryYearAvailabilityByGroupBy;
|
|
81
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026, PeerNova, Inc. All Rights Reserved.
|
|
3
|
+
* PROPRIETARY AND CONFIDENTIAL. Unauthorized copying, modification,
|
|
4
|
+
* or distribution is strictly prohibited. Use is governed by the
|
|
5
|
+
* Master Subscription Agreement (MSA) between PeerNova, Inc. and the
|
|
6
|
+
* licensee. See LICENSE file in the repo root.
|
|
7
|
+
*/
|
|
8
|
+
import { createSuccessResult, createFailureResult } from '../models/service-result.js';
|
|
9
|
+
import { ServiceErrorCodes, sanitizeSoqlIdentifier } from '../adapters/errors.js';
|
|
10
|
+
import { CuneiformQueryBuilder } from '../adapters/soql/cuneiform-query-builder.js';
|
|
11
|
+
import { processInBatches } from '../utils/batch-processor.js';
|
|
12
|
+
/** Default number of objects to process concurrently in each batch. */
|
|
13
|
+
const DEFAULT_CONCURRENCY_LIMIT = 5;
|
|
14
|
+
/**
|
|
15
|
+
* Service that builds a data availability grid for objects across a year range.
|
|
16
|
+
*
|
|
17
|
+
* Uses a single CALENDAR_YEAR(CreatedDate) GROUP BY query per object, which returns
|
|
18
|
+
* all years with data in one round-trip. This replaces the previous approach of
|
|
19
|
+
* Y+1 queries per object (one probe per year + one MIN(CreatedDate) for oldest).
|
|
20
|
+
*
|
|
21
|
+
* Objects are processed in batched parallel groups (default: 5 concurrent).
|
|
22
|
+
* API call count: 1 per object (vs. N×(Y+1) in the sequential pre-fix approach).
|
|
23
|
+
*/
|
|
24
|
+
export class DataAvailabilityService {
|
|
25
|
+
soqlAdapter;
|
|
26
|
+
concurrencyLimit;
|
|
27
|
+
logger;
|
|
28
|
+
constructor(config) {
|
|
29
|
+
this.soqlAdapter = config.soqlAdapter;
|
|
30
|
+
this.concurrencyLimit = config.concurrencyLimit ?? DEFAULT_CONCURRENCY_LIMIT;
|
|
31
|
+
this.logger = config.logger;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Builds a data availability grid for the given objects and year range.
|
|
35
|
+
*
|
|
36
|
+
* @param objectNames - Salesforce object API names to check
|
|
37
|
+
* @param yearRange - The year range to check (from resolveYearRange)
|
|
38
|
+
* @returns Grid with per-object, per-year presence flags and oldest record year
|
|
39
|
+
*/
|
|
40
|
+
async buildGrid(objectNames, yearRange) {
|
|
41
|
+
const startTime = Date.now();
|
|
42
|
+
if (objectNames.length === 0 || yearRange.entries.length === 0) {
|
|
43
|
+
return createSuccessResult({ yearColumns: yearRange.entries.map((e) => e.year), rows: [] }, { message: 'No objects or years to check', metadata: { duration: Date.now() - startTime } });
|
|
44
|
+
}
|
|
45
|
+
const yearColumns = yearRange.entries.map((e) => e.year);
|
|
46
|
+
try {
|
|
47
|
+
this.logger?.log(`Processing ${objectNames.length} objects in batches of ${this.concurrencyLimit}`);
|
|
48
|
+
const rows = await processInBatches(objectNames, this.concurrencyLimit, (objectName) => this.buildRowForObject(objectName, yearRange.entries));
|
|
49
|
+
const duration = Date.now() - startTime;
|
|
50
|
+
const gapCount = rows.reduce((sum, r) => sum + r.years.filter((y) => !y.hasData).length, 0);
|
|
51
|
+
this.logger?.log(`Availability grid: ${rows.length} objects × ${yearColumns.length} years, ${gapCount} gaps in ${duration}ms`);
|
|
52
|
+
return createSuccessResult({ yearColumns, rows }, {
|
|
53
|
+
message: `Checked ${rows.length} objects across ${yearColumns.length} years`,
|
|
54
|
+
metadata: {
|
|
55
|
+
duration,
|
|
56
|
+
apiCallCount: rows.length,
|
|
57
|
+
concurrencyLimit: this.concurrencyLimit,
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
return createFailureResult({ yearColumns, rows: [] }, ServiceErrorCodes.DATA_AVAILABILITY_GRID_BUILD_FAILED, `Availability grid failed: ${error instanceof Error ? error.message : String(error)}`, { metadata: { duration: Date.now() - startTime } });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Builds a single row for one object using a single CALENDAR_YEAR GROUP BY query.
|
|
67
|
+
* Derives both per-year presence flags and the oldest year from one round-trip.
|
|
68
|
+
*/
|
|
69
|
+
async buildRowForObject(objectName, entries) {
|
|
70
|
+
const { yearMap, oldestYear } = await this.queryYearAvailabilityByGroupBy(objectName);
|
|
71
|
+
const years = entries.map((entry) => ({
|
|
72
|
+
year: entry.year,
|
|
73
|
+
hasData: yearMap.get(entry.year) ?? false,
|
|
74
|
+
}));
|
|
75
|
+
return {
|
|
76
|
+
objectApiName: objectName,
|
|
77
|
+
oldestYear,
|
|
78
|
+
years,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Issues a single CALENDAR_YEAR(CreatedDate) GROUP BY query for an object.
|
|
83
|
+
*
|
|
84
|
+
* Returns a year → hasData map and the oldest year (minimum year in results).
|
|
85
|
+
* Returns empty map and null oldestYear when no records exist or query fails.
|
|
86
|
+
*
|
|
87
|
+
* Single query replaces Y+1 separate probes per object (CLI-1513 optimization).
|
|
88
|
+
*/
|
|
89
|
+
async queryYearAvailabilityByGroupBy(objectName) {
|
|
90
|
+
let soql;
|
|
91
|
+
try {
|
|
92
|
+
// sanitizeSoqlIdentifier rejects anything that isn't a valid Salesforce API name
|
|
93
|
+
// (^[A-Za-z][A-Za-z0-9_]*$). Quote characters, spaces, and SOQL comment markers
|
|
94
|
+
// all fail the regex and throw before the query is built.
|
|
95
|
+
const sanitizedObject = sanitizeSoqlIdentifier(objectName);
|
|
96
|
+
soql = new CuneiformQueryBuilder()
|
|
97
|
+
.select(['CALENDAR_YEAR(CreatedDate) yr', 'COUNT(Id) cnt'])
|
|
98
|
+
.from(sanitizedObject)
|
|
99
|
+
.andWhereNull('CreatedDate', false)
|
|
100
|
+
.groupBy(['CALENDAR_YEAR(CreatedDate)'])
|
|
101
|
+
.toSOQL();
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
this.logger?.log(`GROUP BY availability query rejected: invalid object name "${objectName}"`);
|
|
105
|
+
return { yearMap: new Map(), oldestYear: null };
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
const result = await this.soqlAdapter.query(soql);
|
|
109
|
+
if (!result.success || result.data.records.length === 0) {
|
|
110
|
+
return { yearMap: new Map(), oldestYear: null };
|
|
111
|
+
}
|
|
112
|
+
const yearMap = new Map();
|
|
113
|
+
let minYear = null;
|
|
114
|
+
for (const record of result.data.records) {
|
|
115
|
+
yearMap.set(record.yr, record.cnt > 0);
|
|
116
|
+
if (minYear === null || record.yr < minYear) {
|
|
117
|
+
minYear = record.yr;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return { yearMap, oldestYear: minYear };
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
this.logger?.log(`GROUP BY availability query failed for ${objectName}`);
|
|
124
|
+
return { yearMap: new Map(), oldestYear: null };
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=DataAvailabilityService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataAvailabilityService.js","sourceRoot":"","sources":["../../src/services/DataAvailabilityService.ts"],"names":[],"mappings":"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"}
|