@lowdefy/server-dev 6.1.0 → 7.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/client/App.jsx +52 -24
- package/client/Inspector.jsx +73 -30
- package/client/JourneyObserver.jsx +47 -0
- package/client/Page.jsx +54 -22
- package/client/Recorder.jsx +73 -0
- package/client/Routing.jsx +37 -13
- package/client/clientBuildImports.test.mjs +2 -0
- package/client/devStreamConnections.test.mjs +40 -0
- package/client/feedback/FeedbackMount.jsx +2 -2
- package/client/feedback/FeedbackOverlay.jsx +7 -4
- package/client/feedback/feedbackStyles.js +3 -0
- package/client/journeyObserver/startJourneyObserver.js +101 -0
- package/client/journeyObserver/startJourneyObserver.test.mjs +149 -0
- package/client/openInEditor/OpenInEditorListener.jsx +2 -0
- package/client/recorder/buildEngineRecord.js +37 -0
- package/client/recorder/buildInteractionRecord.js +64 -0
- package/client/recorder/buildTraceEvent.js +57 -0
- package/client/recorder/buildTraceEvent.test.mjs +81 -0
- package/client/recorder/chunkRecords.js +69 -0
- package/client/recorder/chunkRecords.test.mjs +59 -0
- package/client/recorder/collectEventActions.js +30 -0
- package/client/recorder/collectEventEndpoints.js +40 -0
- package/client/recorder/collectEventRequests.js +39 -0
- package/client/recorder/createPairingBuffer.js +187 -0
- package/client/recorder/createPairingBuffer.test.mjs +405 -0
- package/client/recorder/createPasswordRedactor.js +84 -0
- package/client/recorder/createRecordBatcher.js +54 -0
- package/client/recorder/createRecordBatcher.test.mjs +76 -0
- package/client/recorder/createRecorder.js +216 -0
- package/client/recorder/createRecorder.test.mjs +318 -0
- package/client/recorder/createRecordingSession.js +61 -0
- package/client/recorder/createRecordingSession.test.mjs +72 -0
- package/client/recorder/diffStateWrites.js +77 -0
- package/client/recorder/diffStateWrites.test.mjs +66 -0
- package/client/recorder/isEventCall.js +30 -0
- package/client/recorder/jsonType.js +39 -0
- package/client/recorder/keyChord.js +47 -0
- package/client/recorder/keyChord.test.mjs +50 -0
- package/client/recorder/sendRecords.js +40 -0
- package/client/recorder/toJsonSafe.js +29 -0
- package/lib/client/BuildingPage.jsx +3 -1
- package/lib/client/ErrorBar.jsx +17 -13
- package/lib/client/RedirectingPage.jsx +56 -0
- package/lib/client/auth/Auth.jsx +11 -6
- package/lib/client/auth/AuthConfigured.jsx +222 -36
- package/lib/client/auth/AuthNotConfigured.js +45 -4
- package/lib/client/auth/authNotConfiguredParity.test.mjs +61 -0
- package/lib/client/auth/authTemplateSync.test.mjs +40 -0
- package/lib/client/auth/betterAuthSessionContract.test.mjs +181 -0
- package/lib/client/auth/createFetchCheckingBuild.js +45 -0
- package/lib/client/bundleBuildId.js +25 -0
- package/lib/client/collectVisibleBlockIds.js +51 -0
- package/lib/client/getCspNonce.js +25 -0
- package/lib/client/getPagePath.js +36 -0
- package/lib/client/getPagePath.test.mjs +51 -0
- package/lib/client/utils/formatErrorsForCopy.js +30 -0
- package/lib/client/utils/formatErrorsForCopy.test.mjs +39 -0
- package/lib/client/utils/getErrorBarColor.js +25 -0
- package/lib/client/utils/getErrorBarColor.test.mjs +34 -0
- package/lib/client/utils/request.js +8 -1
- package/lib/client/utils/usePageConfig.js +89 -25
- package/lib/client/utils/usePageConfig.test.mjs +198 -13
- package/lib/configTree/buildConfigTree.mjs +58 -0
- package/lib/configTree/buildConfigTree.test.mjs +77 -0
- package/lib/configTree/collectConfigText.mjs +101 -0
- package/lib/configTree/collectConfigText.test.mjs +116 -0
- package/lib/configTree/prepareScratchServer.mjs +46 -0
- package/lib/configTree/runConfigTreeBuild.mjs +88 -0
- package/lib/configTree/runConfigTreeBuild.skipPluginChecks.test.mjs +74 -0
- package/lib/configTree/runConfigTreeBuild.test.mjs +202 -0
- package/lib/docs/JourneyStepError.js +30 -0
- package/lib/docs/acquireBrowserSlot.js +30 -0
- package/lib/docs/addNestedEndpoints.js +54 -0
- package/lib/docs/addNestedEndpoints.test.mjs +185 -0
- package/lib/docs/addWriteFlags.js +77 -0
- package/lib/docs/buildEditedPages.js +50 -0
- package/lib/docs/buildWaitHeader.js +21 -0
- package/lib/docs/captureAnnotatedScreenshot.js +23 -12
- package/lib/docs/checkAgentFiles.js +148 -0
- package/lib/docs/checkAgentFiles.test.mjs +225 -0
- package/lib/docs/checkStepReferences.js +239 -0
- package/lib/docs/checkStepReferences.test.mjs +173 -0
- package/lib/docs/checkpointStore.js +3 -0
- package/lib/docs/clientErrorStore.js +18 -1
- package/lib/docs/clientErrorStore.test.mjs +46 -0
- package/lib/docs/collectExercised.js +52 -0
- package/lib/docs/createBrowserLifecycle.js +102 -0
- package/lib/docs/createBrowserLifecycle.test.mjs +212 -0
- package/lib/docs/createDocsMcpServer.js +345 -388
- package/lib/docs/createDocsMcpServer.test.mjs +644 -4
- package/lib/docs/createDocsMcpServerRunJourney.test.mjs +148 -0
- package/lib/docs/createJourneyActors.chromium.test.mjs +227 -0
- package/lib/docs/createJourneyActors.js +213 -0
- package/lib/docs/createJourneyActors.test.mjs +79 -0
- package/lib/docs/createJourneyObservations.js +80 -0
- package/lib/docs/createLeftOriginError.js +26 -0
- package/lib/docs/createNetworkCounter.js +101 -0
- package/lib/docs/dataSets/checkSharedCollectionIds.js +67 -0
- package/lib/docs/dataSets/dataSessionRegistry.js +25 -0
- package/lib/docs/dataSets/dataSetJourneys.chromium.mongodb.test.mjs +679 -0
- package/lib/docs/dataSets/describeDataSetResult.js +25 -0
- package/lib/docs/dataSets/describeDatabaseTarget.js +46 -0
- package/lib/docs/dataSets/deserializeFixture.js +34 -0
- package/lib/docs/dataSets/drainSessionWork.js +37 -0
- package/lib/docs/dataSets/drainSessionWork.test.mjs +64 -0
- package/lib/docs/dataSets/duplicateIndexName.js +24 -0
- package/lib/docs/dataSets/findCollectionCollisions.js +52 -0
- package/lib/docs/dataSets/getDataStore.js +106 -0
- package/lib/docs/dataSets/getDataStore.mongodb.test.mjs +63 -0
- package/lib/docs/dataSets/getDataStore.test.mjs +195 -0
- package/lib/docs/dataSets/groupDataSetByCollection.js +44 -0
- package/lib/docs/dataSets/insertFixture.js +57 -0
- package/lib/docs/dataSets/insertGeneratedDocuments.js +41 -0
- package/lib/docs/dataSets/isDataStoreGone.js +29 -0
- package/lib/docs/dataSets/loadDataSetCollection.js +42 -0
- package/lib/docs/dataSets/mergeCollectionIndexes.js +52 -0
- package/lib/docs/dataSets/mergeCollectionIndexes.test.mjs +59 -0
- package/lib/docs/dataSets/openDataSession.js +119 -0
- package/lib/docs/dataSets/openDataSession.mongodb.test.mjs +343 -0
- package/lib/docs/dataSets/pickDataStorePort.js +58 -0
- package/lib/docs/dataSets/pickDataStorePort.test.mjs +63 -0
- package/lib/docs/dataSets/readConnectionArtifacts.js +46 -0
- package/lib/docs/dataSets/readDataSession.js +41 -0
- package/lib/docs/dataSets/readDataSession.test.mjs +57 -0
- package/lib/docs/dataSets/readDataSet.js +68 -0
- package/lib/docs/dataSets/readDataSet.test.mjs +220 -0
- package/lib/docs/dataSets/registerDataStoreShutdown.js +47 -0
- package/lib/docs/dataSets/removeDataStoreFiles.js +32 -0
- package/lib/docs/dataSets/resolveDataSetCollection.js +46 -0
- package/lib/docs/dataSets/resolveJourneyDataSet.js +106 -0
- package/lib/docs/dataSets/resolveJourneyDataSet.test.mjs +130 -0
- package/lib/docs/dataSets/sweepOrphanDatabases.js +33 -0
- package/lib/docs/dataSets/test/app/lowdefy.yaml +203 -0
- package/lib/docs/dataSets/test/app/modules/archive/module.lowdefy.yaml +30 -0
- package/lib/docs/dataSets/test/app/tests/data/shop.yaml +8 -0
- package/lib/docs/dataSets/test/buildTestApp.mjs +43 -0
- package/lib/docs/devEventBus.js +136 -0
- package/lib/docs/devEventBus.test.mjs +269 -0
- package/lib/docs/devToolDefinitions.js +529 -0
- package/lib/docs/docSources.js +21 -0
- package/lib/docs/docs.test.mjs +171 -15
- package/lib/docs/docsIndex.test.mjs +377 -0
- package/lib/docs/evalOperator.js +5 -3
- package/lib/docs/evalOperatorHeadless.js +84 -12
- package/lib/docs/evalOperatorHeadless.test.mjs +7 -1
- package/lib/docs/evalOperatorInTab.js +2 -1
- package/lib/docs/findConfig.js +95 -49
- package/lib/docs/fitResponse.js +81 -0
- package/lib/docs/fitResponse.test.mjs +128 -0
- package/lib/docs/formatFeedback.js +26 -5
- package/lib/docs/formatFeedback.test.mjs +48 -0
- package/lib/docs/getAppMap.js +7 -1
- package/lib/docs/getBrowser.js +150 -80
- package/lib/docs/getBrowser.test.mjs +407 -16
- package/lib/docs/getBuildId.js +61 -0
- package/lib/docs/getBuildId.test.mjs +84 -0
- package/lib/docs/getBuildStatus.js +54 -6
- package/lib/docs/getBuildStatus.test.mjs +133 -0
- package/lib/docs/getBuildStatusAfterEdits.js +35 -0
- package/lib/docs/getBuildStatusAfterEdits.test.mjs +76 -0
- package/lib/docs/getCoreDoc.js +9 -1
- package/lib/docs/getDoc.js +100 -0
- package/lib/docs/getDocsIndex.js +152 -0
- package/lib/docs/getHazards.js +115 -0
- package/lib/docs/getHazards.test.mjs +175 -0
- package/lib/docs/getMailOutboxDirectory.js +26 -0
- package/lib/docs/getOverview.js +79 -13
- package/lib/docs/getOverviewBasePath.test.mjs +37 -0
- package/lib/docs/getPageBuildStatus.js +46 -0
- package/lib/docs/getPluginDoc.js +21 -23
- package/lib/docs/getSchema.js +33 -1
- package/lib/docs/getStaleStatus.js +36 -0
- package/lib/docs/getStaleStatus.test.mjs +74 -0
- package/lib/docs/guardJourneyOrigin.js +39 -0
- package/lib/docs/inspectState.js +5 -3
- package/lib/docs/inspectStateFromTab.js +2 -2
- package/lib/docs/inspectStateHeadless.js +89 -27
- package/lib/docs/inspectStateHeadless.test.mjs +20 -1
- package/lib/docs/installHeadlessShell.failure.test.mjs +45 -0
- package/lib/docs/installHeadlessShell.js +123 -0
- package/lib/docs/installHeadlessShell.test.mjs +70 -0
- package/lib/docs/installHeadlessShell.timeout.test.mjs +72 -0
- package/lib/docs/isHeadlessShellIncomplete.js +34 -0
- package/lib/docs/isHeadlessShellIncomplete.test.mjs +63 -0
- package/lib/docs/isPageReady.js +77 -0
- package/lib/docs/isPageReady.test.mjs +235 -0
- package/lib/docs/isRunErrorEntry.js +25 -0
- package/lib/docs/journeyMutantCookie.chromium.test.mjs +150 -0
- package/lib/docs/journeyRunRecording.js +35 -0
- package/lib/docs/journeyRunRecording.test.mjs +39 -0
- package/lib/docs/keepEventStreamAlive.js +68 -0
- package/lib/docs/keepEventStreamAlive.test.mjs +77 -0
- package/lib/docs/launchBrowser.js +83 -0
- package/lib/docs/launchBrowser.test.mjs +175 -0
- package/lib/docs/listModuleDocEntries.js +69 -0
- package/lib/docs/listPackageDocFiles.js +67 -0
- package/lib/docs/listPluginDocEntries.js +111 -0
- package/lib/docs/listPlugins.js +9 -58
- package/lib/docs/listTypes.js +14 -6
- package/lib/docs/loadFrameworkHazards.js +40 -0
- package/lib/docs/loadFrameworkHazards.test.mjs +43 -0
- package/lib/docs/loadState.js +103 -35
- package/lib/docs/makeModuleManifestDoc.js +174 -0
- package/lib/docs/matchExercisedPages.js +35 -0
- package/lib/docs/matchJourneyRoute.js +69 -0
- package/lib/docs/matchJourneyRoute.test.mjs +178 -0
- package/lib/docs/mergeNetworkSnapshots.js +49 -0
- package/lib/docs/nextJourneySequence.js +30 -0
- package/lib/docs/noBrowserError.js +22 -0
- package/lib/docs/observe/TRANSIENT_SELECTOR.js +21 -0
- package/lib/docs/observe/claimExpectedErrors.js +67 -0
- package/lib/docs/observe/createJourneyAppErrors.js +236 -0
- package/lib/docs/observe/createJourneyAppErrors.test.mjs +385 -0
- package/lib/docs/observe/evaluateInvariants.js +183 -0
- package/lib/docs/observe/evaluateInvariants.test.mjs +299 -0
- package/lib/docs/observe/findingKey.js +29 -0
- package/lib/docs/observe/hasNoEffect.js +31 -0
- package/lib/docs/observe/hasNoEffect.test.mjs +37 -0
- package/lib/docs/observe/installStepObserver.js +72 -0
- package/lib/docs/observe/isAppApiUrl.js +33 -0
- package/lib/docs/observe/parseAppApiUrl.js +37 -0
- package/lib/docs/observe/readStepObserver.js +42 -0
- package/lib/docs/observe/relativeSource.js +29 -0
- package/lib/docs/observe/resolveConfigKeySource.js +33 -0
- package/lib/docs/observe/takeJourneyEvents.js +36 -0
- package/lib/docs/observe/toAppErrorFailure.js +61 -0
- package/lib/docs/observe/usesSearchStage.js +45 -0
- package/lib/docs/observe/waitForClientErrorReports.js +31 -0
- package/lib/docs/observe/watchJourneyContext.js +75 -0
- package/lib/docs/observe/withAppErrors.js +31 -0
- package/lib/docs/observe/withAppErrors.test.mjs +101 -0
- package/lib/docs/openJourney.js +94 -0
- package/lib/docs/openJourneyEmail.js +41 -0
- package/lib/docs/openJourneyEmail.test.mjs +187 -0
- package/lib/docs/pageBlocks.js +47 -0
- package/lib/docs/pageBuildStatus.test.mjs +103 -0
- package/lib/{client/setPageId.js → docs/parseModuleSource.js} +11 -12
- package/lib/docs/rails/authEngineActions.js +53 -0
- package/lib/docs/rails/authEngineActions.test.mjs +69 -0
- package/lib/docs/rails/authEngineMethods.js +52 -0
- package/lib/docs/rails/authEngineMethods.test.mjs +36 -0
- package/lib/docs/rails/checkAuthActionsRan.js +66 -0
- package/lib/docs/rails/checkAuthActionsRan.test.mjs +149 -0
- package/lib/docs/rails/checkClickRails.js +56 -0
- package/lib/docs/rails/createDataSetRails.js +82 -0
- package/lib/docs/rails/createDataSetRails.test.mjs +172 -0
- package/lib/docs/rails/findExternalBlocks.js +147 -0
- package/lib/docs/rails/findExternalBlocks.test.mjs +254 -0
- package/lib/docs/rails/installAuthActionRecorder.js +56 -0
- package/lib/docs/rails/readAuthActionRecorder.js +32 -0
- package/lib/docs/rails/readBuiltArtifact.js +30 -0
- package/lib/docs/readConnectionPlugins.js +26 -0
- package/lib/docs/readDevAuthMode.js +32 -0
- package/lib/docs/readDocEntry.js +40 -0
- package/lib/docs/readDocTitle.js +26 -0
- package/lib/docs/readJourneyEmailMatch.js +57 -0
- package/lib/docs/readJourneyEmailMatch.test.mjs +110 -0
- package/lib/docs/readJourneySession.js +56 -0
- package/lib/docs/readMailOutbox.js +37 -0
- package/lib/docs/readPagePath.js +27 -0
- package/lib/docs/readPluginPackages.js +99 -0
- package/lib/docs/readProxyBuildWait.js +38 -0
- package/lib/docs/readRoutineSteps.js +45 -0
- package/lib/docs/registerShownTextEngine.js +118 -0
- package/lib/docs/requestRestart.js +30 -0
- package/lib/docs/requestRestart.test.mjs +49 -0
- package/lib/docs/resolvePageInstance.js +46 -0
- package/lib/docs/resolvePageInstance.test.mjs +81 -0
- package/lib/docs/resolveSource.js +11 -7
- package/lib/docs/resolveSource.test.mjs +1 -1
- package/lib/docs/resolveToolCaller.js +62 -0
- package/lib/docs/reviewPage.js +51 -0
- package/lib/docs/reviewPageBuilds.js +56 -0
- package/lib/docs/reviewPageBuilds.test.mjs +207 -0
- package/lib/docs/runCheck.js +75 -0
- package/lib/docs/runCheck.test.mjs +91 -0
- package/lib/docs/runCheckChild.js +49 -0
- package/lib/docs/runEndpoint.js +185 -0
- package/lib/docs/runEndpoint.test.mjs +509 -0
- package/lib/docs/runErrorBuffers.js +99 -0
- package/lib/docs/runErrorBuffers.test.mjs +95 -0
- package/lib/docs/runJourney.js +347 -0
- package/lib/docs/runJourney.test.mjs +2383 -0
- package/lib/docs/runJourneyAsUsers.js +44 -0
- package/lib/docs/runJourneyDataSet.test.mjs +274 -0
- package/lib/docs/runJourneySteps.js +1320 -0
- package/lib/docs/runRequest.js +100 -59
- package/lib/docs/runRequest.test.mjs +190 -0
- package/lib/docs/saveAnnotatedScreenshot.js +1 -1
- package/lib/docs/scaffoldPage.js +3 -1
- package/lib/docs/screenshotPage.js +163 -11
- package/lib/docs/screenshotPage.test.mjs +263 -1
- package/lib/docs/screenshotPageClip.test.mjs +4 -0
- package/lib/docs/searchDocs.js +82 -30
- package/lib/docs/searchDocs.test.mjs +100 -0
- package/lib/docs/searchIcons.js +90 -0
- package/lib/docs/searchIcons.test.mjs +127 -0
- package/lib/docs/selectExercised.js +39 -0
- package/lib/docs/selectFinalState.js +66 -0
- package/lib/docs/selectFinalState.test.mjs +51 -0
- package/lib/docs/serverErrorStore.js +54 -0
- package/lib/docs/serverErrorStore.test.mjs +50 -0
- package/lib/docs/setupTestFixtures.mjs +133 -39
- package/lib/docs/shownTextSelector.js +28 -0
- package/lib/docs/snapshotState.js +13 -5
- package/lib/docs/splitSearchTerms.js +62 -0
- package/lib/docs/splitSearchTerms.test.mjs +50 -0
- package/lib/docs/stateCheckpoints.test.mjs +77 -0
- package/lib/docs/tabAvailable.js +6 -5
- package/lib/docs/tabChannel.js +127 -21
- package/lib/docs/tabChannel.test.mjs +187 -29
- package/lib/docs/unsettledPageNote.js +24 -0
- package/lib/docs/validateJourneyMail.js +36 -0
- package/lib/docs/validateJourneyTimeout.js +38 -0
- package/lib/docs/validateJourneyTimeout.test.mjs +29 -0
- package/lib/docs/validateRecordingParam.js +42 -0
- package/lib/docs/validateStateSelection.js +33 -0
- package/lib/docs/validateStateSelection.test.mjs +33 -0
- package/lib/docs/validateViewport.js +51 -0
- package/lib/docs/validateViewport.test.mjs +54 -0
- package/lib/docs/waitForBuild.js +50 -0
- package/lib/docs/waitForBuild.test.mjs +75 -0
- package/lib/docs/waitForJourneyEmail.js +77 -0
- package/lib/docs/withBrowserSlot.js +45 -0
- package/lib/docs/withBrowserSlot.test.mjs +75 -0
- package/lib/docs/withDataSession.js +53 -0
- package/lib/server/applyDataSetRedirect.js +83 -0
- package/lib/server/applyDataSetRedirect.test.mjs +340 -0
- package/lib/server/applyDataSetRedirectTenantReach.test.mjs +204 -0
- package/lib/server/applyDataSetRedirectWalled.test.mjs +131 -0
- package/lib/server/auth/createSystemContext.js +73 -0
- package/lib/server/auth/{getAuthConfig.js → getAuth.js} +15 -9
- package/lib/server/auth/getHeadlessUser.js +9 -8
- package/lib/server/auth/getHeadlessUser.test.mjs +41 -0
- package/lib/server/auth/getMockUser.js +18 -14
- package/lib/server/auth/{session.js → getStrategies.js} +17 -16
- package/lib/server/auth/headlessUser.js +3 -2
- package/lib/server/auth/journeyActor.js +35 -0
- package/lib/server/auth/resolveHeadlessUser.test.mjs +0 -4
- package/lib/server/checkPageRecord.js +44 -0
- package/lib/server/contextMapBudget.js +24 -0
- package/lib/server/contextMapBudget.test.mjs +98 -0
- package/lib/server/continueJitKeys.js +28 -0
- package/lib/server/continueJitKeys.test.mjs +43 -0
- package/lib/server/createDataSessionEndedError.js +33 -0
- package/lib/server/createDataSetRefusal.js +26 -0
- package/lib/server/createLowdefyContext.js +168 -41
- package/lib/server/createLowdefyContext.test.mjs +328 -8
- package/lib/server/getClientAddress.js +51 -0
- package/lib/server/getClientAddress.test.mjs +56 -0
- package/lib/server/getPageJitEnrichment.test.mjs +29 -11
- package/lib/server/hashConfigContent.js +26 -0
- package/lib/server/importAppCode.test.mjs +57 -0
- package/lib/server/isRoutineStep.js +27 -0
- package/lib/server/jitPageBuilder.js +309 -126
- package/lib/server/jitPageBuilder.skipPluginChecks.test.mjs +78 -0
- package/lib/server/jitPageBuilder.test.mjs +218 -0
- package/lib/server/journeyCookies/JOURNEY_COOKIES.js +37 -0
- package/lib/server/journeyCookies/forwardJourneyCookies.js +46 -0
- package/lib/server/journeyCookies/readJourneyCookie.js +52 -0
- package/lib/server/journeyCookies/writeJourneyCookie.js +46 -0
- package/lib/server/journeyCookies.js +22 -0
- package/lib/server/journeyCookies.test.mjs +145 -0
- package/lib/server/loadDynamicJsMap.js +47 -0
- package/lib/server/log/createHandleError.js +38 -2
- package/lib/server/log/createHandleError.test.mjs +125 -2
- package/lib/server/log/createLogger.js +3 -0
- package/lib/server/log/createLogger.test.mjs +15 -0
- package/lib/server/log/logRequest.js +2 -3
- package/lib/server/mutantDataSetWrappers.test.mjs +112 -0
- package/lib/server/mutants/applyMutant.js +39 -0
- package/lib/server/mutants/artifactPatterns.js +25 -0
- package/lib/server/mutants/buildAnchor.js +45 -0
- package/lib/server/mutants/collectSharedIds.js +41 -0
- package/lib/server/mutants/configPathSegments.js +38 -0
- package/lib/server/mutants/createMutantReadConfigFile.js +42 -0
- package/lib/server/mutants/describeEvent.js +22 -0
- package/lib/server/mutants/enumerateArtifact.js +56 -0
- package/lib/server/mutants/findNodeByKey.js +45 -0
- package/lib/server/mutants/findNodeByPointer.js +49 -0
- package/lib/server/mutants/getArtifactKind.js +32 -0
- package/lib/server/mutants/groupMutantCopies.js +56 -0
- package/lib/server/mutants/hashArtifact.js +25 -0
- package/lib/server/mutants/hashMutantTarget.js +34 -0
- package/lib/server/mutants/listMutants.js +122 -0
- package/lib/server/mutants/listMutants.test.mjs +502 -0
- package/lib/server/mutants/mutantId.js +30 -0
- package/lib/server/mutants/mutantRuns.js +57 -0
- package/lib/server/mutants/mutantRuns.test.mjs +136 -0
- package/lib/server/mutants/operators/dropAction.js +47 -0
- package/lib/server/mutants/operators/dropBlock.js +44 -0
- package/lib/server/mutants/operators/dropPayload.js +52 -0
- package/lib/server/mutants/operators/dropStep.js +44 -0
- package/lib/server/mutants/operators/flipVisible.js +53 -0
- package/lib/server/mutants/operators/index.js +37 -0
- package/lib/server/mutants/operators/retargetLink.js +72 -0
- package/lib/server/mutants/operators/skipValidate.js +77 -0
- package/lib/server/mutants/operators/swapIf.js +112 -0
- package/lib/server/mutants/operators.test.mjs +396 -0
- package/lib/server/mutants/positionFreePath.js +38 -0
- package/lib/server/mutants/removeFromParent.js +28 -0
- package/lib/server/mutants/test/fixtures.mjs +173 -0
- package/lib/server/mutants/test/keyArtifact.mjs +63 -0
- package/lib/server/mutants/validateMutantParam.js +69 -0
- package/lib/server/mutants/validateMutantsBody.js +88 -0
- package/lib/server/mutants/walkArtifact.js +179 -0
- package/lib/server/pageBuildRecords.js +131 -0
- package/lib/server/pageBuildRecords.test.mjs +258 -0
- package/lib/server/pageCache.mjs +22 -7
- package/lib/server/pageCache.test.mjs +22 -7
- package/lib/server/pageRebuilds.test.mjs +543 -0
- package/lib/server/pruneJitMaps.js +36 -0
- package/lib/server/pruneJitMaps.test.mjs +55 -0
- package/lib/server/readInstanceRecord.js +33 -0
- package/lib/server/readInstanceRecord.test.mjs +99 -0
- package/lib/server/readMergedMaps.js +86 -0
- package/lib/server/readMergedMaps.test.mjs +79 -0
- package/lib/server/recording/appendRecords.js +33 -0
- package/lib/server/recording/errorRecordingStamp.js +34 -0
- package/lib/server/recording/errorRecordingStamp.test.mjs +31 -0
- package/lib/server/recording/isRecordingEnabled.js +31 -0
- package/lib/server/recording/readRecordingCookie.js +71 -0
- package/lib/server/recording/readRecordingCookie.test.mjs +73 -0
- package/lib/server/recording/recordingCookiePayload.js +33 -0
- package/lib/server/recording/servedBuilds.js +46 -0
- package/lib/server/recording/servedBuilds.test.mjs +42 -0
- package/lib/server/sinkExternalConnections.js +95 -0
- package/lib/server/sinkExternalConnections.test.mjs +135 -0
- package/lib/server/skipStaleMapWrites.js +62 -0
- package/lib/server/skipStaleMapWrites.test.mjs +113 -0
- package/lib/server/startIdleGc.js +67 -0
- package/lib/server/startIdleGc.test.mjs +138 -0
- package/lib/server/testFixtures/importAppCodeTwice.mjs +70 -0
- package/lib/server/trackSessionWork.js +30 -0
- package/lib/vite/createDevServerExclude.js +40 -0
- package/lib/vite/createDevServerExclude.test.mjs +79 -0
- package/manager/getContext.mjs +24 -2
- package/manager/processes/initialBuild.mjs +14 -0
- package/manager/processes/initialBuild.test.mjs +101 -0
- package/manager/processes/lowdefyBuild.mjs +30 -7
- package/manager/processes/lowdefyBuild.skipPluginChecks.test.mjs +62 -0
- package/manager/processes/lowdefyBuild.test.mjs +136 -1
- package/manager/processes/optimizeDependencies.mjs +59 -0
- package/manager/processes/restartServer.mjs +34 -6
- package/manager/processes/restartServer.test.mjs +162 -0
- package/manager/processes/shutdownServer.mjs +11 -0
- package/manager/processes/shutdownServer.test.mjs +45 -0
- package/manager/processes/startFirstServer.mjs +46 -0
- package/manager/processes/startFirstServer.test.mjs +326 -0
- package/manager/processes/startMailSink.mjs +135 -0
- package/manager/processes/startMailSink.test.mjs +146 -0
- package/manager/processes/startProxy.mjs +129 -12
- package/manager/processes/startProxy.test.mjs +366 -0
- package/manager/processes/startServer.mjs +47 -6
- package/manager/processes/startServer.test.mjs +155 -0
- package/manager/processes/startWatchers.mjs +6 -4
- package/manager/processes/syncServer.mjs +69 -0
- package/manager/processes/syncServer.test.mjs +141 -0
- package/manager/processes/waitForDevServer.mjs +48 -0
- package/manager/processes/waitForDevServer.test.mjs +112 -0
- package/manager/run.mjs +128 -43
- package/manager/utils/BatchChanges.mjs +21 -5
- package/manager/utils/BatchChanges.test.mjs +77 -0
- package/manager/utils/acquireDevInstance.mjs +99 -0
- package/manager/utils/acquireDevInstance.test.mjs +160 -0
- package/manager/utils/createBuildActivity.mjs +67 -0
- package/manager/utils/createBuildActivity.test.mjs +58 -0
- package/manager/utils/createChangeSignal.mjs +39 -0
- package/manager/utils/createChangeSignal.test.mjs +62 -0
- package/manager/utils/createCustomPluginMessagesMap.mjs +23 -33
- package/manager/utils/createCustomPluginTypesMap.mjs +24 -30
- package/manager/utils/createCustomPluginTypesMap.test.mjs +94 -0
- package/manager/utils/createDotPathIgnore.mjs +44 -0
- package/manager/utils/createDotPathIgnore.test.mjs +65 -0
- package/manager/utils/createIdleGc.mjs +51 -0
- package/manager/utils/createIdleGc.test.mjs +77 -0
- package/manager/utils/createRequestActivity.mjs +100 -0
- package/manager/utils/createRequestActivity.test.mjs +121 -0
- package/manager/utils/createServerArtifactTracker.mjs +83 -0
- package/manager/utils/createServerArtifactTracker.test.mjs +78 -0
- package/manager/utils/createServerEnv.mjs +39 -0
- package/manager/utils/filesHaveSameBytes.mjs +41 -0
- package/manager/utils/findBuildFilesOutsideWatch.mjs +59 -0
- package/manager/utils/findBuildFilesOutsideWatch.test.mjs +111 -0
- package/manager/utils/importFresh.mjs +46 -0
- package/manager/utils/importFresh.test.mjs +72 -0
- package/manager/utils/importFreshWorker.mjs +20 -0
- package/manager/utils/killTaggedBrowser.mjs +35 -0
- package/manager/utils/pagePathChanged.mjs +56 -0
- package/manager/utils/pruneRecordings.mjs +85 -0
- package/manager/utils/pruneRecordings.test.mjs +117 -0
- package/manager/utils/publishBuildDirectory.mjs +121 -0
- package/manager/utils/publishBuildDirectory.order.test.mjs +74 -0
- package/manager/utils/publishBuildDirectory.test.mjs +262 -0
- package/manager/utils/readBasePath.mjs +27 -0
- package/manager/utils/readBasePath.test.mjs +43 -0
- package/manager/utils/readBuildStatusWait.mjs +67 -0
- package/manager/utils/readManagerVersion.mjs +30 -0
- package/manager/utils/readManagerVersion.test.mjs +35 -0
- package/manager/utils/readPluginDefinitions.mjs +36 -0
- package/manager/utils/resolveDevAuthUrl.mjs +58 -0
- package/manager/utils/resolveDevAuthUrl.test.mjs +107 -0
- package/manager/utils/resolvePorts.mjs +49 -0
- package/manager/utils/setupWatcher.mjs +19 -11
- package/manager/utils/startRecordingPruner.mjs +45 -0
- package/manager/utils/startRecordingPruner.test.mjs +66 -0
- package/manager/utils/waitForChildExit.mjs +53 -0
- package/manager/utils/waitForChildExit.test.mjs +70 -0
- package/manager/utils/waitForServer.mjs +44 -0
- package/manager/utils/writeBuildStatus.mjs +1 -1
- package/manager/watchers/createPluginSourceIgnore.mjs +77 -0
- package/manager/watchers/envWatcher.mjs +9 -2
- package/manager/watchers/envWatcher.test.mjs +87 -0
- package/manager/watchers/listServerSidePackages.mjs +47 -0
- package/manager/watchers/listServerSidePackages.test.mjs +38 -0
- package/manager/watchers/lowdefyBuildWatcher.mjs +106 -22
- package/manager/watchers/lowdefyBuildWatcher.test.mjs +309 -0
- package/manager/watchers/pluginSourceWatcher.mjs +79 -0
- package/manager/watchers/pluginSourceWatcher.test.mjs +222 -0
- package/manager/watchers/restartRequestWatcher.mjs +71 -0
- package/manager/watchers/restartRequestWatcher.test.mjs +111 -0
- package/manager/watchers/selectLocalPluginPackages.mjs +48 -0
- package/manager/watchers/selectLocalPluginPackages.test.mjs +73 -0
- package/manager/watchers/serverPackageWatcher.mjs +38 -0
- package/package.json +60 -47
- package/package.original.json +60 -47
- package/src/app.js +131 -20
- package/src/html/renderDevPage.js +63 -11
- package/src/html/renderDevPage.test.mjs +138 -0
- package/src/lib/getRequestPath.js +29 -0
- package/src/middleware/createSameOriginGuard.js +37 -0
- package/src/middleware/createSameOriginGuard.test.mjs +102 -0
- package/src/middleware/errorHandler.js +51 -1
- package/src/middleware/errorHandler.test.mjs +173 -3
- package/src/middleware/isRebindingSafeHost.js +44 -0
- package/src/middleware/isRebindingSafeHost.test.mjs +32 -0
- package/src/middleware/localDevToolsOnly.js +38 -0
- package/src/middleware/localDevToolsOnly.test.mjs +61 -0
- package/src/middleware/noStore.js +27 -0
- package/src/middleware/noStore.test.mjs +48 -0
- package/src/middleware/requestTimeout.js +38 -0
- package/src/middleware/staleFlag.js +76 -0
- package/src/middleware/staleFlag.test.mjs +127 -0
- package/src/middleware/stampCaller.js +38 -0
- package/src/middleware/stampCaller.test.mjs +64 -0
- package/src/routes/agent.js +15 -3
- package/src/routes/auth.js +29 -20
- package/src/routes/auth.test.mjs +30 -56
- package/src/routes/clientError.js +13 -13
- package/src/routes/cron.js +3 -1
- package/src/routes/cronForward.js +3 -1
- package/src/routes/detached.js +22 -9
- package/src/routes/devInspect.js +17 -8
- package/src/routes/devInspect.test.mjs +44 -7
- package/src/routes/devRecording.js +113 -0
- package/src/routes/devRecording.test.mjs +253 -0
- package/src/routes/docs/buildStatus.js +10 -2
- package/src/routes/docs/buildStatus.test.mjs +46 -0
- package/src/routes/docs/content.js +5 -3
- package/src/routes/docs/evalOperator.js +15 -1
- package/src/routes/docs/events.js +50 -0
- package/src/routes/docs/events.test.mjs +117 -0
- package/src/routes/docs/find.js +9 -1
- package/src/routes/docs/icons.js +30 -0
- package/src/routes/docs/inspectState.js +16 -1
- package/src/routes/docs/journey.js +194 -0
- package/src/routes/docs/journey.test.mjs +401 -0
- package/src/routes/docs/journeyRefusals.test.mjs +71 -0
- package/src/routes/docs/loadState.js +4 -2
- package/src/routes/docs/mcp.js +34 -3
- package/src/routes/docs/mcp.test.mjs +130 -0
- package/src/routes/docs/mutants.js +78 -0
- package/src/routes/docs/mutants.test.mjs +180 -0
- package/src/routes/docs/parsePathParamsParam.js +41 -0
- package/src/routes/docs/parsePathParamsParam.test.mjs +42 -0
- package/src/routes/docs/parseUserParam.js +27 -21
- package/src/routes/docs/parseUserParam.test.mjs +17 -5
- package/src/routes/docs/restart.js +35 -0
- package/src/routes/docs/restart.test.mjs +64 -0
- package/src/routes/docs/runEndpoint.js +54 -0
- package/src/routes/docs/runEndpoint.test.mjs +165 -0
- package/src/routes/docs/runRequest.js +25 -8
- package/src/routes/docs/runRequest.test.mjs +92 -0
- package/src/routes/docs/screenshot.js +50 -2
- package/src/routes/docs/screenshot.test.mjs +117 -0
- package/src/routes/docs/search.js +15 -2
- package/src/routes/docs/snapshotState.js +17 -3
- package/src/routes/endpoints.js +27 -26
- package/src/routes/endpointsTextAnswer.test.mjs +77 -0
- package/src/routes/feedback.js +10 -13
- package/src/routes/jitPage.js +99 -35
- package/src/routes/jitPage.test.mjs +248 -0
- package/src/routes/mcp.js +82 -5
- package/src/routes/mcp.test.mjs +215 -0
- package/src/routes/mcpMemberToken.test.mjs +125 -0
- package/src/routes/mcpProtectedResourceMetadata.js +34 -0
- package/src/routes/mcpProtectedResourceMetadata.test.mjs +65 -0
- package/src/routes/mountDevPageRoutes.js +25 -0
- package/src/routes/mountDevPageRoutes.test.mjs +30 -0
- package/src/routes/mountOauthDiscovery.js +44 -0
- package/src/routes/mountOauthDiscovery.test.mjs +79 -0
- package/src/routes/normalizeMcpProtocolVersionHeader.js +46 -0
- package/src/routes/normalizeMcpProtocolVersionHeader.test.mjs +62 -0
- package/src/routes/reload.js +16 -0
- package/src/routes/request.js +6 -4
- package/src/routes/request.test.mjs +9 -5
- package/src/routes/requestBody.test.mjs +159 -0
- package/src/routes/usage.js +6 -2
- package/src/routes/user.js +27 -0
- package/src/routes/websocket.js +29 -8
- package/src/routes/websocket.test.mjs +65 -0
- package/src/routes/wellKnownFallback.js +30 -0
- package/src/routes/wellKnownFallback.test.mjs +32 -0
- package/src/websocket/devWebSocket.js +41 -26
- package/src/websocket/devWebSocket.test.mjs +157 -0
- package/vite.config.js +53 -23
- package/lib/server/auth/getDevSession.js +0 -70
- package/lib/server/auth/getDevSession.test.mjs +0 -138
- package/manager/processes/warnAuthUrlPortMismatch.mjs +0 -47
- package/manager/processes/warnAuthUrlPortMismatch.test.mjs +0 -93
- package/manager/watchers/moduleBuildWatcher.mjs +0 -79
- package/manager/watchers/serverArtifactWatcher.mjs +0 -120
- package/src/routes/apiPage.js +0 -37
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { cachedPromises, serializer } from '@lowdefy/helpers';
|
|
18
|
+
|
|
19
|
+
import createMutantReadConfigFile from './createMutantReadConfigFile.js';
|
|
20
|
+
import { journeyActorToken } from '../auth/journeyActor.js';
|
|
21
|
+
import { openMutantRun, readMutantRun } from './mutantRuns.js';
|
|
22
|
+
import { pageFixture } from './test/fixtures.mjs';
|
|
23
|
+
|
|
24
|
+
const ARTIFACT = 'pages/tickets.json';
|
|
25
|
+
|
|
26
|
+
// As the API context reads a build artifact: through cachedPromises, so every
|
|
27
|
+
// request shares one parsed object per path while the cache holds it.
|
|
28
|
+
function createCachedReadConfigFile(files) {
|
|
29
|
+
const store = new Map();
|
|
30
|
+
const cache = { get: (key) => store.get(key), set: (key, value) => store.set(key, value) };
|
|
31
|
+
return cachedPromises({
|
|
32
|
+
cache,
|
|
33
|
+
getter: async (filePath) => serializer.deserializeFromString(files[filePath] ?? 'null'),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function setup(mutantOverrides = {}) {
|
|
38
|
+
const { root } = pageFixture();
|
|
39
|
+
const success = root.slots.content.blocks[3].slots.content.blocks[0];
|
|
40
|
+
const files = {
|
|
41
|
+
[ARTIFACT]: serializer.serializeToString(root),
|
|
42
|
+
'events.json': serializer.serializeToString({ onInit: { try: [], catch: [] } }),
|
|
43
|
+
};
|
|
44
|
+
const readConfigFile = createCachedReadConfigFile(files);
|
|
45
|
+
const opened = openMutantRun({
|
|
46
|
+
mutant: {
|
|
47
|
+
buildId: 'build-1',
|
|
48
|
+
artifact: ARTIFACT,
|
|
49
|
+
key: success['~k'],
|
|
50
|
+
arg: null,
|
|
51
|
+
operator: 'drop-block',
|
|
52
|
+
...mutantOverrides,
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
return { opened, readConfigFile, root };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function mutantCookie(payload, token = journeyActorToken) {
|
|
59
|
+
return `session=abc; lowdefy_journey_mutant=${token}.${payload}`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
test('a read of the target path returns the mutated copy and counts one application', async () => {
|
|
63
|
+
const { opened, readConfigFile } = setup();
|
|
64
|
+
const read = createMutantReadConfigFile({ readConfigFile, run: opened.run });
|
|
65
|
+
const page = await read(ARTIFACT);
|
|
66
|
+
expect(page.slots.content.blocks[3].slots.content.blocks).toEqual([]);
|
|
67
|
+
expect(opened.run.applied).toBe(1);
|
|
68
|
+
expect(opened.run.misses).toEqual([]);
|
|
69
|
+
opened.close();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test('a read of another path is untouched', async () => {
|
|
73
|
+
const { opened, readConfigFile } = setup();
|
|
74
|
+
const read = createMutantReadConfigFile({ readConfigFile, run: opened.run });
|
|
75
|
+
expect(await read('events.json')).toBe(await readConfigFile('events.json'));
|
|
76
|
+
expect(opened.run.applied).toBe(0);
|
|
77
|
+
opened.close();
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('a mutated read followed by an unmutated read through a shared cache returns the original', async () => {
|
|
81
|
+
const { opened, readConfigFile } = setup();
|
|
82
|
+
const mutated = await createMutantReadConfigFile({ readConfigFile, run: opened.run })(ARTIFACT);
|
|
83
|
+
const original = await readConfigFile(ARTIFACT);
|
|
84
|
+
expect(mutated.slots.content.blocks[3].slots.content.blocks).toHaveLength(0);
|
|
85
|
+
expect(original.slots.content.blocks[3].slots.content.blocks).toHaveLength(1);
|
|
86
|
+
// The copy keeps ~k, so the mutant can still be found in it.
|
|
87
|
+
expect(mutated.slots.content.blocks[0]['~k']).toEqual(original.slots.content.blocks[0]['~k']);
|
|
88
|
+
opened.close();
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('a key not found and an apply with no arg each record a miss and apply nothing', async () => {
|
|
92
|
+
const missingKey = setup({ key: 'not-a-key' });
|
|
93
|
+
const page = await createMutantReadConfigFile({
|
|
94
|
+
readConfigFile: missingKey.readConfigFile,
|
|
95
|
+
run: missingKey.opened.run,
|
|
96
|
+
})(ARTIFACT);
|
|
97
|
+
expect(missingKey.opened.run.applied).toBe(0);
|
|
98
|
+
expect(missingKey.opened.run.misses).toEqual([{ reason: 'key not found', path: ARTIFACT }]);
|
|
99
|
+
expect(JSON.stringify(page)).toEqual(JSON.stringify(missingKey.root));
|
|
100
|
+
missingKey.opened.close();
|
|
101
|
+
|
|
102
|
+
const name = missingKey.root.slots.content.blocks[1];
|
|
103
|
+
const noArg = setup({ operator: 'flip-visible', key: name['~k'], arg: null });
|
|
104
|
+
await createMutantReadConfigFile({ readConfigFile: noArg.readConfigFile, run: noArg.opened.run })(
|
|
105
|
+
ARTIFACT
|
|
106
|
+
);
|
|
107
|
+
expect(noArg.opened.run.applied).toBe(0);
|
|
108
|
+
expect(noArg.opened.run.misses).toEqual([
|
|
109
|
+
{ reason: 'flip-visible needs arg visible or properties.disabled', path: ARTIFACT },
|
|
110
|
+
]);
|
|
111
|
+
noArg.opened.close();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test('readMutantRun returns the open run a verified mutant cookie names', () => {
|
|
115
|
+
const { opened } = setup();
|
|
116
|
+
expect(readMutantRun(mutantCookie(opened.cookiePayload))).toBe(opened.run);
|
|
117
|
+
opened.close();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test('readMutantRun returns null for a forged token, a missing cookie and a closed run', () => {
|
|
121
|
+
const { opened } = setup();
|
|
122
|
+
expect(readMutantRun(mutantCookie(opened.cookiePayload, '0'.repeat(64)))).toBeNull();
|
|
123
|
+
expect(readMutantRun('session=abc')).toBeNull();
|
|
124
|
+
expect(readMutantRun(undefined)).toBeNull();
|
|
125
|
+
opened.close();
|
|
126
|
+
expect(readMutantRun(mutantCookie(opened.cookiePayload))).toBeNull();
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test('openMutantRun gives every run its own 16-byte id', () => {
|
|
130
|
+
const first = setup().opened;
|
|
131
|
+
const second = setup().opened;
|
|
132
|
+
expect(first.id).toMatch(/^[0-9a-f]{32}$/);
|
|
133
|
+
expect(first.id).not.toEqual(second.id);
|
|
134
|
+
first.close();
|
|
135
|
+
second.close();
|
|
136
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { EVENTS_ARTIFACT, PAGE_ARTIFACT } from '../artifactPatterns.js';
|
|
18
|
+
import buildAnchor from '../buildAnchor.js';
|
|
19
|
+
import describeEvent from '../describeEvent.js';
|
|
20
|
+
import removeFromParent from '../removeFromParent.js';
|
|
21
|
+
|
|
22
|
+
function enumerate({ node, parent, keyInParent, scope }) {
|
|
23
|
+
if (scope.role !== 'action') {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
return [
|
|
27
|
+
{
|
|
28
|
+
key: node['~k'],
|
|
29
|
+
arg: null,
|
|
30
|
+
anchor: buildAnchor({ scope, type: 'action' }),
|
|
31
|
+
describe: `drop-action ${node.type} "${node.id}" (${keyInParent + 1} of ${
|
|
32
|
+
parent.length
|
|
33
|
+
}) from ${describeEvent(scope)}`,
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function apply({ parent, keyInParent }) {
|
|
39
|
+
return removeFromParent({ parent, keyInParent });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default {
|
|
43
|
+
name: 'drop-action',
|
|
44
|
+
artifacts: [PAGE_ARTIFACT, EVENTS_ARTIFACT],
|
|
45
|
+
enumerate,
|
|
46
|
+
apply,
|
|
47
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { PAGE_ARTIFACT } from '../artifactPatterns.js';
|
|
18
|
+
import buildAnchor from '../buildAnchor.js';
|
|
19
|
+
import removeFromParent from '../removeFromParent.js';
|
|
20
|
+
|
|
21
|
+
function enumerate({ node, scope }) {
|
|
22
|
+
if (scope.role !== 'block' || scope.parentBlockId === null) {
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
return [
|
|
26
|
+
{
|
|
27
|
+
key: node['~k'],
|
|
28
|
+
arg: null,
|
|
29
|
+
anchor: buildAnchor({ scope, type: 'block' }),
|
|
30
|
+
describe: `drop-block ${node.type} "${scope.blockId}" from ${scope.parentBlockId}`,
|
|
31
|
+
},
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function apply({ parent, keyInParent }) {
|
|
36
|
+
return removeFromParent({ parent, keyInParent });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default {
|
|
40
|
+
name: 'drop-block',
|
|
41
|
+
artifacts: [PAGE_ARTIFACT],
|
|
42
|
+
enumerate,
|
|
43
|
+
apply,
|
|
44
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { type } from '@lowdefy/helpers';
|
|
18
|
+
|
|
19
|
+
import { PAGE_ARTIFACT } from '../artifactPatterns.js';
|
|
20
|
+
import buildAnchor from '../buildAnchor.js';
|
|
21
|
+
|
|
22
|
+
// The payload a page artifact's request carries is what the browser
|
|
23
|
+
// evaluates and sends, so dropping one key changes what the server receives.
|
|
24
|
+
function enumerate({ node, scope }) {
|
|
25
|
+
if (scope.role !== 'payload') {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
return Object.keys(node).map((arg) => ({
|
|
29
|
+
key: node['~k'],
|
|
30
|
+
arg,
|
|
31
|
+
anchor: buildAnchor({ scope, type: 'request' }),
|
|
32
|
+
describe: `drop-payload "${arg}" from request "${scope.requestId}"`,
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function apply({ node, arg }) {
|
|
37
|
+
if (!type.isString(arg)) {
|
|
38
|
+
return { applied: false, reason: 'drop-payload needs the payload key as arg' };
|
|
39
|
+
}
|
|
40
|
+
if (!Object.prototype.hasOwnProperty.call(node, arg)) {
|
|
41
|
+
return { applied: false, reason: `payload has no key "${arg}"` };
|
|
42
|
+
}
|
|
43
|
+
delete node[arg];
|
|
44
|
+
return { applied: true };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default {
|
|
48
|
+
name: 'drop-payload',
|
|
49
|
+
artifacts: [PAGE_ARTIFACT],
|
|
50
|
+
enumerate,
|
|
51
|
+
apply,
|
|
52
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { ENDPOINT_ARTIFACT } from '../artifactPatterns.js';
|
|
18
|
+
import buildAnchor from '../buildAnchor.js';
|
|
19
|
+
import removeFromParent from '../removeFromParent.js';
|
|
20
|
+
|
|
21
|
+
function enumerate({ node, scope }) {
|
|
22
|
+
if (scope.role !== 'step') {
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
return [
|
|
26
|
+
{
|
|
27
|
+
key: node['~k'],
|
|
28
|
+
arg: null,
|
|
29
|
+
anchor: buildAnchor({ scope, type: 'endpoint' }),
|
|
30
|
+
describe: `drop-step ${node.type} "${scope.stepId}" from endpoint "${scope.endpointId}"`,
|
|
31
|
+
},
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function apply({ parent, keyInParent }) {
|
|
36
|
+
return removeFromParent({ parent, keyInParent });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default {
|
|
40
|
+
name: 'drop-step',
|
|
41
|
+
artifacts: [ENDPOINT_ARTIFACT],
|
|
42
|
+
enumerate,
|
|
43
|
+
apply,
|
|
44
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { get, set, type } from '@lowdefy/helpers';
|
|
18
|
+
|
|
19
|
+
import { PAGE_ARTIFACT } from '../artifactPatterns.js';
|
|
20
|
+
import buildAnchor from '../buildAnchor.js';
|
|
21
|
+
|
|
22
|
+
const ARGS = ['visible', 'properties.disabled'];
|
|
23
|
+
|
|
24
|
+
function enumerate({ node, scope }) {
|
|
25
|
+
if (scope.role !== 'block') {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
return ARGS.filter((arg) => !type.isUndefined(get(node, arg))).map((arg) => ({
|
|
29
|
+
key: node['~k'],
|
|
30
|
+
arg,
|
|
31
|
+
anchor: buildAnchor({ scope, type: 'block' }),
|
|
32
|
+
describe: `flip-visible ${arg} on ${scope.blockId}`,
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function apply({ node, arg }) {
|
|
37
|
+
if (!ARGS.includes(arg)) {
|
|
38
|
+
return { applied: false, reason: `flip-visible needs arg visible or properties.disabled` };
|
|
39
|
+
}
|
|
40
|
+
const value = get(node, arg);
|
|
41
|
+
if (type.isUndefined(value)) {
|
|
42
|
+
return { applied: false, reason: `block has no ${arg}` };
|
|
43
|
+
}
|
|
44
|
+
set(node, arg, type.isBoolean(value) ? !value : { _not: value });
|
|
45
|
+
return { applied: true };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export default {
|
|
49
|
+
name: 'flip-visible',
|
|
50
|
+
artifacts: [PAGE_ARTIFACT],
|
|
51
|
+
enumerate,
|
|
52
|
+
apply,
|
|
53
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import dropAction from './dropAction.js';
|
|
18
|
+
import dropBlock from './dropBlock.js';
|
|
19
|
+
import dropPayload from './dropPayload.js';
|
|
20
|
+
import dropStep from './dropStep.js';
|
|
21
|
+
import flipVisible from './flipVisible.js';
|
|
22
|
+
import retargetLink from './retargetLink.js';
|
|
23
|
+
import skipValidate from './skipValidate.js';
|
|
24
|
+
import swapIf from './swapIf.js';
|
|
25
|
+
|
|
26
|
+
const operators = {
|
|
27
|
+
[dropAction.name]: dropAction,
|
|
28
|
+
[skipValidate.name]: skipValidate,
|
|
29
|
+
[flipVisible.name]: flipVisible,
|
|
30
|
+
[swapIf.name]: swapIf,
|
|
31
|
+
[dropPayload.name]: dropPayload,
|
|
32
|
+
[retargetLink.name]: retargetLink,
|
|
33
|
+
[dropBlock.name]: dropBlock,
|
|
34
|
+
[dropStep.name]: dropStep,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export default operators;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { type } from '@lowdefy/helpers';
|
|
18
|
+
|
|
19
|
+
import { EVENTS_ARTIFACT, PAGE_ARTIFACT } from '../artifactPatterns.js';
|
|
20
|
+
import buildAnchor from '../buildAnchor.js';
|
|
21
|
+
import describeEvent from '../describeEvent.js';
|
|
22
|
+
|
|
23
|
+
// The build's default pages always include 404, so a retargeted Link always
|
|
24
|
+
// lands somewhere. Links by url, back or home name no page and are skipped.
|
|
25
|
+
function linksToPage(params) {
|
|
26
|
+
if (type.isString(params)) {
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
return (
|
|
30
|
+
type.isObject(params) &&
|
|
31
|
+
!type.isUndefined(params.pageId) &&
|
|
32
|
+
type.isUndefined(params.url) &&
|
|
33
|
+
type.isUndefined(params.back) &&
|
|
34
|
+
type.isUndefined(params.home)
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function enumerate({ node, scope }) {
|
|
39
|
+
if (scope.role !== 'action' || node.type !== 'Link') {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
if (!linksToPage(node.params)) {
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
return [
|
|
46
|
+
{
|
|
47
|
+
key: node['~k'],
|
|
48
|
+
arg: null,
|
|
49
|
+
anchor: buildAnchor({ scope, type: 'action' }),
|
|
50
|
+
describe: `retarget-link Link "${node.id}" from ${describeEvent(scope)} to 404`,
|
|
51
|
+
},
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function apply({ node }) {
|
|
56
|
+
if (type.isString(node.params)) {
|
|
57
|
+
node.params = '404';
|
|
58
|
+
return { applied: true };
|
|
59
|
+
}
|
|
60
|
+
if (linksToPage(node.params)) {
|
|
61
|
+
node.params.pageId = '404';
|
|
62
|
+
return { applied: true };
|
|
63
|
+
}
|
|
64
|
+
return { applied: false, reason: 'Link names no page' };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export default {
|
|
68
|
+
name: 'retarget-link',
|
|
69
|
+
artifacts: [PAGE_ARTIFACT, EVENTS_ARTIFACT],
|
|
70
|
+
enumerate,
|
|
71
|
+
apply,
|
|
72
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { type } from '@lowdefy/helpers';
|
|
18
|
+
|
|
19
|
+
import { PAGE_ARTIFACT } from '../artifactPatterns.js';
|
|
20
|
+
import buildAnchor from '../buildAnchor.js';
|
|
21
|
+
import describeEvent from '../describeEvent.js';
|
|
22
|
+
import removeFromParent from '../removeFromParent.js';
|
|
23
|
+
|
|
24
|
+
// Page artifacts only: the build refuses Validate in app events.
|
|
25
|
+
function enumerate({ node, parent, keyInParent, scope }) {
|
|
26
|
+
if (scope.role === 'action' && node.type === 'Validate') {
|
|
27
|
+
return [
|
|
28
|
+
{
|
|
29
|
+
key: node['~k'],
|
|
30
|
+
arg: null,
|
|
31
|
+
anchor: buildAnchor({ scope, type: 'action' }),
|
|
32
|
+
describe: `skip-validate Validate "${node.id}" from ${describeEvent(scope)}`,
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
}
|
|
36
|
+
if (scope.role === 'block' && !type.isNone(node.required) && node.required !== false) {
|
|
37
|
+
return [
|
|
38
|
+
{
|
|
39
|
+
key: node['~k'],
|
|
40
|
+
arg: 'required',
|
|
41
|
+
anchor: buildAnchor({ scope, type: 'block' }),
|
|
42
|
+
describe: `skip-validate required on ${scope.blockId}`,
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
if (scope.role === 'validateEntry') {
|
|
47
|
+
return [
|
|
48
|
+
{
|
|
49
|
+
key: node['~k'],
|
|
50
|
+
arg: null,
|
|
51
|
+
anchor: buildAnchor({ scope, type: 'block' }),
|
|
52
|
+
describe: `skip-validate validate rule ${keyInParent + 1} of ${parent.length} on ${
|
|
53
|
+
scope.blockId
|
|
54
|
+
}`,
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
}
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function apply({ node, parent, keyInParent, arg }) {
|
|
62
|
+
if (arg === 'required') {
|
|
63
|
+
if (type.isUndefined(node.required)) {
|
|
64
|
+
return { applied: false, reason: 'block has no required' };
|
|
65
|
+
}
|
|
66
|
+
delete node.required;
|
|
67
|
+
return { applied: true };
|
|
68
|
+
}
|
|
69
|
+
return removeFromParent({ parent, keyInParent });
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export default {
|
|
73
|
+
name: 'skip-validate',
|
|
74
|
+
artifacts: [PAGE_ARTIFACT],
|
|
75
|
+
enumerate,
|
|
76
|
+
apply,
|
|
77
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { type } from '@lowdefy/helpers';
|
|
18
|
+
|
|
19
|
+
import {
|
|
20
|
+
ENDPOINT_ARTIFACT,
|
|
21
|
+
EVENTS_ARTIFACT,
|
|
22
|
+
PAGE_ARTIFACT,
|
|
23
|
+
REQUEST_ARTIFACT,
|
|
24
|
+
} from '../artifactPatterns.js';
|
|
25
|
+
import buildAnchor from '../buildAnchor.js';
|
|
26
|
+
|
|
27
|
+
const REGIONS = [
|
|
28
|
+
'blockProperties',
|
|
29
|
+
'actionParams',
|
|
30
|
+
'requestPayload',
|
|
31
|
+
'requestProperties',
|
|
32
|
+
'routine',
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
function anchorType(scope) {
|
|
36
|
+
switch (scope.region) {
|
|
37
|
+
case 'blockProperties':
|
|
38
|
+
return 'block';
|
|
39
|
+
case 'actionParams':
|
|
40
|
+
return 'action';
|
|
41
|
+
case 'routine':
|
|
42
|
+
return 'endpoint';
|
|
43
|
+
default:
|
|
44
|
+
return 'request';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function describeWhere(scope) {
|
|
49
|
+
switch (scope.region) {
|
|
50
|
+
case 'blockProperties':
|
|
51
|
+
return `${scope.blockId}.properties`;
|
|
52
|
+
case 'actionParams':
|
|
53
|
+
return `action "${scope.actionId}" params`;
|
|
54
|
+
case 'routine':
|
|
55
|
+
return `endpoint "${scope.endpointId}"`;
|
|
56
|
+
case 'requestPayload':
|
|
57
|
+
return `request "${scope.requestId}" payload`;
|
|
58
|
+
default:
|
|
59
|
+
return `request "${scope.requestId}" properties`;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function isSwappableIf(node) {
|
|
64
|
+
return type.isObject(node._if) && !type.isUndefined(node._if.else);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function isSwappableRoutineIf(node, scope) {
|
|
68
|
+
return (
|
|
69
|
+
scope.role === 'control' && !type.isUndefined(node[':if']) && !type.isUndefined(node[':else'])
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function enumerate({ node, scope }) {
|
|
74
|
+
if (!REGIONS.includes(scope.region)) {
|
|
75
|
+
return [];
|
|
76
|
+
}
|
|
77
|
+
if (!isSwappableIf(node) && !isSwappableRoutineIf(node, scope)) {
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
const operator = isSwappableIf(node) ? '_if' : ':if';
|
|
81
|
+
return [
|
|
82
|
+
{
|
|
83
|
+
key: node['~k'],
|
|
84
|
+
arg: null,
|
|
85
|
+
anchor: buildAnchor({ scope, type: anchorType(scope) }),
|
|
86
|
+
describe: `swap-if ${operator} in ${describeWhere(scope)}`,
|
|
87
|
+
},
|
|
88
|
+
];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function apply({ node }) {
|
|
92
|
+
if (isSwappableIf(node)) {
|
|
93
|
+
const { then, else: otherwise } = node._if;
|
|
94
|
+
node._if.then = otherwise;
|
|
95
|
+
node._if.else = then;
|
|
96
|
+
return { applied: true };
|
|
97
|
+
}
|
|
98
|
+
if (!type.isUndefined(node[':if']) && !type.isUndefined(node[':else'])) {
|
|
99
|
+
const then = node[':then'];
|
|
100
|
+
node[':then'] = node[':else'];
|
|
101
|
+
node[':else'] = then;
|
|
102
|
+
return { applied: true };
|
|
103
|
+
}
|
|
104
|
+
return { applied: false, reason: 'no _if or :if with an else branch' };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export default {
|
|
108
|
+
name: 'swap-if',
|
|
109
|
+
artifacts: [PAGE_ARTIFACT, REQUEST_ARTIFACT, ENDPOINT_ARTIFACT, EVENTS_ARTIFACT],
|
|
110
|
+
enumerate,
|
|
111
|
+
apply,
|
|
112
|
+
};
|