@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
|
@@ -73,7 +73,7 @@ test('resolveSource marks a user combined with source "tab" as invalid input', (
|
|
|
73
73
|
|
|
74
74
|
expect(result.invalidInput).toBe(true);
|
|
75
75
|
expect(result.error).toBe(
|
|
76
|
-
'inspectState cannot apply "user" to the developer\'s live tab — it carries their real session. Omit "source", or use "headless".'
|
|
76
|
+
'inspectState cannot apply "user" to the developer\'s live tab — it carries their real session and database. Omit "source", or use "headless".'
|
|
77
77
|
);
|
|
78
78
|
expect(result.tryTab).toBeUndefined();
|
|
79
79
|
});
|
|
@@ -0,0 +1,62 @@
|
|
|
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 readDevAuthMode from './readDevAuthMode.js';
|
|
21
|
+
import resolveJourneyDataSet from './dataSets/resolveJourneyDataSet.js';
|
|
22
|
+
|
|
23
|
+
const SHAPE =
|
|
24
|
+
'"user" should be a user object, e.g. {"roles":["admin"]}, "none" to act signed out, or the name of a user in the data set named by "data".';
|
|
25
|
+
|
|
26
|
+
// Who a dev tool call acts as, in the forms a journey takes: a user object
|
|
27
|
+
// (merged over the roleless headless default), "none" (no injected caller,
|
|
28
|
+
// so the app's own auth decides), or the name of a user in the data set
|
|
29
|
+
// `data` names. A data set also runs the call on a fresh database of its own,
|
|
30
|
+
// loaded with it (see withDataSession). Returns { user, dataSet } - user is
|
|
31
|
+
// the object, "none" or undefined; dataSet is undefined without `data` - or
|
|
32
|
+
// { error, invalidInput: true } for a caller the call cannot act as.
|
|
33
|
+
async function resolveToolCaller({ user, data }) {
|
|
34
|
+
if (!type.isNone(data) && !type.isString(data)) {
|
|
35
|
+
return {
|
|
36
|
+
error: `"data" should be the name of a data set in tests/data/<name>.yaml. Received ${JSON.stringify(
|
|
37
|
+
data
|
|
38
|
+
)}.`,
|
|
39
|
+
invalidInput: true,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
if (!type.isNone(user) && !type.isObject(user) && !type.isString(user)) {
|
|
43
|
+
return { error: `${SHAPE} Received ${JSON.stringify(user)}.`, invalidInput: true };
|
|
44
|
+
}
|
|
45
|
+
if (user === '') {
|
|
46
|
+
return { error: `${SHAPE} Received "".`, invalidInput: true };
|
|
47
|
+
}
|
|
48
|
+
const resolved = await resolveJourneyDataSet({
|
|
49
|
+
data,
|
|
50
|
+
user: user ?? undefined,
|
|
51
|
+
subject: 'call',
|
|
52
|
+
configDirectory: process.env.LOWDEFY_DIRECTORY_CONFIG ?? process.cwd(),
|
|
53
|
+
buildDirectory: path.join(process.cwd(), 'build'),
|
|
54
|
+
...readDevAuthMode(),
|
|
55
|
+
});
|
|
56
|
+
if (!type.isUndefined(resolved.error)) {
|
|
57
|
+
return { error: resolved.error, invalidInput: true };
|
|
58
|
+
}
|
|
59
|
+
return { user: resolved.user, dataSet: resolved.dataSet };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export default resolveToolCaller;
|
|
@@ -0,0 +1,51 @@
|
|
|
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
|
+
import pageBuildRecords from '../server/pageBuildRecords.js';
|
|
21
|
+
import { reviewBuiltPage } from '../server/jitPageBuilder.js';
|
|
22
|
+
|
|
23
|
+
async function readModifiedAt(filePath) {
|
|
24
|
+
try {
|
|
25
|
+
return (await fs.promises.stat(filePath)).mtimeMs;
|
|
26
|
+
} catch {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// A page built since the server started is edited when its next request would
|
|
32
|
+
// rebuild it (see reviewBuiltPage): it was built on an earlier build context
|
|
33
|
+
// (a config build was published since), or a change event since its build
|
|
34
|
+
// touched it, which for a page whose build ran app code is any change event.
|
|
35
|
+
// A page not built since the server started is edited when its own page file
|
|
36
|
+
// changed after the start. signals is what syncBuildSignals returned.
|
|
37
|
+
// Returns 'edited', 'unbuilt' (never built and not edited) or 'current'.
|
|
38
|
+
async function reviewPage({ pageId, entry, configDirectory, signals }) {
|
|
39
|
+
if (pageBuildRecords.get(pageId)) {
|
|
40
|
+
return reviewBuiltPage({ pageId, ...signals });
|
|
41
|
+
}
|
|
42
|
+
const pageFileModifiedAt = entry?.refPath
|
|
43
|
+
? await readModifiedAt(path.resolve(configDirectory, entry.refPath))
|
|
44
|
+
: null;
|
|
45
|
+
if (pageFileModifiedAt !== null && pageFileModifiedAt > performance.timeOrigin) {
|
|
46
|
+
return 'edited';
|
|
47
|
+
}
|
|
48
|
+
return 'unbuilt';
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export default reviewPage;
|
|
@@ -0,0 +1,56 @@
|
|
|
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
|
+
|
|
19
|
+
import pageBuildRecords from '../server/pageBuildRecords.js';
|
|
20
|
+
import { syncBuildSignals } from '../server/jitPageBuilder.js';
|
|
21
|
+
import reviewPage from './reviewPage.js';
|
|
22
|
+
|
|
23
|
+
// Sorts the registered pages by what the dev server knows about them (see
|
|
24
|
+
// reviewPage): edited, unbuilt, and failed, the pages whose last build failed,
|
|
25
|
+
// with its errors. The build signals are read first, so an edit no page
|
|
26
|
+
// request has seen yet is reviewed too; pages that share a file read it once,
|
|
27
|
+
// through the build context's read cache.
|
|
28
|
+
async function reviewPageBuilds() {
|
|
29
|
+
const buildDirectory = path.join(process.cwd(), 'build');
|
|
30
|
+
const configDirectory = process.env.LOWDEFY_DIRECTORY_CONFIG || process.cwd();
|
|
31
|
+
const signals = syncBuildSignals({ buildDirectory, configDirectory });
|
|
32
|
+
const registry = signals.registry ?? {};
|
|
33
|
+
const pageIds = Object.keys(registry);
|
|
34
|
+
const reviews = await Promise.all(
|
|
35
|
+
pageIds.map((pageId) =>
|
|
36
|
+
reviewPage({ pageId, entry: registry[pageId], configDirectory, signals })
|
|
37
|
+
)
|
|
38
|
+
);
|
|
39
|
+
const edited = [];
|
|
40
|
+
const unbuilt = [];
|
|
41
|
+
const failed = [];
|
|
42
|
+
pageIds.forEach((pageId, index) => {
|
|
43
|
+
const errors = pageBuildRecords.get(pageId)?.errors;
|
|
44
|
+
if (errors) {
|
|
45
|
+
failed.push({ pageId, errors });
|
|
46
|
+
}
|
|
47
|
+
if (reviews[index] === 'edited') {
|
|
48
|
+
edited.push(pageId);
|
|
49
|
+
} else if (reviews[index] === 'unbuilt') {
|
|
50
|
+
unbuilt.push(pageId);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
return { edited, unbuilt, failed };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export default reviewPageBuilds;
|
|
@@ -0,0 +1,207 @@
|
|
|
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 { jest } from '@jest/globals';
|
|
19
|
+
import os from 'node:os';
|
|
20
|
+
import path from 'node:path';
|
|
21
|
+
|
|
22
|
+
// reviewPageBuilds reads the build from process.cwd()/build and page files
|
|
23
|
+
// from LOWDEFY_DIRECTORY_CONFIG: point both at a throwaway app, and build its
|
|
24
|
+
// pages with the dev server's real page builder.
|
|
25
|
+
const serverDirectory = fs.mkdtempSync(path.join(os.tmpdir(), 'lowdefy-review-pages-'));
|
|
26
|
+
const buildDirectory = path.join(serverDirectory, 'build');
|
|
27
|
+
const configDirectory = path.join(serverDirectory, 'config');
|
|
28
|
+
process.chdir(serverDirectory);
|
|
29
|
+
process.env.LOWDEFY_DIRECTORY_CONFIG = configDirectory;
|
|
30
|
+
|
|
31
|
+
const { default: buildPageIfNeeded } = await import('../server/jitPageBuilder.js');
|
|
32
|
+
const { default: buildEditedPages } = await import('./buildEditedPages.js');
|
|
33
|
+
const { default: reviewPageBuilds } = await import('./reviewPageBuilds.js');
|
|
34
|
+
|
|
35
|
+
// A JIT page build loads the build package's plugins on first use.
|
|
36
|
+
jest.setTimeout(30000);
|
|
37
|
+
|
|
38
|
+
const longAgo = new Date('2000-01-01T00:00:00.000Z');
|
|
39
|
+
let lastSignal = 0;
|
|
40
|
+
|
|
41
|
+
function writeFile(filePath, content) {
|
|
42
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
43
|
+
fs.writeFileSync(filePath, content);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function writeConfigFile(relativePath, content, { modified } = {}) {
|
|
47
|
+
const filePath = path.join(configDirectory, relativePath);
|
|
48
|
+
writeFile(filePath, content);
|
|
49
|
+
if (modified) {
|
|
50
|
+
fs.utimesSync(filePath, modified, modified);
|
|
51
|
+
}
|
|
52
|
+
return filePath;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// A config build's output, as far as a JIT page build reads it. Each call
|
|
56
|
+
// publishes a new page registry, as a config build does.
|
|
57
|
+
function publishBuild(pageIds) {
|
|
58
|
+
writeFile(path.join(buildDirectory, 'idCounter.json'), '{"prefix":"cfg1_","counter":10}');
|
|
59
|
+
writeFile(path.join(buildDirectory, 'installedPluginPackages.json'), '["@lowdefy/blocks-basic"]');
|
|
60
|
+
writeFile(path.join(buildDirectory, 'theme.json'), '{}');
|
|
61
|
+
const registry = Object.fromEntries(
|
|
62
|
+
pageIds.map((pageId) => [
|
|
63
|
+
pageId,
|
|
64
|
+
{ pageId, auth: { public: true }, refId: `ref-${pageId}`, refPath: `pages/${pageId}.yaml` },
|
|
65
|
+
])
|
|
66
|
+
);
|
|
67
|
+
const registryPath = path.join(buildDirectory, 'pageRegistry.json');
|
|
68
|
+
writeFile(`${registryPath}.staged`, JSON.stringify(registry));
|
|
69
|
+
fs.renameSync(`${registryPath}.staged`, registryPath);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// What the manager writes after a batch of watched changes.
|
|
73
|
+
function signalChange() {
|
|
74
|
+
lastSignal += 1;
|
|
75
|
+
writeFile(path.join(buildDirectory, 'invalidatePages'), String(lastSignal));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function request(pageId) {
|
|
79
|
+
return buildPageIfNeeded({ pageId, buildDirectory, configDirectory }).then(
|
|
80
|
+
(result) => (result === true ? 'served' : 'built'),
|
|
81
|
+
() => 'failed'
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
beforeEach(() => {
|
|
86
|
+
fs.rmSync(configDirectory, { recursive: true, force: true });
|
|
87
|
+
writeConfigFile('package.json', '{"type":"module"}');
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test('a built page whose files are unchanged is neither edited nor unbuilt', async () => {
|
|
91
|
+
writeConfigFile(
|
|
92
|
+
'pages/current.yaml',
|
|
93
|
+
'id: current\ntype: Box\nblocks:\n - _ref: shared.yaml\n',
|
|
94
|
+
{
|
|
95
|
+
modified: longAgo,
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
writeConfigFile('shared.yaml', 'id: shared\ntype: Box\n', { modified: longAgo });
|
|
99
|
+
publishBuild(['current']);
|
|
100
|
+
await request('current');
|
|
101
|
+
signalChange();
|
|
102
|
+
|
|
103
|
+
expect(await reviewPageBuilds()).toEqual({ edited: [], unbuilt: [], failed: [] });
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test('right after an edit, with no page request since, the edited pages are listed', async () => {
|
|
107
|
+
writeConfigFile('pages/a.yaml', 'id: a\ntype: Box\nblocks:\n - _ref: shared.yaml\n');
|
|
108
|
+
writeConfigFile('pages/b.yaml', 'id: b\ntype: Box\n');
|
|
109
|
+
writeConfigFile('shared.yaml', 'id: shared\ntype: Box\n');
|
|
110
|
+
publishBuild(['a', 'b']);
|
|
111
|
+
await request('a');
|
|
112
|
+
await request('b');
|
|
113
|
+
|
|
114
|
+
writeConfigFile('shared.yaml', 'id: shared\ntype: Box\nproperties:\n title: New\n');
|
|
115
|
+
signalChange();
|
|
116
|
+
|
|
117
|
+
expect((await reviewPageBuilds()).edited).toEqual(['a']);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test('a built page is edited when a file its build read is gone', async () => {
|
|
121
|
+
writeConfigFile('pages/removed.yaml', 'id: removed\ntype: Box\n');
|
|
122
|
+
publishBuild(['removed']);
|
|
123
|
+
await request('removed');
|
|
124
|
+
fs.rmSync(path.join(configDirectory, 'pages/removed.yaml'));
|
|
125
|
+
signalChange();
|
|
126
|
+
|
|
127
|
+
expect((await reviewPageBuilds()).edited).toEqual(['removed']);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test('after an unrelated edit, a page whose build ran app code is edited and a YAML-only page is not', async () => {
|
|
131
|
+
writeConfigFile('pages/coded.yaml', 'id: coded\ntype: Box\nblocks:\n - _ref: banner.js\n');
|
|
132
|
+
writeConfigFile('banner.js', "export default { id: 'banner', type: 'Box' };\n");
|
|
133
|
+
writeConfigFile('pages/plain.yaml', 'id: plain\ntype: Box\n');
|
|
134
|
+
writeConfigFile('pages/other.yaml', 'id: other\ntype: Box\n');
|
|
135
|
+
publishBuild(['coded', 'plain', 'other']);
|
|
136
|
+
await request('coded');
|
|
137
|
+
await request('plain');
|
|
138
|
+
|
|
139
|
+
writeConfigFile('pages/other.yaml', 'id: other\ntype: Box\nproperties:\n title: Edited\n');
|
|
140
|
+
signalChange();
|
|
141
|
+
|
|
142
|
+
const { edited } = await reviewPageBuilds();
|
|
143
|
+
expect(edited).toContain('coded');
|
|
144
|
+
expect(edited).not.toContain('plain');
|
|
145
|
+
expect(await buildEditedPages()).toContain('coded');
|
|
146
|
+
expect(await request('plain')).toBe('served');
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test('after a config publish every built page is edited, also one whose build failed', async () => {
|
|
150
|
+
writeConfigFile('pages/before.yaml', 'id: before\ntype: Box\n');
|
|
151
|
+
writeConfigFile(
|
|
152
|
+
'pages/failed_before.yaml',
|
|
153
|
+
'id: failed_before\ntype: Box\nblocks:\n - id: x\n type: Buton\n'
|
|
154
|
+
);
|
|
155
|
+
publishBuild(['before', 'failed_before']);
|
|
156
|
+
await request('before');
|
|
157
|
+
expect(await request('failed_before')).toBe('failed');
|
|
158
|
+
|
|
159
|
+
publishBuild(['before', 'failed_before']);
|
|
160
|
+
|
|
161
|
+
expect((await reviewPageBuilds()).edited).toEqual(['before', 'failed_before']);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
test('a page whose last build failed is listed with its errors', async () => {
|
|
165
|
+
writeConfigFile(
|
|
166
|
+
'pages/broken.yaml',
|
|
167
|
+
'id: broken\ntype: Box\nblocks:\n - id: x\n type: Buton\n'
|
|
168
|
+
);
|
|
169
|
+
publishBuild(['broken']);
|
|
170
|
+
await request('broken');
|
|
171
|
+
|
|
172
|
+
const { failed } = await reviewPageBuilds();
|
|
173
|
+
expect(failed.map((page) => page.pageId)).toEqual(['broken']);
|
|
174
|
+
expect(failed[0].errors[0].message).toContain('Buton');
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
test('a page never built is edited when its page file changed after the server started, and unbuilt otherwise', async () => {
|
|
178
|
+
writeConfigFile('pages/new.yaml', 'id: new\ntype: Box\n');
|
|
179
|
+
writeConfigFile('pages/old.yaml', 'id: old\ntype: Box\n', { modified: longAgo });
|
|
180
|
+
publishBuild(['new', 'old', 'missing']);
|
|
181
|
+
|
|
182
|
+
expect(await reviewPageBuilds()).toEqual({
|
|
183
|
+
edited: ['new'],
|
|
184
|
+
unbuilt: ['old', 'missing'],
|
|
185
|
+
failed: [],
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
test('a wait builds exactly the pages the next requests would rebuild', async () => {
|
|
190
|
+
writeConfigFile('pages/one.yaml', 'id: one\ntype: Box\nblocks:\n - _ref: common.yaml\n');
|
|
191
|
+
writeConfigFile('pages/two.yaml', 'id: two\ntype: Box\nblocks:\n - _ref: common.yaml\n');
|
|
192
|
+
writeConfigFile('pages/three.yaml', 'id: three\ntype: Box\n');
|
|
193
|
+
writeConfigFile('pages/coded.yaml', 'id: coded\ntype: Box\nblocks:\n - _ref: banner.js\n');
|
|
194
|
+
writeConfigFile('banner.js', "export default { id: 'banner', type: 'Box' };\n");
|
|
195
|
+
writeConfigFile('common.yaml', 'id: common\ntype: Box\n');
|
|
196
|
+
const pageIds = ['one', 'two', 'three', 'coded'];
|
|
197
|
+
publishBuild(pageIds);
|
|
198
|
+
for (const pageId of pageIds) await request(pageId);
|
|
199
|
+
|
|
200
|
+
writeConfigFile('common.yaml', 'id: common\ntype: Box\nproperties:\n title: New\n');
|
|
201
|
+
signalChange();
|
|
202
|
+
|
|
203
|
+
expect((await buildEditedPages()).sort()).toEqual(['coded', 'one', 'two']);
|
|
204
|
+
for (const pageId of pageIds) {
|
|
205
|
+
expect(await request(pageId)).toBe('served');
|
|
206
|
+
}
|
|
207
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
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 { fileURLToPath } from 'url';
|
|
17
|
+
import { execFile } from 'child_process';
|
|
18
|
+
import { promisify } from 'util';
|
|
19
|
+
|
|
20
|
+
const execFileAsync = promisify(execFile);
|
|
21
|
+
|
|
22
|
+
const childPath = fileURLToPath(new URL('./runCheckChild.js', import.meta.url));
|
|
23
|
+
|
|
24
|
+
// Reports must be readable by an agent even when the check itself broke, so
|
|
25
|
+
// the report shape always comes back; a broken run is one unlocated error.
|
|
26
|
+
function brokenReport(message) {
|
|
27
|
+
return {
|
|
28
|
+
ok: false,
|
|
29
|
+
errors: [
|
|
30
|
+
{
|
|
31
|
+
message,
|
|
32
|
+
name: 'LowdefyInternalError',
|
|
33
|
+
source: null,
|
|
34
|
+
config: null,
|
|
35
|
+
configKey: null,
|
|
36
|
+
checkSlug: null,
|
|
37
|
+
prodError: false,
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
warnings: [],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Runs `check` from @lowdefy/build against this dev server's config in a child
|
|
45
|
+
// node process. The dev server directory is already installed, so no install
|
|
46
|
+
// is needed — but @lowdefy/build keeps module-level state (the makeId counter
|
|
47
|
+
// the JIT page builder relies on for stable ~k keys), and a full check resets
|
|
48
|
+
// it, so the check cannot share this process with the running server.
|
|
49
|
+
async function runCheck() {
|
|
50
|
+
const serverDirectory = process.cwd();
|
|
51
|
+
const configDirectory = process.env.LOWDEFY_DIRECTORY_CONFIG || serverDirectory;
|
|
52
|
+
let stdout;
|
|
53
|
+
try {
|
|
54
|
+
({ stdout } = await execFileAsync(process.execPath, [childPath], {
|
|
55
|
+
cwd: serverDirectory,
|
|
56
|
+
env: {
|
|
57
|
+
...process.env,
|
|
58
|
+
LOWDEFY_DIRECTORY_CONFIG: configDirectory,
|
|
59
|
+
LOWDEFY_DIRECTORY_SERVER: serverDirectory,
|
|
60
|
+
},
|
|
61
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
62
|
+
}));
|
|
63
|
+
} catch (error) {
|
|
64
|
+
return brokenReport(
|
|
65
|
+
`lowdefy check failed to run: ${error.message}${
|
|
66
|
+
error.stderr ? `\n${String(error.stderr).trim()}` : ''
|
|
67
|
+
}`
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
const lastLine = stdout.trim().split('\n').pop();
|
|
71
|
+
const report = JSON.parse(lastLine);
|
|
72
|
+
return { ok: report.errors.length === 0, ...report };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export default runCheck;
|
|
@@ -0,0 +1,91 @@
|
|
|
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 { jest } from '@jest/globals';
|
|
17
|
+
|
|
18
|
+
jest.unstable_mockModule('child_process', () => ({
|
|
19
|
+
execFile: jest.fn(),
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
const { execFile } = await import('child_process');
|
|
23
|
+
const { default: runCheck } = await import('./runCheck.js');
|
|
24
|
+
|
|
25
|
+
const locatedError = {
|
|
26
|
+
message: 'Page "nope" referenced in menu link "x" not found.',
|
|
27
|
+
name: 'ConfigWarning',
|
|
28
|
+
source: '/app/lowdefy.yaml:5',
|
|
29
|
+
config: 'root.menus[0:default].links[0:x:MenuLink]',
|
|
30
|
+
configKey: 'a',
|
|
31
|
+
checkSlug: 'link-refs',
|
|
32
|
+
prodError: true,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
function mockChild({ stdout, error }) {
|
|
36
|
+
execFile.mockImplementation((file, args, options, callback) => {
|
|
37
|
+
if (error) {
|
|
38
|
+
callback(error, { stdout: '', stderr: error.stderr ?? '' });
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
callback(null, { stdout, stderr: '' });
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const originalConfigDirectory = process.env.LOWDEFY_DIRECTORY_CONFIG;
|
|
46
|
+
|
|
47
|
+
beforeEach(() => {
|
|
48
|
+
process.env.LOWDEFY_DIRECTORY_CONFIG = '/app';
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
afterEach(() => {
|
|
52
|
+
if (originalConfigDirectory === undefined) {
|
|
53
|
+
delete process.env.LOWDEFY_DIRECTORY_CONFIG;
|
|
54
|
+
} else {
|
|
55
|
+
process.env.LOWDEFY_DIRECTORY_CONFIG = originalConfigDirectory;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('runCheck runs the child in the server directory against the config directory', async () => {
|
|
60
|
+
mockChild({ stdout: `${JSON.stringify({ errors: [], warnings: [] })}\n` });
|
|
61
|
+
const result = await runCheck();
|
|
62
|
+
expect(result).toEqual({ ok: true, errors: [], warnings: [] });
|
|
63
|
+
const [file, args, options] = execFile.mock.calls[0];
|
|
64
|
+
expect(file).toBe(process.execPath);
|
|
65
|
+
expect(args[0]).toMatch(/runCheckChild\.js$/);
|
|
66
|
+
expect(options.cwd).toBe(process.cwd());
|
|
67
|
+
expect(options.env.LOWDEFY_DIRECTORY_CONFIG).toBe('/app');
|
|
68
|
+
expect(options.env.LOWDEFY_DIRECTORY_SERVER).toBe(process.cwd());
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('runCheck returns the located errors and warnings with ok false when there are errors', async () => {
|
|
72
|
+
const report = { errors: [locatedError], warnings: [{ ...locatedError, prodError: false }] };
|
|
73
|
+
mockChild({ stdout: `some stray log line\n${JSON.stringify(report)}\n` });
|
|
74
|
+
const result = await runCheck();
|
|
75
|
+
expect(result).toEqual({ ok: false, ...report });
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test('runCheck reports a broken check run as one unlocated internal error', async () => {
|
|
79
|
+
const error = new Error('Command failed: node runCheckChild.js');
|
|
80
|
+
error.stderr = 'TypeError: boom\n';
|
|
81
|
+
mockChild({ error });
|
|
82
|
+
const result = await runCheck();
|
|
83
|
+
expect(result.ok).toBe(false);
|
|
84
|
+
expect(result.warnings).toEqual([]);
|
|
85
|
+
expect(result.errors).toHaveLength(1);
|
|
86
|
+
expect(result.errors[0].name).toBe('LowdefyInternalError');
|
|
87
|
+
expect(result.errors[0].source).toBeNull();
|
|
88
|
+
expect(result.errors[0].message).toBe(
|
|
89
|
+
'lowdefy check failed to run: Command failed: node runCheckChild.js\nTypeError: boom'
|
|
90
|
+
);
|
|
91
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
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 path from 'path';
|
|
17
|
+
|
|
18
|
+
import { check } from '@lowdefy/build/dev';
|
|
19
|
+
import { createNodeLogger } from '@lowdefy/logger/node';
|
|
20
|
+
|
|
21
|
+
import createCustomPluginMessagesMap from '../../manager/utils/createCustomPluginMessagesMap.mjs';
|
|
22
|
+
import createCustomPluginTypesMap from '../../manager/utils/createCustomPluginTypesMap.mjs';
|
|
23
|
+
|
|
24
|
+
// Child process for runCheck.js: prints the { errors, warnings } report as the
|
|
25
|
+
// last line of stdout and exits 0 whenever the check ran. The logger is silent
|
|
26
|
+
// because every error and warning is in the report already.
|
|
27
|
+
async function run() {
|
|
28
|
+
const serverDirectory = path.resolve(process.env.LOWDEFY_DIRECTORY_SERVER ?? process.cwd());
|
|
29
|
+
const directories = {
|
|
30
|
+
build: path.join(serverDirectory, 'build'),
|
|
31
|
+
config: path.resolve(process.env.LOWDEFY_DIRECTORY_CONFIG ?? process.cwd()),
|
|
32
|
+
server: serverDirectory,
|
|
33
|
+
};
|
|
34
|
+
const logger = createNodeLogger({ name: 'lowdefy_check', level: 'silent' });
|
|
35
|
+
const [customTypesMap, customMessagesMap] = await Promise.all([
|
|
36
|
+
createCustomPluginTypesMap({ directories, logger }),
|
|
37
|
+
createCustomPluginMessagesMap({ directories, logger }),
|
|
38
|
+
]);
|
|
39
|
+
const report = await check({
|
|
40
|
+
customMessagesMap,
|
|
41
|
+
customTypesMap,
|
|
42
|
+
directories,
|
|
43
|
+
logger,
|
|
44
|
+
refResolver: process.env.LOWDEFY_BUILD_REF_RESOLVER,
|
|
45
|
+
});
|
|
46
|
+
process.stdout.write(`${JSON.stringify(report)}\n`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
run();
|