@lowdefy/server-dev 6.1.0 → 7.1.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 +78 -0
- package/lib/docs/dataSets/dataSessionRegistry.js +25 -0
- package/lib/docs/dataSets/dataSetJourneys.chromium.mongodb.test.mjs +727 -0
- package/lib/docs/dataSets/describeDataSetResult.js +25 -0
- package/lib/docs/dataSets/describeDatabaseTarget.js +46 -0
- package/lib/docs/dataSets/describeTargetKey.js +29 -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/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 +52 -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 +133 -0
- package/lib/docs/dataSets/openDataSession.mongodb.test.mjs +493 -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 +83 -0
- package/lib/docs/dataSets/readDataSet.test.mjs +251 -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/sessionDatabaseName.js +32 -0
- package/lib/docs/dataSets/sweepOrphanDatabases.js +36 -0
- package/lib/docs/dataSets/test/app/lowdefy.yaml +225 -0
- package/lib/docs/dataSets/test/app/modules/archive/module.lowdefy.yaml +30 -0
- package/lib/docs/dataSets/test/app/tests/data/shop.yaml +12 -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 +81 -7
- package/lib/docs/getBuildStatus.test.mjs +229 -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 +92 -0
- package/lib/server/applyDataSetRedirect.test.mjs +446 -0
- package/lib/server/applyDataSetRedirectTenantReach.test.mjs +207 -0
- package/lib/server/applyDataSetRedirectWalled.test.mjs +134 -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 +331 -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 +115 -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 +25 -3
- package/manager/processes/initialBuild.mjs +17 -1
- package/manager/processes/initialBuild.test.mjs +104 -0
- package/manager/processes/lowdefyBuild.mjs +31 -7
- package/manager/processes/lowdefyBuild.skipPluginChecks.test.mjs +72 -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,69 @@
|
|
|
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 path from 'node:path';
|
|
18
|
+
import { type } from '@lowdefy/helpers';
|
|
19
|
+
|
|
20
|
+
import listPackageDocFiles from './listPackageDocFiles.js';
|
|
21
|
+
import parseModuleSource from './parseModuleSource.js';
|
|
22
|
+
import readDocTitle from './readDocTitle.js';
|
|
23
|
+
|
|
24
|
+
// Docs of the app's modules: each README and docs/*.md, plus a generated page
|
|
25
|
+
// of the components, exports and vars its module.lowdefy.yaml declares.
|
|
26
|
+
// Returns the entries and the local module roots, whose doc files can change
|
|
27
|
+
// while the server runs.
|
|
28
|
+
function listModuleDocEntries({ modules }) {
|
|
29
|
+
const entries = [];
|
|
30
|
+
const localDirs = [];
|
|
31
|
+
for (const moduleEntry of Object.values(modules ?? {})) {
|
|
32
|
+
if (moduleEntry.isLocal) {
|
|
33
|
+
localDirs.push(moduleEntry.moduleRoot);
|
|
34
|
+
}
|
|
35
|
+
const base = {
|
|
36
|
+
section: 'Modules',
|
|
37
|
+
source: 'module',
|
|
38
|
+
...parseModuleSource({ source: moduleEntry.source }),
|
|
39
|
+
};
|
|
40
|
+
const moduleSlug = `modules/${moduleEntry.id}`;
|
|
41
|
+
const { readme, docs } = listPackageDocFiles({ dir: moduleEntry.moduleRoot });
|
|
42
|
+
if (!type.isNone(readme)) {
|
|
43
|
+
entries.push({
|
|
44
|
+
...base,
|
|
45
|
+
slug: moduleSlug,
|
|
46
|
+
title: readDocTitle({ filePath: readme, fallback: `${moduleEntry.id} module` }),
|
|
47
|
+
filePath: readme,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
for (const filePath of docs) {
|
|
51
|
+
const stem = path.basename(filePath, '.md');
|
|
52
|
+
entries.push({
|
|
53
|
+
...base,
|
|
54
|
+
slug: `${moduleSlug}/${stem}`,
|
|
55
|
+
title: readDocTitle({ filePath, fallback: stem }),
|
|
56
|
+
filePath,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
entries.push({
|
|
60
|
+
...base,
|
|
61
|
+
slug: `${moduleSlug}/manifest`,
|
|
62
|
+
title: `${moduleEntry.id} module: components, exports and vars`,
|
|
63
|
+
moduleEntry,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return { entries, localDirs };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export default listModuleDocEntries;
|
|
@@ -0,0 +1,67 @@
|
|
|
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 fs from 'node:fs';
|
|
18
|
+
import path from 'node:path';
|
|
19
|
+
|
|
20
|
+
// Docs are served from inside the package only: a file, or a docs folder,
|
|
21
|
+
// that links outside it is left out, as is a link that points nowhere or a
|
|
22
|
+
// directory named like a markdown file.
|
|
23
|
+
function isFileInside({ realDir, filePath }) {
|
|
24
|
+
if (!fs.existsSync(filePath)) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
const realPath = fs.realpathSync(filePath);
|
|
28
|
+
return realPath.startsWith(`${realDir}${path.sep}`) && fs.statSync(realPath).isFile();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function listMarkdownFiles({ realDir, dir }) {
|
|
32
|
+
return fs
|
|
33
|
+
.readdirSync(dir)
|
|
34
|
+
.filter((fileName) => fileName.endsWith('.md'))
|
|
35
|
+
.sort()
|
|
36
|
+
.map((fileName) => path.join(dir, fileName))
|
|
37
|
+
.filter((filePath) => isFileInside({ realDir, filePath }));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// The markdown a plugin or module ships: its README, and the files in docs/
|
|
41
|
+
// (a plugin that builds its docs may only have dist/docs/).
|
|
42
|
+
function listPackageDocFiles({ dir }) {
|
|
43
|
+
// A local plugin or module can be removed while the server runs.
|
|
44
|
+
if (!fs.existsSync(dir)) {
|
|
45
|
+
return { readme: null, docs: [] };
|
|
46
|
+
}
|
|
47
|
+
const realDir = fs.realpathSync(dir);
|
|
48
|
+
let readme = null;
|
|
49
|
+
for (const fileName of ['README.md', 'readme.md']) {
|
|
50
|
+
const filePath = path.join(dir, fileName);
|
|
51
|
+
if (isFileInside({ realDir, filePath })) {
|
|
52
|
+
readme = filePath;
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
let docs = [];
|
|
57
|
+
for (const docsDir of ['docs', 'dist/docs']) {
|
|
58
|
+
const dirPath = path.join(dir, docsDir);
|
|
59
|
+
if (fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory()) {
|
|
60
|
+
docs = listMarkdownFiles({ realDir, dir: dirPath });
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return { readme, docs };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export default listPackageDocFiles;
|
|
@@ -0,0 +1,111 @@
|
|
|
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 fs from 'node:fs';
|
|
18
|
+
import path from 'node:path';
|
|
19
|
+
import { type } from '@lowdefy/helpers';
|
|
20
|
+
|
|
21
|
+
import listPackageDocFiles from './listPackageDocFiles.js';
|
|
22
|
+
import readDocTitle from './readDocTitle.js';
|
|
23
|
+
import readPluginPackages from './readPluginPackages.js';
|
|
24
|
+
import resolvePluginDir from './resolvePluginDir.js';
|
|
25
|
+
|
|
26
|
+
// Type kinds a doc can be looked up by, singular as the core docs name them.
|
|
27
|
+
const TYPE_KINDS = {
|
|
28
|
+
actions: 'action',
|
|
29
|
+
agents: 'agent',
|
|
30
|
+
blocks: 'block',
|
|
31
|
+
connections: 'connection',
|
|
32
|
+
notifications: 'notification',
|
|
33
|
+
operators: 'operator',
|
|
34
|
+
requests: 'request',
|
|
35
|
+
websockets: 'websocket',
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
function readPackageVersion({ dir, fallback }) {
|
|
39
|
+
const packageJson = JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf8'));
|
|
40
|
+
return packageJson.version ?? fallback;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// A published plugin is installed inside node_modules; a local one links to a
|
|
44
|
+
// directory outside it.
|
|
45
|
+
function isLocalPluginDir({ dir }) {
|
|
46
|
+
return !dir.split(path.sep).includes('node_modules');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Docs shipped by the app's plugins, Lowdefy's own left out (the core docs
|
|
50
|
+
// cover them). Returns the entries, the directories whose doc files can change
|
|
51
|
+
// while the server runs, and each type's doc slug, keyed "kind:typeName".
|
|
52
|
+
function listPluginDocEntries() {
|
|
53
|
+
const entries = [];
|
|
54
|
+
const localDirs = [];
|
|
55
|
+
const typeDocs = new Map();
|
|
56
|
+
for (const plugin of readPluginPackages()) {
|
|
57
|
+
if (plugin.package.startsWith('@lowdefy/')) {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const dir = resolvePluginDir({ packageName: plugin.package });
|
|
61
|
+
if (type.isNone(dir)) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const local = isLocalPluginDir({ dir });
|
|
65
|
+
if (local) {
|
|
66
|
+
localDirs.push(dir);
|
|
67
|
+
}
|
|
68
|
+
const base = {
|
|
69
|
+
section: 'Plugins',
|
|
70
|
+
source: local ? 'local-plugin' : 'plugin',
|
|
71
|
+
package: plugin.package,
|
|
72
|
+
version: readPackageVersion({ dir, fallback: plugin.version }),
|
|
73
|
+
};
|
|
74
|
+
const { readme, docs } = listPackageDocFiles({ dir });
|
|
75
|
+
const packageSlug = `plugins/${plugin.package}`;
|
|
76
|
+
if (!type.isNone(readme)) {
|
|
77
|
+
entries.push({ ...base, slug: packageSlug, title: plugin.package, filePath: readme });
|
|
78
|
+
}
|
|
79
|
+
const docsByStem = new Map();
|
|
80
|
+
for (const filePath of docs) {
|
|
81
|
+
const stem = path.basename(filePath, '.md');
|
|
82
|
+
const entry = {
|
|
83
|
+
...base,
|
|
84
|
+
slug: `${packageSlug}/${stem}`,
|
|
85
|
+
title: readDocTitle({ filePath, fallback: stem }),
|
|
86
|
+
filePath,
|
|
87
|
+
};
|
|
88
|
+
docsByStem.set(stem.toLowerCase(), entry);
|
|
89
|
+
entries.push(entry);
|
|
90
|
+
}
|
|
91
|
+
for (const [kinds, typeNames] of Object.entries(plugin.types)) {
|
|
92
|
+
const kind = TYPE_KINDS[kinds];
|
|
93
|
+
if (type.isUndefined(kind)) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
for (const typeName of typeNames) {
|
|
97
|
+
const typeEntry = docsByStem.get(typeName.toLowerCase());
|
|
98
|
+
if (!type.isUndefined(typeEntry)) {
|
|
99
|
+
typeEntry.kind = typeEntry.kind ?? kind;
|
|
100
|
+
typeEntry.typeName = typeEntry.typeName ?? typeName;
|
|
101
|
+
typeDocs.set(`${kind}:${typeName}`, typeEntry.slug);
|
|
102
|
+
} else if (!type.isNone(readme)) {
|
|
103
|
+
typeDocs.set(`${kind}:${typeName}`, packageSlug);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return { entries, localDirs, typeDocs };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export default listPluginDocEntries;
|
package/lib/docs/listPlugins.js
CHANGED
|
@@ -14,67 +14,18 @@
|
|
|
14
14
|
limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import
|
|
18
|
-
|
|
19
|
-
function addTypes({ plugins, store, kind }) {
|
|
20
|
-
for (const [typeName, definition] of Object.entries(store ?? {})) {
|
|
21
|
-
if (!plugins[definition.package]) {
|
|
22
|
-
plugins[definition.package] = { package: definition.package, version: definition.version, types: {} };
|
|
23
|
-
}
|
|
24
|
-
const plugin = plugins[definition.package];
|
|
25
|
-
if (!plugin.types[kind]) {
|
|
26
|
-
plugin.types[kind] = [];
|
|
27
|
-
}
|
|
28
|
-
plugin.types[kind].push(typeName);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
17
|
+
import getDocsIndex from './getDocsIndex.js';
|
|
18
|
+
import readPluginPackages from './readPluginPackages.js';
|
|
31
19
|
|
|
32
20
|
function listPlugins() {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
addTypes({ plugins, store: availableTypes.actions, kind: 'actions' });
|
|
39
|
-
addTypes({ plugins, store: availableTypes.agents, kind: 'agents' });
|
|
40
|
-
addTypes({ plugins, store: availableTypes.blocks, kind: 'blocks' });
|
|
41
|
-
addTypes({ plugins, store: availableTypes.connections, kind: 'connections' });
|
|
42
|
-
addTypes({ plugins, store: availableTypes.notifications, kind: 'notifications' });
|
|
43
|
-
addTypes({ plugins, store: availableTypes.operators?.client, kind: 'operators' });
|
|
44
|
-
addTypes({ plugins, store: availableTypes.operators?.server, kind: 'operators' });
|
|
45
|
-
addTypes({ plugins, store: availableTypes.requests, kind: 'requests' });
|
|
46
|
-
addTypes({ plugins, store: availableTypes.websockets, kind: 'websockets' });
|
|
47
|
-
|
|
48
|
-
const customPackages = new Set();
|
|
49
|
-
const customStores = [
|
|
50
|
-
customTypesMap.actions,
|
|
51
|
-
customTypesMap.agents,
|
|
52
|
-
customTypesMap.blocks,
|
|
53
|
-
customTypesMap.connections,
|
|
54
|
-
customTypesMap.operators?.client,
|
|
55
|
-
customTypesMap.operators?.server,
|
|
56
|
-
customTypesMap.requests,
|
|
57
|
-
customTypesMap.websockets,
|
|
58
|
-
];
|
|
59
|
-
for (const store of customStores) {
|
|
60
|
-
for (const definition of Object.values(store ?? {})) {
|
|
61
|
-
customPackages.add(definition.package);
|
|
21
|
+
const slugs = new Set(getDocsIndex().entries.map((entry) => entry.slug));
|
|
22
|
+
return readPluginPackages().map((plugin) => {
|
|
23
|
+
const docSlug = `plugins/${plugin.package}`;
|
|
24
|
+
if (!slugs.has(docSlug)) {
|
|
25
|
+
return plugin;
|
|
62
26
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return Object.values(plugins)
|
|
66
|
-
.map((plugin) => ({
|
|
67
|
-
...plugin,
|
|
68
|
-
custom: customPackages.has(plugin.package),
|
|
69
|
-
installed: installedPackages.includes(plugin.package),
|
|
70
|
-
types: Object.fromEntries(
|
|
71
|
-
Object.entries(plugin.types).map(([kind, typeNames]) => [
|
|
72
|
-
kind,
|
|
73
|
-
[...new Set(typeNames)].sort(),
|
|
74
|
-
])
|
|
75
|
-
),
|
|
76
|
-
}))
|
|
77
|
-
.sort((a, b) => a.package.localeCompare(b.package));
|
|
27
|
+
return { ...plugin, docSlug };
|
|
28
|
+
});
|
|
78
29
|
}
|
|
79
30
|
|
|
80
31
|
export default listPlugins;
|
package/lib/docs/listTypes.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import { type } from '@lowdefy/helpers';
|
|
18
18
|
|
|
19
|
-
import
|
|
19
|
+
import getDocsIndex from './getDocsIndex.js';
|
|
20
20
|
import normalizeTypeKind from './normalizeTypeKind.js';
|
|
21
21
|
import readBuildArtifact from './readBuildArtifact.js';
|
|
22
22
|
|
|
@@ -52,19 +52,27 @@ function listTypes({ kind }) {
|
|
|
52
52
|
const normalizedKind = normalizeTypeKind({ kind });
|
|
53
53
|
if (type.isNone(normalizedKind)) {
|
|
54
54
|
throw new Error(
|
|
55
|
-
`Unknown type kind. Received ${JSON.stringify(
|
|
55
|
+
`Unknown type kind. Received ${JSON.stringify(
|
|
56
|
+
kind
|
|
57
|
+
)}. Use one of: blocks, operators, actions, connections, requests, agents, notifications, websockets.`
|
|
56
58
|
);
|
|
57
59
|
}
|
|
58
60
|
const availableTypes = readBuildArtifact({ name: 'plugins/availableTypes.json' }) ?? {};
|
|
59
61
|
const types = readBuildArtifact({ name: 'types.json', deserialize: true }) ?? {};
|
|
60
62
|
const blockMetas = readBuildArtifact({ name: 'plugins/blockMetas.json' }) ?? {};
|
|
61
|
-
const
|
|
63
|
+
const { entries, typeDocs } = getDocsIndex();
|
|
62
64
|
|
|
63
65
|
const docSlugsByType = new Map();
|
|
64
66
|
const kindSingular = normalizedKind.slice(0, -1);
|
|
65
|
-
for (const
|
|
66
|
-
if (
|
|
67
|
-
docSlugsByType.set(
|
|
67
|
+
for (const entry of entries) {
|
|
68
|
+
if (entry.source === 'core' && entry.kind === kindSingular && entry.typeName) {
|
|
69
|
+
docSlugsByType.set(entry.typeName, entry.slug);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
for (const [key, slug] of typeDocs) {
|
|
73
|
+
const separator = key.indexOf(':');
|
|
74
|
+
if (key.slice(0, separator) === kindSingular) {
|
|
75
|
+
docSlugsByType.set(key.slice(separator + 1), slug);
|
|
68
76
|
}
|
|
69
77
|
}
|
|
70
78
|
|
|
@@ -0,0 +1,40 @@
|
|
|
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
|
+
import fs from 'node:fs';
|
|
17
|
+
import { createRequire } from 'node:module';
|
|
18
|
+
|
|
19
|
+
const require = createRequire(import.meta.url);
|
|
20
|
+
|
|
21
|
+
let hazards;
|
|
22
|
+
|
|
23
|
+
// Framework-level hazards ship hand-authored in @lowdefy/docs-content (its
|
|
24
|
+
// content/ directory is regenerated, hazards.json at the package root is
|
|
25
|
+
// not). Memoized like getDocsManifest: the list changes only with a release.
|
|
26
|
+
function loadFrameworkHazards() {
|
|
27
|
+
if (hazards !== undefined) {
|
|
28
|
+
return hazards;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const hazardsPath = require.resolve('@lowdefy/docs-content/hazards.json');
|
|
32
|
+
hazards = JSON.parse(fs.readFileSync(hazardsPath, 'utf8'));
|
|
33
|
+
} catch {
|
|
34
|
+
// docs-content not installed — type-attached hazards are still served.
|
|
35
|
+
hazards = null;
|
|
36
|
+
}
|
|
37
|
+
return hazards;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default loadFrameworkHazards;
|
|
@@ -0,0 +1,43 @@
|
|
|
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
|
+
import loadFrameworkHazards from './loadFrameworkHazards.js';
|
|
17
|
+
|
|
18
|
+
test('loadFrameworkHazards loads the shipped hazards.json with well-formed unique entries', () => {
|
|
19
|
+
const hazards = loadFrameworkHazards();
|
|
20
|
+
expect(Array.isArray(hazards)).toBe(true);
|
|
21
|
+
expect(hazards.length).toBeGreaterThan(0);
|
|
22
|
+
const ids = hazards.map((hazard) => hazard.id);
|
|
23
|
+
expect(new Set(ids).size).toEqual(ids.length);
|
|
24
|
+
for (const hazard of hazards) {
|
|
25
|
+
expect(hazard.id).toMatch(/^[a-z0-9]+(-[a-z0-9]+)*$/);
|
|
26
|
+
expect(typeof hazard.message).toBe('string');
|
|
27
|
+
expect(hazard.see === null || typeof hazard.see === 'string').toBe(true);
|
|
28
|
+
const { kinds, types, when } = hazard.appliesTo;
|
|
29
|
+
expect(kinds !== undefined || types !== undefined).toBe(true);
|
|
30
|
+
for (const kind of kinds ?? []) {
|
|
31
|
+
expect(['blocks', 'operators', 'actions', 'connections', 'requests', 'pages']).toContain(
|
|
32
|
+
kind
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
if (when !== undefined) {
|
|
36
|
+
expect(when).toEqual('connectionTenantNotNone');
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('loadFrameworkHazards returns the same memoized list on repeated calls', () => {
|
|
42
|
+
expect(loadFrameworkHazards()).toBe(loadFrameworkHazards());
|
|
43
|
+
});
|
package/lib/docs/loadState.js
CHANGED
|
@@ -14,27 +14,35 @@
|
|
|
14
14
|
limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import { type } from '@lowdefy/helpers';
|
|
17
|
+
import { type, urlQuery as urlQueryFn } from '@lowdefy/helpers';
|
|
18
18
|
|
|
19
|
-
import
|
|
20
|
-
import
|
|
19
|
+
import { buildPageUrl, getBrowser, openPage } from './getBrowser.js';
|
|
20
|
+
import noBrowserError from './noBrowserError.js';
|
|
21
21
|
import { loadMocks } from './devMockRegistry.js';
|
|
22
22
|
import { readCheckpoint } from './checkpointStore.js';
|
|
23
|
+
import resolvePageInstance from './resolvePageInstance.js';
|
|
24
|
+
import resolveToolCaller from './resolveToolCaller.js';
|
|
25
|
+
import unsettledPageNote from './unsettledPageNote.js';
|
|
26
|
+
import withBrowserSlot from './withBrowserSlot.js';
|
|
27
|
+
import withDataSession from './withDataSession.js';
|
|
23
28
|
|
|
24
29
|
const VERIFY_KEY_COUNT = 3;
|
|
30
|
+
const READY_TIMEOUT = 15000;
|
|
25
31
|
|
|
26
32
|
// Loads a state checkpoint's recorded requests into devMockRegistry (shared
|
|
27
33
|
// by both modes below — src/routes/request.js consults it regardless of how
|
|
28
34
|
// the page was opened), then either:
|
|
29
|
-
// - 'headless': drives a headless page to the checkpoint's
|
|
30
|
-
// injects its recorded state directly
|
|
35
|
+
// - 'headless': drives a headless page to the checkpoint's page instance
|
|
36
|
+
// (pageId, pathParams) and urlQuery, injects its recorded state directly
|
|
37
|
+
// into that instance's context, and verifies
|
|
31
38
|
// a few keys round-tripped. Good for an agent verifying its own change.
|
|
32
|
-
// Takes a `user`
|
|
33
|
-
// into a page that actually
|
|
39
|
+
// Takes a `user` (and `data`, see resolveToolCaller) so a checkpoint
|
|
40
|
+
// captured on a role-gated page restores into a page that actually
|
|
41
|
+
// renders (see resolveHeadlessUser.js).
|
|
34
42
|
// - 'registry-only': just returns a URL a human can open in a real browser
|
|
35
43
|
// tab — client/Inspector.jsx's `?_checkpoint=` bootstrap does the state
|
|
36
44
|
// injection client-side once that tab loads.
|
|
37
|
-
async function loadState({ origin, name, mode = 'headless', user }) {
|
|
45
|
+
async function loadState({ origin, name, mode = 'headless', user, data }) {
|
|
38
46
|
if (type.isNone(name) || !type.isString(name)) {
|
|
39
47
|
return { error: `loadState requires a "name" string. Received ${JSON.stringify(name)}.` };
|
|
40
48
|
}
|
|
@@ -42,10 +50,10 @@ async function loadState({ origin, name, mode = 'headless', user }) {
|
|
|
42
50
|
// `user` only reaches a page this function opens itself. In 'registry-only'
|
|
43
51
|
// mode the developer opens the returned URL in their own browser, carrying
|
|
44
52
|
// their own session, so an injected caller would be silently dropped.
|
|
45
|
-
if (!type.isNone(user) && mode === 'registry-only') {
|
|
53
|
+
if ((!type.isNone(user) || !type.isNone(data)) && mode === 'registry-only') {
|
|
54
|
+
const param = type.isNone(user) ? 'data' : 'user';
|
|
46
55
|
return {
|
|
47
|
-
error:
|
|
48
|
-
'loadState cannot apply "user" in "registry-only" mode — the developer opens the returned URL in their own browser, carrying their own session. Use the default "headless" mode.',
|
|
56
|
+
error: `loadState cannot apply "${param}" in "registry-only" mode — the developer opens the returned URL in their own browser, carrying their own session and database. Use the default "headless" mode.`,
|
|
49
57
|
invalidInput: true,
|
|
50
58
|
};
|
|
51
59
|
}
|
|
@@ -62,16 +70,25 @@ async function loadState({ origin, name, mode = 'headless', user }) {
|
|
|
62
70
|
return { error: `Checkpoint "${name}" has no recorded pageId.` };
|
|
63
71
|
}
|
|
64
72
|
|
|
73
|
+
const { pathParams } = checkpoint;
|
|
74
|
+
const instance = resolvePageInstance({ pageId, pathParams });
|
|
75
|
+
if (!type.isUndefined(instance.error)) {
|
|
76
|
+
return { error: `Checkpoint "${name}" cannot open its page: ${instance.error}` };
|
|
77
|
+
}
|
|
78
|
+
|
|
65
79
|
loadMocks({ pageId, mocks: checkpoint.requests });
|
|
66
80
|
|
|
67
|
-
|
|
68
|
-
const urlQuery = checkpoint.urlQuery
|
|
81
|
+
// The checkpoint keeps the query string the page was captured at.
|
|
82
|
+
const urlQuery = urlQueryFn.parse(checkpoint.urlQuery);
|
|
69
83
|
|
|
70
84
|
if (mode === 'registry-only') {
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
85
|
+
const url = buildPageUrl({
|
|
86
|
+
origin,
|
|
87
|
+
pageId,
|
|
88
|
+
path: instance.path,
|
|
89
|
+
pathParams,
|
|
90
|
+
urlQuery: { ...urlQuery, _checkpoint: name },
|
|
91
|
+
});
|
|
75
92
|
return {
|
|
76
93
|
url,
|
|
77
94
|
instructions:
|
|
@@ -91,55 +108,106 @@ async function loadState({ origin, name, mode = 'headless', user }) {
|
|
|
91
108
|
return { error: `loadState requires an "origin" string. Received ${JSON.stringify(origin)}.` };
|
|
92
109
|
}
|
|
93
110
|
|
|
111
|
+
const caller = await resolveToolCaller({ user, data });
|
|
112
|
+
if (!type.isUndefined(caller.error)) {
|
|
113
|
+
return caller;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return withBrowserSlot({
|
|
117
|
+
task: () =>
|
|
118
|
+
withDataSession({
|
|
119
|
+
dataSet: caller.dataSet,
|
|
120
|
+
task: ({ dataCookie }) =>
|
|
121
|
+
loadStateInBrowser({
|
|
122
|
+
origin,
|
|
123
|
+
name,
|
|
124
|
+
mode,
|
|
125
|
+
user: caller.user,
|
|
126
|
+
dataCookie,
|
|
127
|
+
pageId,
|
|
128
|
+
instance,
|
|
129
|
+
pathParams,
|
|
130
|
+
urlQuery,
|
|
131
|
+
checkpoint,
|
|
132
|
+
}),
|
|
133
|
+
}),
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// The part of loadState that runs in the browser, inside a browser slot.
|
|
138
|
+
async function loadStateInBrowser({
|
|
139
|
+
origin,
|
|
140
|
+
name,
|
|
141
|
+
mode,
|
|
142
|
+
user,
|
|
143
|
+
dataCookie,
|
|
144
|
+
pageId,
|
|
145
|
+
instance,
|
|
146
|
+
pathParams,
|
|
147
|
+
urlQuery,
|
|
148
|
+
checkpoint,
|
|
149
|
+
}) {
|
|
94
150
|
let browser;
|
|
95
151
|
try {
|
|
96
152
|
browser = await getBrowser();
|
|
97
153
|
} catch (error) {
|
|
98
|
-
return {
|
|
99
|
-
error: `No Chromium available. Run: npx playwright install chromium (${error.message})`,
|
|
100
|
-
};
|
|
154
|
+
return { error: noBrowserError(error) };
|
|
101
155
|
}
|
|
102
156
|
|
|
103
157
|
let context;
|
|
104
158
|
try {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
159
|
+
const opened = await openPage({
|
|
160
|
+
browser,
|
|
161
|
+
origin,
|
|
162
|
+
pageId,
|
|
163
|
+
path: instance.path,
|
|
164
|
+
pathParams,
|
|
165
|
+
urlQuery,
|
|
166
|
+
user,
|
|
167
|
+
dataCookie,
|
|
168
|
+
timeout: READY_TIMEOUT,
|
|
169
|
+
});
|
|
110
170
|
context = opened.context;
|
|
111
171
|
const { page } = opened;
|
|
112
172
|
|
|
113
|
-
await page.waitForFunction(
|
|
114
|
-
|
|
115
|
-
|
|
173
|
+
await page.waitForFunction(
|
|
174
|
+
(contextKey) => Boolean(window.lowdefy?.contexts?.[contextKey]),
|
|
175
|
+
instance.instanceKey,
|
|
176
|
+
{
|
|
177
|
+
timeout: READY_TIMEOUT,
|
|
178
|
+
}
|
|
179
|
+
);
|
|
116
180
|
|
|
117
181
|
const stateEntries = Object.entries(checkpoint.state ?? {});
|
|
118
182
|
await page.evaluate(
|
|
119
|
-
({
|
|
120
|
-
const pageContext = window.lowdefy.contexts[
|
|
183
|
+
({ contextKey, entries }) => {
|
|
184
|
+
const pageContext = window.lowdefy.contexts[contextKey];
|
|
121
185
|
entries.forEach(([key, value]) => {
|
|
122
186
|
pageContext._internal.State.set(key, value);
|
|
123
187
|
});
|
|
124
188
|
pageContext._internal.update();
|
|
125
189
|
},
|
|
126
|
-
{
|
|
190
|
+
{ contextKey: instance.instanceKey, entries: stateEntries }
|
|
127
191
|
);
|
|
128
192
|
|
|
129
193
|
const verifyKeys = stateEntries.slice(0, VERIFY_KEY_COUNT).map(([key]) => key);
|
|
130
194
|
const verifiedKeys = await page.evaluate(
|
|
131
|
-
({
|
|
132
|
-
const pageContext = window.lowdefy.contexts[
|
|
195
|
+
({ contextKey, keys }) => {
|
|
196
|
+
const pageContext = window.lowdefy.contexts[contextKey];
|
|
133
197
|
const result = {};
|
|
134
198
|
keys.forEach((key) => {
|
|
135
199
|
result[key] = pageContext.state?.[key];
|
|
136
200
|
});
|
|
137
201
|
return result;
|
|
138
202
|
},
|
|
139
|
-
{
|
|
203
|
+
{ contextKey: instance.instanceKey, keys: verifyKeys }
|
|
140
204
|
);
|
|
141
205
|
|
|
142
|
-
|
|
206
|
+
const result = { loaded: true, mode, url: opened.url, verifiedKeys };
|
|
207
|
+
if (!opened.ready) {
|
|
208
|
+
return { ...result, ready: false, note: unsettledPageNote({ timeout: READY_TIMEOUT }) };
|
|
209
|
+
}
|
|
210
|
+
return result;
|
|
143
211
|
} catch (error) {
|
|
144
212
|
return { error: `Failed to load checkpoint "${name}": ${error.message}` };
|
|
145
213
|
} finally {
|