@mistriwork/engine 0.0.0-stage → 1.0.0-rc.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +17 -2
- package/dist/adapters/adapter.d.ts +693 -0
- package/dist/adapters/adapter.js +444 -0
- package/dist/adapters/cache/cacheStore.d.ts +75 -0
- package/dist/adapters/cache/cacheStore.js +160 -0
- package/dist/adapters/cache/resp.d.ts +52 -0
- package/dist/adapters/cache/resp.js +237 -0
- package/dist/adapters/commands/canonicalJson.d.ts +19 -0
- package/dist/adapters/commands/canonicalJson.js +154 -0
- package/dist/adapters/connect.d.ts +29 -0
- package/dist/adapters/connect.js +40 -0
- package/dist/adapters/connectionBudget.d.ts +101 -0
- package/dist/adapters/connectionBudget.js +128 -0
- package/dist/adapters/dbLatency.d.ts +35 -0
- package/dist/adapters/dbLatency.js +79 -0
- package/dist/adapters/epochCache.d.ts +50 -0
- package/dist/adapters/epochCache.js +85 -0
- package/dist/adapters/http/egress.d.ts +48 -0
- package/dist/adapters/http/egress.js +175 -0
- package/dist/adapters/http/httpAdapter.d.ts +71 -0
- package/dist/adapters/http/httpAdapter.js +512 -0
- package/dist/adapters/http/httpDescription.d.ts +32 -0
- package/dist/adapters/http/httpDescription.js +246 -0
- package/dist/adapters/http/openapi.d.ts +98 -0
- package/dist/adapters/http/openapi.js +487 -0
- package/dist/adapters/layoutRefusal.d.ts +24 -0
- package/dist/adapters/layoutRefusal.js +35 -0
- package/dist/adapters/net/networkPolicy.d.ts +44 -0
- package/dist/adapters/net/networkPolicy.js +123 -0
- package/dist/adapters/net/untrustedDatabase.d.ts +18 -0
- package/dist/adapters/net/untrustedDatabase.js +120 -0
- package/dist/adapters/poolAdmission.d.ts +43 -0
- package/dist/adapters/poolAdmission.js +184 -0
- package/dist/adapters/poolMetrics.d.ts +121 -0
- package/dist/adapters/poolMetrics.js +185 -0
- package/dist/adapters/postgres.d.ts +436 -0
- package/dist/adapters/postgres.js +1890 -0
- package/dist/adapters/postgresCatalog.d.ts +96 -0
- package/dist/adapters/postgresCatalog.js +387 -0
- package/dist/adapters/postgresCatalogDigest.d.ts +30 -0
- package/dist/adapters/postgresCatalogDigest.js +87 -0
- package/dist/adapters/postgresCatalogRows.d.ts +62 -0
- package/dist/adapters/postgresCatalogRows.js +37 -0
- package/dist/adapters/postgresDates.d.ts +1 -0
- package/dist/adapters/postgresDates.js +39 -0
- package/dist/adapters/postgresMaintenance.d.ts +33 -0
- package/dist/adapters/postgresMaintenance.js +179 -0
- package/dist/adapters/postgresPool.d.ts +255 -0
- package/dist/adapters/postgresPool.js +838 -0
- package/dist/adapters/postgresPooler.d.ts +28 -0
- package/dist/adapters/postgresPooler.js +267 -0
- package/dist/adapters/postgresReadCatalog.d.ts +31 -0
- package/dist/adapters/postgresReadCatalog.js +226 -0
- package/dist/adapters/postgresReadSnapshot.d.ts +46 -0
- package/dist/adapters/postgresReadSnapshot.js +133 -0
- package/dist/adapters/postgresSchemaEpoch.d.ts +24 -0
- package/dist/adapters/postgresSchemaEpoch.js +149 -0
- package/dist/adapters/postgresTransactionHandle.d.ts +173 -0
- package/dist/adapters/postgresTransactionHandle.js +524 -0
- package/dist/adapters/postgresValues.d.ts +30 -0
- package/dist/adapters/postgresValues.js +75 -0
- package/dist/adapters/replicas.d.ts +70 -0
- package/dist/adapters/replicas.js +208 -0
- package/dist/adapters/reservedSql.d.ts +38 -0
- package/dist/adapters/reservedSql.js +264 -0
- package/dist/adapters/rolePrivileges.d.ts +17 -0
- package/dist/adapters/rolePrivileges.js +22 -0
- package/dist/adapters/scoped/keyRows.d.ts +65 -0
- package/dist/adapters/scoped/keyRows.js +173 -0
- package/dist/adapters/scoped/postgresScopeCatalog.d.ts +16 -0
- package/dist/adapters/scoped/postgresScopeCatalog.js +117 -0
- package/dist/adapters/scoped/scopedCommandOperations.d.ts +5 -0
- package/dist/adapters/scoped/scopedCommandOperations.js +48 -0
- package/dist/adapters/scoped/scopedReads.d.ts +20 -0
- package/dist/adapters/scoped/scopedReads.js +174 -0
- package/dist/adapters/scoped/scopedTransaction.d.ts +89 -0
- package/dist/adapters/scoped/scopedTransaction.js +303 -0
- package/dist/adapters/scoped/sqliteScopeCatalog.d.ts +16 -0
- package/dist/adapters/scoped/sqliteScopeCatalog.js +241 -0
- package/dist/adapters/scoped/updateGuard.d.ts +3 -0
- package/dist/adapters/scoped/updateGuard.js +40 -0
- package/dist/adapters/serverSettings.d.ts +45 -0
- package/dist/adapters/serverSettings.js +46 -0
- package/dist/adapters/sqlite.d.ts +262 -0
- package/dist/adapters/sqlite.js +1434 -0
- package/dist/adapters/sqliteCostlyReads.d.ts +33 -0
- package/dist/adapters/sqliteCostlyReads.js +49 -0
- package/dist/adapters/sqliteDecimals.d.ts +22 -0
- package/dist/adapters/sqliteDecimals.js +57 -0
- package/dist/adapters/sqliteHandles.d.ts +43 -0
- package/dist/adapters/sqliteHandles.js +143 -0
- package/dist/adapters/sqliteStatementProcess.d.ts +29 -0
- package/dist/adapters/sqliteStatementProcess.js +131 -0
- package/dist/adapters/statementControl.d.ts +34 -0
- package/dist/adapters/statementControl.js +90 -0
- package/dist/adapters/storeHost.d.ts +130 -0
- package/dist/adapters/storeHost.js +13 -0
- package/dist/adapters/telemetry/drivers.d.ts +21 -0
- package/dist/adapters/telemetry/drivers.js +321 -0
- package/dist/adapters/telemetry/metrics.d.ts +63 -0
- package/dist/adapters/telemetry/metrics.js +122 -0
- package/dist/adapters/telemetry/otlp.d.ts +12 -0
- package/dist/adapters/telemetry/otlp.js +320 -0
- package/dist/adapters/telemetry/otlpEncode.d.ts +48 -0
- package/dist/adapters/telemetry/otlpEncode.js +366 -0
- package/dist/adapters/telemetry/otlpEnv.d.ts +1 -0
- package/dist/adapters/telemetry/otlpEnv.js +12 -0
- package/dist/adapters/telemetry/serverTiming.d.ts +83 -0
- package/dist/adapters/telemetry/serverTiming.js +503 -0
- package/dist/adapters/telemetry/start.d.ts +10 -0
- package/dist/adapters/telemetry/start.js +25 -0
- package/dist/adapters/telemetry/statement.d.ts +16 -0
- package/dist/adapters/telemetry/statement.js +134 -0
- package/dist/adapters/telemetry/trace.d.ts +127 -0
- package/dist/adapters/telemetry/trace.js +295 -0
- package/dist/adapters/writeAhead.d.ts +27 -0
- package/dist/adapters/writeAhead.js +46 -0
- package/dist/adapters/writeAttribution.d.ts +18 -0
- package/dist/adapters/writeAttribution.js +23 -0
- package/dist/adapters/writeCapture.d.ts +73 -0
- package/dist/adapters/writeCapture.js +20 -0
- package/dist/adapters/writeLanes.d.ts +94 -0
- package/dist/adapters/writeLanes.js +232 -0
- package/dist/engine.d.ts +15 -0
- package/dist/engine.js +13 -0
- package/dist/server/auth/credentials.d.ts +61 -0
- package/dist/server/auth/credentials.js +260 -0
- package/dist/server/cacheService.d.ts +50 -0
- package/dist/server/cacheService.js +110 -0
- package/dist/server/cli/args.d.ts +176 -0
- package/dist/server/cli/args.js +342 -0
- package/dist/server/cli/bin.d.ts +5 -0
- package/dist/server/cli/bin.js +66 -0
- package/dist/server/cli/browser.d.ts +15 -0
- package/dist/server/cli/browser.js +37 -0
- package/dist/server/cli/config.d.ts +50 -0
- package/dist/server/cli/config.js +206 -0
- package/dist/server/cli/startup.d.ts +36 -0
- package/dist/server/cli/startup.js +128 -0
- package/dist/server/cli/startupOptions.d.ts +63 -0
- package/dist/server/cli/startupOptions.js +143 -0
- package/dist/server/cli/subcommand.d.ts +28 -0
- package/dist/server/cli/subcommand.js +32 -0
- package/dist/server/cli/usage.d.ts +13 -0
- package/dist/server/cli/usage.js +31 -0
- package/dist/server/clientHttp.d.ts +184 -0
- package/dist/server/clientHttp.js +700 -0
- package/dist/server/clientSurface.d.ts +128 -0
- package/dist/server/clientSurface.js +182 -0
- package/dist/server/columnGrants.d.ts +103 -0
- package/dist/server/columnGrants.js +730 -0
- package/dist/server/compileCache.d.ts +1 -0
- package/dist/server/compileCache.js +30 -0
- package/dist/server/config/locations.d.ts +1 -0
- package/dist/server/config/locations.js +15 -0
- package/dist/server/configPaths.d.ts +7 -0
- package/dist/server/configPaths.js +34 -0
- package/dist/server/configSections.d.ts +64 -0
- package/dist/server/configSections.js +72 -0
- package/dist/server/connectionRedaction.d.ts +30 -0
- package/dist/server/connectionRedaction.js +77 -0
- package/dist/server/connections.d.ts +353 -0
- package/dist/server/connections.js +978 -0
- package/dist/server/constraints.d.ts +82 -0
- package/dist/server/constraints.js +169 -0
- package/dist/server/demo.d.ts +9 -0
- package/dist/server/demo.js +554 -0
- package/dist/server/devclient.d.ts +108 -0
- package/dist/server/devclient.js +361 -0
- package/dist/server/evidence.d.ts +55 -0
- package/dist/server/evidence.js +323 -0
- package/dist/server/hiddenColumns.d.ts +32 -0
- package/dist/server/hiddenColumns.js +238 -0
- package/dist/server/http/baselineHeaders.d.ts +24 -0
- package/dist/server/http/baselineHeaders.js +12 -0
- package/dist/server/http/captured.d.ts +35 -0
- package/dist/server/http/captured.js +73 -0
- package/dist/server/http/clock.d.ts +1 -0
- package/dist/server/http/clock.js +14 -0
- package/dist/server/http/connectionSource.d.ts +4 -0
- package/dist/server/http/connectionSource.js +48 -0
- package/dist/server/http/context.d.ts +189 -0
- package/dist/server/http/context.js +11 -0
- package/dist/server/http/crawlerText.d.ts +15 -0
- package/dist/server/http/crawlerText.js +32 -0
- package/dist/server/http/dataRoutes.d.ts +88 -0
- package/dist/server/http/dataRoutes.js +137 -0
- package/dist/server/http/door.d.ts +57 -0
- package/dist/server/http/door.js +39 -0
- package/dist/server/http/exportRoute.d.ts +15 -0
- package/dist/server/http/exportRoute.js +320 -0
- package/dist/server/http/firstPaint.d.ts +108 -0
- package/dist/server/http/firstPaint.js +262 -0
- package/dist/server/http/httpOperationRoutes.d.ts +11 -0
- package/dist/server/http/httpOperationRoutes.js +50 -0
- package/dist/server/http/pageReads.d.ts +20 -0
- package/dist/server/http/pageReads.js +205 -0
- package/dist/server/http/pageRoutes.d.ts +39 -0
- package/dist/server/http/pageRoutes.js +291 -0
- package/dist/server/http/probes.d.ts +22 -0
- package/dist/server/http/probes.js +27 -0
- package/dist/server/http/rateLimit.d.ts +131 -0
- package/dist/server/http/rateLimit.js +351 -0
- package/dist/server/http/readRoutes.d.ts +9 -0
- package/dist/server/http/readRoutes.js +131 -0
- package/dist/server/http/readRouting.d.ts +20 -0
- package/dist/server/http/readRouting.js +80 -0
- package/dist/server/http/recordCompose.d.ts +67 -0
- package/dist/server/http/recordCompose.js +167 -0
- package/dist/server/http/recordWrites.d.ts +89 -0
- package/dist/server/http/recordWrites.js +298 -0
- package/dist/server/http/refusalReport.d.ts +38 -0
- package/dist/server/http/refusalReport.js +63 -0
- package/dist/server/http/reply.d.ts +130 -0
- package/dist/server/http/reply.js +394 -0
- package/dist/server/http/requestOrigin.d.ts +11 -0
- package/dist/server/http/requestOrigin.js +8 -0
- package/dist/server/http/router.d.ts +45 -0
- package/dist/server/http/router.js +22 -0
- package/dist/server/http/serverCore.d.ts +68 -0
- package/dist/server/http/serverCore.js +177 -0
- package/dist/server/http/traceRequest.d.ts +30 -0
- package/dist/server/http/traceRequest.js +224 -0
- package/dist/server/http/trust.d.ts +261 -0
- package/dist/server/http/trust.js +472 -0
- package/dist/server/http/writeRefusal.d.ts +33 -0
- package/dist/server/http/writeRefusal.js +24 -0
- package/dist/server/httpConnection.d.ts +49 -0
- package/dist/server/httpConnection.js +170 -0
- package/dist/server/impact.d.ts +55 -0
- package/dist/server/impact.js +47 -0
- package/dist/server/journal.d.ts +134 -0
- package/dist/server/journal.js +398 -0
- package/dist/server/keysetReadHttp.d.ts +52 -0
- package/dist/server/keysetReadHttp.js +85 -0
- package/dist/server/layouts.d.ts +49 -0
- package/dist/server/layouts.js +192 -0
- package/dist/server/migrate/cli.d.ts +55 -0
- package/dist/server/migrate/cli.js +517 -0
- package/dist/server/migrate/database.d.ts +37 -0
- package/dist/server/migrate/database.js +247 -0
- package/dist/server/migrate/desired.d.ts +76 -0
- package/dist/server/migrate/desired.js +292 -0
- package/dist/server/migrate/files.d.ts +34 -0
- package/dist/server/migrate/files.js +141 -0
- package/dist/server/migrate/flyway.d.ts +7 -0
- package/dist/server/migrate/flyway.js +69 -0
- package/dist/server/migrate/history.d.ts +70 -0
- package/dist/server/migrate/history.js +211 -0
- package/dist/server/migrate/runner.d.ts +100 -0
- package/dist/server/migrate/runner.js +409 -0
- package/dist/server/migrate/snapshot.d.ts +30 -0
- package/dist/server/migrate/snapshot.js +239 -0
- package/dist/server/migrate/target.d.ts +33 -0
- package/dist/server/migrate/target.js +82 -0
- package/dist/server/openapiDraft.d.ts +25 -0
- package/dist/server/openapiDraft.js +171 -0
- package/dist/server/operations/diagnostics.d.ts +101 -0
- package/dist/server/operations/diagnostics.js +284 -0
- package/dist/server/operations/requestMetrics.d.ts +33 -0
- package/dist/server/operations/requestMetrics.js +94 -0
- package/dist/server/packageVersion.d.ts +1 -0
- package/dist/server/packageVersion.js +11 -0
- package/dist/server/poolConfig.d.ts +34 -0
- package/dist/server/poolConfig.js +114 -0
- package/dist/server/product.d.ts +20 -0
- package/dist/server/product.js +12 -0
- package/dist/server/recordHistoryOperations.d.ts +39 -0
- package/dist/server/recordHistoryOperations.js +43 -0
- package/dist/server/recordWriteOperations.d.ts +111 -0
- package/dist/server/recordWriteOperations.js +329 -0
- package/dist/server/resourceReadHttp.d.ts +81 -0
- package/dist/server/resourceReadHttp.js +606 -0
- package/dist/server/resourceReadOperations.d.ts +147 -0
- package/dist/server/resourceReadOperations.js +452 -0
- package/dist/server/scaffoldMachine.d.ts +54 -0
- package/dist/server/scaffoldMachine.js +184 -0
- package/dist/server/seed/cli.d.ts +20 -0
- package/dist/server/seed/cli.js +164 -0
- package/dist/server/seed/lexicon.d.ts +26 -0
- package/dist/server/seed/lexicon.js +585 -0
- package/dist/server/seed/seed.d.ts +70 -0
- package/dist/server/seed/seed.js +779 -0
- package/dist/server/seed/words.d.ts +21 -0
- package/dist/server/seed/words.js +164 -0
- package/dist/server/serverRequests.d.ts +6 -0
- package/dist/server/serverRequests.js +33 -0
- package/dist/server/serverTimeouts.d.ts +33 -0
- package/dist/server/serverTimeouts.js +32 -0
- package/dist/server/shapeonly.d.ts +32 -0
- package/dist/server/shapeonly.js +110 -0
- package/dist/server/startupWarnings.d.ts +32 -0
- package/dist/server/startupWarnings.js +92 -0
- package/dist/shared/addressParams.d.ts +28 -0
- package/dist/shared/addressParams.js +47 -0
- package/dist/shared/appCards.d.ts +123 -0
- package/dist/shared/appCards.js +385 -0
- package/dist/shared/appComponents.d.ts +177 -0
- package/dist/shared/appComponents.js +422 -0
- package/dist/shared/appDocuments.d.ts +43 -0
- package/dist/shared/appDocuments.js +131 -0
- package/dist/shared/appEmbeds.d.ts +21 -0
- package/dist/shared/appEmbeds.js +24 -0
- package/dist/shared/appIcons.d.ts +28 -0
- package/dist/shared/appIcons.js +223 -0
- package/dist/shared/appLinks.d.ts +17 -0
- package/dist/shared/appLinks.js +124 -0
- package/dist/shared/appListColumns.d.ts +3 -0
- package/dist/shared/appListColumns.js +66 -0
- package/dist/shared/appLocale.d.ts +36 -0
- package/dist/shared/appLocale.js +86 -0
- package/dist/shared/appMessages.d.ts +44 -0
- package/dist/shared/appMessages.js +78 -0
- package/dist/shared/appNoun.d.ts +21 -0
- package/dist/shared/appNoun.js +32 -0
- package/dist/shared/autoBucket.d.ts +98 -0
- package/dist/shared/autoBucket.js +305 -0
- package/dist/shared/autoValues.d.ts +25 -0
- package/dist/shared/autoValues.js +25 -0
- package/dist/shared/breakdown.d.ts +228 -0
- package/dist/shared/breakdown.js +557 -0
- package/dist/shared/breakdowntext.d.ts +41 -0
- package/dist/shared/breakdowntext.js +400 -0
- package/dist/shared/builtInThemes.d.ts +2 -0
- package/dist/shared/builtInThemes.js +771 -0
- package/dist/shared/chartSeparation.d.ts +11 -0
- package/dist/shared/chartSeparation.js +58 -0
- package/dist/shared/clauses.d.ts +22 -0
- package/dist/shared/clauses.js +97 -0
- package/dist/shared/columnCaption.d.ts +16 -0
- package/dist/shared/columnCaption.js +90 -0
- package/dist/shared/commandFieldPath.d.ts +2 -0
- package/dist/shared/commandFieldPath.js +7 -0
- package/dist/shared/commandWire.d.ts +26 -0
- package/dist/shared/commandWire.js +41 -0
- package/dist/shared/computed.d.ts +161 -0
- package/dist/shared/computed.js +378 -0
- package/dist/shared/computedParse.d.ts +13 -0
- package/dist/shared/computedParse.js +278 -0
- package/dist/shared/computedValue.d.ts +47 -0
- package/dist/shared/computedValue.js +191 -0
- package/dist/shared/connection.d.ts +30 -0
- package/dist/shared/connection.js +1 -0
- package/dist/shared/csv.d.ts +20 -0
- package/dist/shared/csv.js +63 -0
- package/dist/shared/dashLayout.d.ts +30 -0
- package/dist/shared/dashLayout.js +132 -0
- package/dist/shared/dashboardAsks.d.ts +93 -0
- package/dist/shared/dashboardAsks.js +129 -0
- package/dist/shared/dashboardTrend.d.ts +20 -0
- package/dist/shared/dashboardTrend.js +50 -0
- package/dist/shared/declaredReferences.d.ts +50 -0
- package/dist/shared/declaredReferences.js +202 -0
- package/dist/shared/definedFields.d.ts +63 -0
- package/dist/shared/definedFields.js +103 -0
- package/dist/shared/definedValues.d.ts +63 -0
- package/dist/shared/definedValues.js +184 -0
- package/dist/shared/displayDefaults.d.ts +135 -0
- package/dist/shared/displayDefaults.js +529 -0
- package/dist/shared/dueDate.d.ts +6 -0
- package/dist/shared/dueDate.js +6 -0
- package/dist/shared/duration.d.ts +4 -0
- package/dist/shared/duration.js +23 -0
- package/dist/shared/fileBounds.d.ts +9 -0
- package/dist/shared/fileBounds.js +9 -0
- package/dist/shared/filter.d.ts +217 -0
- package/dist/shared/filter.js +305 -0
- package/dist/shared/firstPaint.d.ts +24 -0
- package/dist/shared/firstPaint.js +33 -0
- package/dist/shared/form.d.ts +21 -0
- package/dist/shared/form.js +25 -0
- package/dist/shared/formValues.d.ts +104 -0
- package/dist/shared/formValues.js +352 -0
- package/dist/shared/funnel.d.ts +45 -0
- package/dist/shared/funnel.js +108 -0
- package/dist/shared/httpOperations.d.ts +48 -0
- package/dist/shared/httpOperations.js +9 -0
- package/dist/shared/iconGlyphs.d.ts +4 -0
- package/dist/shared/iconGlyphs.js +151 -0
- package/dist/shared/iconWeights.d.ts +3 -0
- package/dist/shared/iconWeights.js +162 -0
- package/dist/shared/imageWidths.d.ts +32 -0
- package/dist/shared/imageWidths.js +38 -0
- package/dist/shared/keysetPage.d.ts +62 -0
- package/dist/shared/keysetPage.js +159 -0
- package/dist/shared/like.d.ts +20 -0
- package/dist/shared/like.js +29 -0
- package/dist/shared/listEmpty.d.ts +12 -0
- package/dist/shared/listEmpty.js +36 -0
- package/dist/shared/listFilters.d.ts +28 -0
- package/dist/shared/listFilters.js +84 -0
- package/dist/shared/listPresentations.d.ts +199 -0
- package/dist/shared/listPresentations.js +7 -0
- package/dist/shared/listQuestion.d.ts +52 -0
- package/dist/shared/listQuestion.js +137 -0
- package/dist/shared/lookPalettes.d.ts +62 -0
- package/dist/shared/lookPalettes.js +306 -0
- package/dist/shared/maskQuoted.d.ts +24 -0
- package/dist/shared/maskQuoted.js +48 -0
- package/dist/shared/mentionLabel.d.ts +19 -0
- package/dist/shared/mentionLabel.js +38 -0
- package/dist/shared/mentionLookup.d.ts +17 -0
- package/dist/shared/mentionLookup.js +64 -0
- package/dist/shared/menuCounts.d.ts +16 -0
- package/dist/shared/menuCounts.js +74 -0
- package/dist/shared/model.d.ts +79 -0
- package/dist/shared/model.js +153 -0
- package/dist/shared/money.d.ts +44 -0
- package/dist/shared/money.js +81 -0
- package/dist/shared/moneyEntry.d.ts +7 -0
- package/dist/shared/moneyEntry.js +27 -0
- package/dist/shared/mount.d.ts +118 -0
- package/dist/shared/mount.js +248 -0
- package/dist/shared/niceTicks.d.ts +26 -0
- package/dist/shared/niceTicks.js +50 -0
- package/dist/shared/order.d.ts +59 -0
- package/dist/shared/order.js +133 -0
- package/dist/shared/page.d.ts +135 -0
- package/dist/shared/page.js +1187 -0
- package/dist/shared/pageAnatomy.d.ts +99 -0
- package/dist/shared/pageAnatomy.js +370 -0
- package/dist/shared/pageConfig.d.ts +25 -0
- package/dist/shared/pageConfig.js +1308 -0
- package/dist/shared/pageEmptyActions.d.ts +12 -0
- package/dist/shared/pageEmptyActions.js +20 -0
- package/dist/shared/pageLayouts.d.ts +72 -0
- package/dist/shared/pageLayouts.js +205 -0
- package/dist/shared/pageModel.d.ts +785 -0
- package/dist/shared/pageModel.js +121 -0
- package/dist/shared/pagePaths.d.ts +180 -0
- package/dist/shared/pagePaths.js +869 -0
- package/dist/shared/pagePlans.d.ts +52 -0
- package/dist/shared/pagePlans.js +108 -0
- package/dist/shared/pageRoutes.d.ts +9 -0
- package/dist/shared/pageRoutes.js +9 -0
- package/dist/shared/query.d.ts +166 -0
- package/dist/shared/query.js +1302 -0
- package/dist/shared/queryDates.d.ts +12 -0
- package/dist/shared/queryDates.js +101 -0
- package/dist/shared/queryOperands.d.ts +99 -0
- package/dist/shared/queryOperands.js +131 -0
- package/dist/shared/reads.d.ts +103 -0
- package/dist/shared/reads.js +154 -0
- package/dist/shared/recordLabel.d.ts +51 -0
- package/dist/shared/recordLabel.js +123 -0
- package/dist/shared/recordReadKeys.d.ts +30 -0
- package/dist/shared/recordReadKeys.js +51 -0
- package/dist/shared/recordReads.d.ts +268 -0
- package/dist/shared/recordReads.js +368 -0
- package/dist/shared/recordview.d.ts +198 -0
- package/dist/shared/recordview.js +356 -0
- package/dist/shared/referenceModel.d.ts +58 -0
- package/dist/shared/referenceModel.js +194 -0
- package/dist/shared/refusal.d.ts +64 -0
- package/dist/shared/refusal.js +144 -0
- package/dist/shared/relatedCreate.d.ts +30 -0
- package/dist/shared/relatedCreate.js +162 -0
- package/dist/shared/resourceHttp.d.ts +464 -0
- package/dist/shared/resourceHttp.js +1 -0
- package/dist/shared/richText.d.ts +85 -0
- package/dist/shared/richText.js +305 -0
- package/dist/shared/rollups.d.ts +143 -0
- package/dist/shared/rollups.js +64 -0
- package/dist/shared/rowScope.d.ts +72 -0
- package/dist/shared/rowScope.js +376 -0
- package/dist/shared/runtimeTables.d.ts +44 -0
- package/dist/shared/runtimeTables.js +79 -0
- package/dist/shared/schema.d.ts +523 -0
- package/dist/shared/schema.js +627 -0
- package/dist/shared/schematext.d.ts +38 -0
- package/dist/shared/schematext.js +101 -0
- package/dist/shared/scopeCatalog.d.ts +29 -0
- package/dist/shared/scopeCatalog.js +468 -0
- package/dist/shared/servedApp.d.ts +681 -0
- package/dist/shared/servedApp.js +45 -0
- package/dist/shared/sessionLease.d.ts +34 -0
- package/dist/shared/sessionLease.js +3 -0
- package/dist/shared/shape.d.ts +55 -0
- package/dist/shared/shape.js +168 -0
- package/dist/shared/slug.d.ts +1 -0
- package/dist/shared/slug.js +12 -0
- package/dist/shared/sortText.d.ts +14 -0
- package/dist/shared/sortText.js +26 -0
- package/dist/shared/sqlRelation.d.ts +4 -0
- package/dist/shared/sqlRelation.js +8 -0
- package/dist/shared/sqlsaved.d.ts +44 -0
- package/dist/shared/sqlsaved.js +63 -0
- package/dist/shared/stitchedPaths.d.ts +27 -0
- package/dist/shared/stitchedPaths.js +38 -0
- package/dist/shared/structuredFilter.d.ts +22 -0
- package/dist/shared/structuredFilter.js +1 -0
- package/dist/shared/subtitlePath.d.ts +20 -0
- package/dist/shared/subtitlePath.js +24 -0
- package/dist/shared/suggest.d.ts +18 -0
- package/dist/shared/suggest.js +59 -0
- package/dist/shared/tableSizing.d.ts +4 -0
- package/dist/shared/tableSizing.js +9 -0
- package/dist/shared/tagLists.d.ts +57 -0
- package/dist/shared/tagLists.js +34 -0
- package/dist/shared/textRules.d.ts +54 -0
- package/dist/shared/textRules.js +133 -0
- package/dist/shared/theme.d.ts +94 -0
- package/dist/shared/theme.js +800 -0
- package/dist/shared/themeColor.d.ts +34 -0
- package/dist/shared/themeColor.js +109 -0
- package/dist/shared/themeFaces.d.ts +30 -0
- package/dist/shared/themeFaces.js +42 -0
- package/dist/shared/themeInk.d.ts +20 -0
- package/dist/shared/themeInk.js +52 -0
- package/dist/shared/themeLooks.d.ts +9 -0
- package/dist/shared/themeLooks.js +572 -0
- package/dist/shared/themeParts.d.ts +26 -0
- package/dist/shared/themeParts.js +71 -0
- package/dist/shared/themePartsCheck.d.ts +21 -0
- package/dist/shared/themePartsCheck.js +91 -0
- package/dist/shared/themePresets.d.ts +85 -0
- package/dist/shared/themePresets.js +139 -0
- package/dist/shared/themeRecipeWords.d.ts +156 -0
- package/dist/shared/themeRecipeWords.js +156 -0
- package/dist/shared/themeRecipes.d.ts +213 -0
- package/dist/shared/themeRecipes.js +234 -0
- package/dist/shared/themeResolve.d.ts +55 -0
- package/dist/shared/themeResolve.js +52 -0
- package/dist/shared/themeTokens.d.ts +107 -0
- package/dist/shared/themeTokens.js +116 -0
- package/dist/shared/themeType.d.ts +38 -0
- package/dist/shared/themeType.js +205 -0
- package/dist/shared/unitWord.d.ts +4 -0
- package/dist/shared/unitWord.js +37 -0
- package/dist/shared/view.d.ts +195 -0
- package/dist/shared/view.js +987 -0
- package/dist/shared/viewLabels.d.ts +47 -0
- package/dist/shared/viewLabels.js +459 -0
- package/dist/shared/viewPaths.d.ts +248 -0
- package/dist/shared/viewPaths.js +294 -0
- package/dist/shared/viewtext.d.ts +57 -0
- package/dist/shared/viewtext.js +282 -0
- package/dist/shared/vocabulary.d.ts +71 -0
- package/dist/shared/vocabulary.js +249 -0
- package/dist/shared/weekStart.d.ts +7 -0
- package/dist/shared/weekStart.js +36 -0
- package/mark.svg +1 -0
- package/package.json +261 -4
- package/schema/model.d.ts +298 -0
- package/schema/theme.d.ts +587 -0
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A first page with its data in it (shared/firstPaint.ts says why).
|
|
3
|
+
*
|
|
4
|
+
* When the shell is served for an address, the server asks itself what the
|
|
5
|
+
* page will ask first — who is here, the runtime, the App, its schema, its
|
|
6
|
+
* pages and saved views, then the first room's own reads — and writes each
|
|
7
|
+
* answer into the page, in a `<script type="application/json">` block the
|
|
8
|
+
* client reads instead of fetching. Nothing here decides what anyone may
|
|
9
|
+
* read: every answer is the reply of the route a fetch would reach, asked
|
|
10
|
+
* through the whole dispatcher (`Loop`, handler.ts) with the page request's
|
|
11
|
+
* own headers — its cookie, its proxy identity, its host — so the gate, the
|
|
12
|
+
* App's grants, a row policy and a public visitor's grant all apply exactly
|
|
13
|
+
* as they would to the fetch. A read that route refuses, fails, or answers
|
|
14
|
+
* with anything but JSON is left out, and the client asks it itself and is
|
|
15
|
+
* told in its own words.
|
|
16
|
+
*
|
|
17
|
+
* Nothing is read from the request but its address: the path and the query
|
|
18
|
+
* parameters say which room; the headers only ride along to the routes, as
|
|
19
|
+
* a fetch's would. An answer that sets a cookie (a public form's claim) is
|
|
20
|
+
* never carried — a cookie is the client's to receive from its own request
|
|
21
|
+
* — nor one whose reply says something only its headers can
|
|
22
|
+
* (`x-mistri-search`).
|
|
23
|
+
*
|
|
24
|
+
* The block is bounded (MOST): answers are written in the order the page
|
|
25
|
+
* needs them, and one that would take the page past the bound is left for
|
|
26
|
+
* the client to ask. A page that carries any answer is one person's: it is
|
|
27
|
+
* sent `private` and never stored by a shared cache (clientHttp.ts).
|
|
28
|
+
*/
|
|
29
|
+
import { Readable } from 'node:stream';
|
|
30
|
+
import { itemKey, readKey } from '../../shared/firstPaint.js';
|
|
31
|
+
import { BREAKDOWN_BATCH } from '../resourceReadHttp.js';
|
|
32
|
+
import { COUNT_EACH_MAX } from '../../shared/reads.js';
|
|
33
|
+
/** The most JSON a page carries, in bytes before compression: a wide catalog's schema is a third of it. */
|
|
34
|
+
const MOST = 1024 * 1024;
|
|
35
|
+
/**
|
|
36
|
+
* How long a page waits for its answers, in ms. The page's head and scripts
|
|
37
|
+
* are already on their way (clientHttp.ts streams it), so this is only how
|
|
38
|
+
* long the block holds the end of the page: a read that takes longer is left
|
|
39
|
+
* for the client to ask, and a slow room costs its own read, never the page.
|
|
40
|
+
*/
|
|
41
|
+
let BUDGET = 1500;
|
|
42
|
+
/** For tests on a busy machine: how long a page waits for its answers. */
|
|
43
|
+
export function setFirstPaintBudget(ms) {
|
|
44
|
+
BUDGET = ms;
|
|
45
|
+
}
|
|
46
|
+
/* A page request's headers that describe the navigation rather than who is
|
|
47
|
+
asking: a fetch from the page carries its own. */
|
|
48
|
+
const NAVIGATION = new Set([
|
|
49
|
+
'if-none-match',
|
|
50
|
+
'if-modified-since',
|
|
51
|
+
'if-match',
|
|
52
|
+
'if-unmodified-since',
|
|
53
|
+
'if-range',
|
|
54
|
+
'range',
|
|
55
|
+
'accept',
|
|
56
|
+
'accept-encoding',
|
|
57
|
+
'content-type',
|
|
58
|
+
'content-length',
|
|
59
|
+
'transfer-encoding',
|
|
60
|
+
'origin',
|
|
61
|
+
'referer',
|
|
62
|
+
'upgrade-insecure-requests',
|
|
63
|
+
'purpose',
|
|
64
|
+
'sec-purpose',
|
|
65
|
+
'cache-control',
|
|
66
|
+
'pragma',
|
|
67
|
+
'expect',
|
|
68
|
+
'x-mistri-account',
|
|
69
|
+
]);
|
|
70
|
+
/**
|
|
71
|
+
* The request a fetch from this page would make: the page's own headers —
|
|
72
|
+
* its cookie, its proxy identity, its host — for the page's own origin, as
|
|
73
|
+
* `fetch` sends them (same-origin, JSON), and the body, if any. Enough of
|
|
74
|
+
* IncomingMessage for the gate, the auth store and the body reader.
|
|
75
|
+
*/
|
|
76
|
+
export function loopbackRequest(page, method, target, body) {
|
|
77
|
+
const payload = body === undefined ? undefined : Buffer.from(JSON.stringify(body), 'utf8');
|
|
78
|
+
const headers = {};
|
|
79
|
+
for (const [name, value] of Object.entries(page.headers)) {
|
|
80
|
+
if (value !== undefined && !NAVIGATION.has(name) && !name.startsWith('sec-fetch-'))
|
|
81
|
+
headers[name] = value;
|
|
82
|
+
}
|
|
83
|
+
Object.assign(headers, { 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty' }, payload ? { 'content-type': 'application/json', 'content-length': String(payload.length) } : {});
|
|
84
|
+
const stream = Readable.from(payload ? [payload] : []);
|
|
85
|
+
const socket = page.socket;
|
|
86
|
+
return Object.assign(stream, {
|
|
87
|
+
method,
|
|
88
|
+
url: target,
|
|
89
|
+
headers,
|
|
90
|
+
httpVersion: page.httpVersion,
|
|
91
|
+
httpVersionMajor: page.httpVersionMajor,
|
|
92
|
+
httpVersionMinor: page.httpVersionMinor,
|
|
93
|
+
complete: true,
|
|
94
|
+
aborted: false,
|
|
95
|
+
socket: {
|
|
96
|
+
remoteAddress: socket?.remoteAddress,
|
|
97
|
+
remotePort: socket?.remotePort,
|
|
98
|
+
remoteFamily: socket?.remoteFamily,
|
|
99
|
+
localAddress: socket?.localAddress,
|
|
100
|
+
localPort: socket?.localPort,
|
|
101
|
+
encrypted: socket?.encrypted,
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/** The answers a page carries, in the order it needs them. */
|
|
106
|
+
class Carried {
|
|
107
|
+
reads = [];
|
|
108
|
+
items = [];
|
|
109
|
+
read(method, target, body, answer) {
|
|
110
|
+
if (!answer)
|
|
111
|
+
return undefined;
|
|
112
|
+
if (!ok(answer))
|
|
113
|
+
return undefined;
|
|
114
|
+
// A placed form owns a fresh operation token. Never inline it even if a
|
|
115
|
+
// caller accidentally marks the response as carriable.
|
|
116
|
+
if (answer.body && typeof answer.body === 'object' && Object.hasOwn(answer.body, 'placement'))
|
|
117
|
+
return undefined;
|
|
118
|
+
if (answer.carriable)
|
|
119
|
+
this.reads.push([readKey(method, target, body), { body: answer.body, ...(answer.account ? { account: answer.account } : {}) }]);
|
|
120
|
+
return answer.body;
|
|
121
|
+
}
|
|
122
|
+
item(kind, owner, item, body, account) {
|
|
123
|
+
if (body && typeof body === 'object' && Object.hasOwn(body, 'placement'))
|
|
124
|
+
return;
|
|
125
|
+
this.items.push([itemKey(kind, owner, item), { body, ...(account ? { account } : {}) }]);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* The block's JSON, within the bound: whatever would pass it is left for the
|
|
129
|
+
* client to ask. Each answer is serialized once, and the block is joined from
|
|
130
|
+
* those pieces: it used to be serialized to be measured and again to be sent,
|
|
131
|
+
* which was the most expensive thing a page load did on a busy server.
|
|
132
|
+
*/
|
|
133
|
+
json(most) {
|
|
134
|
+
let size = 32;
|
|
135
|
+
const take = (entries) => {
|
|
136
|
+
const kept = new Map();
|
|
137
|
+
for (const [key, value] of entries) {
|
|
138
|
+
const name = JSON.stringify(key);
|
|
139
|
+
const body = JSON.stringify(value);
|
|
140
|
+
const cost = Buffer.byteLength(escapeData(name)) + Buffer.byteLength(escapeData(body)) + 2;
|
|
141
|
+
if (size + cost > most)
|
|
142
|
+
continue;
|
|
143
|
+
kept.set(name, body);
|
|
144
|
+
size += cost;
|
|
145
|
+
}
|
|
146
|
+
return kept;
|
|
147
|
+
};
|
|
148
|
+
const reads = take(this.reads);
|
|
149
|
+
const items = take(this.items);
|
|
150
|
+
if (!reads.size && !items.size)
|
|
151
|
+
return undefined;
|
|
152
|
+
const object = (kept) => `{${[...kept].map(([name, body]) => `${name}:${body}`).join(',')}}`;
|
|
153
|
+
return `{"reads":${object(reads)},"items":${object(items)}}`;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/** A reply the client would take as an answer: a success, in JSON, that says no error. */
|
|
157
|
+
function ok(answer) {
|
|
158
|
+
if (answer.status < 200 || answer.status >= 300 || answer.body === null || typeof answer.body !== 'object')
|
|
159
|
+
return false;
|
|
160
|
+
return !('error' in answer.body);
|
|
161
|
+
}
|
|
162
|
+
/* The most items each batch route takes at once (resourceReadHttp.ts BREAKDOWN_BATCH, shared/reads.ts COUNT_EACH_MAX). */
|
|
163
|
+
const BATCH_MOST = { '/api/breakdowns': BREAKDOWN_BATCH, '/api/counts': COUNT_EACH_MAX };
|
|
164
|
+
const chunks = (items, size) => {
|
|
165
|
+
const out = [];
|
|
166
|
+
for (let at = 0; at < items.length; at += size)
|
|
167
|
+
out.push(items.slice(at, at + size));
|
|
168
|
+
return out;
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* The answers for the page at `path` (its inside form, shared/mount.ts)
|
|
172
|
+
* with `search`: what boot.js asks, in its order, and then what the first
|
|
173
|
+
* room asks (`rooms`, an App's: firstPaintRooms.ts). Each round's requests
|
|
174
|
+
* are asked together.
|
|
175
|
+
*/
|
|
176
|
+
export async function firstPaint({ path, search, loop: asked, most = MOST, budget = BUDGET, rooms, }) {
|
|
177
|
+
const carried = new Carried();
|
|
178
|
+
/* Past the budget every answer still out is none: the client asks it. */
|
|
179
|
+
const controller = new AbortController();
|
|
180
|
+
const deadline = performance.now() + Math.max(0, budget);
|
|
181
|
+
let timer;
|
|
182
|
+
const late = new Promise((resolve) => {
|
|
183
|
+
timer = setTimeout(() => {
|
|
184
|
+
controller.abort();
|
|
185
|
+
resolve(undefined);
|
|
186
|
+
}, Math.max(0, budget));
|
|
187
|
+
});
|
|
188
|
+
const loop = (method, target, body) => {
|
|
189
|
+
// A completed earlier stage must not launch more work after the deadline.
|
|
190
|
+
if (controller.signal.aborted || performance.now() >= deadline)
|
|
191
|
+
return Promise.resolve(undefined);
|
|
192
|
+
const answer = asked(method, target, body, controller.signal).then((value) => (performance.now() < deadline ? value : undefined), () => undefined);
|
|
193
|
+
return Promise.race([answer, late]);
|
|
194
|
+
};
|
|
195
|
+
try {
|
|
196
|
+
return await answered(carried, path, search, loop, most, rooms);
|
|
197
|
+
}
|
|
198
|
+
finally {
|
|
199
|
+
clearTimeout(timer);
|
|
200
|
+
controller.abort();
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
async function answered(carried, path, search, loop, most, rooms) {
|
|
204
|
+
const ask = async (method, target, body) => carried.read(method, target, body, await loop(method, target, body));
|
|
205
|
+
const done = () => ({ json: carried.json(most) });
|
|
206
|
+
/* A page that is all its own reads is asked for before who-am-I (boot.js). */
|
|
207
|
+
const alone = rooms?.alone(path);
|
|
208
|
+
if (alone) {
|
|
209
|
+
for (const read of alone)
|
|
210
|
+
await ask(read.method, read.target, read.body);
|
|
211
|
+
return done();
|
|
212
|
+
}
|
|
213
|
+
const first = path.split('/').filter(Boolean)[0];
|
|
214
|
+
let requested = null;
|
|
215
|
+
try {
|
|
216
|
+
requested = first ? decodeURIComponent(first) : null;
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
return done();
|
|
220
|
+
}
|
|
221
|
+
const [me, runtime] = (await Promise.all([
|
|
222
|
+
ask('GET', requested ? `/api/whoami?${new URLSearchParams({ app: requested })}` : '/api/whoami'),
|
|
223
|
+
ask('GET', '/api/runtime'),
|
|
224
|
+
]));
|
|
225
|
+
if (!me || !runtime || !rooms)
|
|
226
|
+
return done();
|
|
227
|
+
const room = await rooms.room({ path, search, requested, me, runtime, ask });
|
|
228
|
+
if (!room)
|
|
229
|
+
return done();
|
|
230
|
+
const { app: selected, plan } = room;
|
|
231
|
+
await Promise.all([
|
|
232
|
+
...plan.reads.map((read) => ask(read.method, read.target, read.body)),
|
|
233
|
+
...plan.batches.flatMap((batch) => chunks(batch.items, BATCH_MOST[batch.path]).map(async (items) => {
|
|
234
|
+
const answer = await loop('POST', batch.path, { ...batch.body, items: items.map((item) => item.sent), app: selected });
|
|
235
|
+
// Individual batch items have no response headers for the client to check.
|
|
236
|
+
// Keep them only when the batch belongs to the identity boot established.
|
|
237
|
+
const account = typeof me.accountId === 'string' ? me.accountId : undefined;
|
|
238
|
+
const results = answer && ok(answer) && answer.carriable && answer.account === account
|
|
239
|
+
? answer.body.results
|
|
240
|
+
: undefined;
|
|
241
|
+
if (!Array.isArray(results) || results.length !== items.length)
|
|
242
|
+
return;
|
|
243
|
+
items.forEach((item, index) => {
|
|
244
|
+
const body = batch.unwrap ? batch.unwrap(results[index]) : results[index];
|
|
245
|
+
if (body !== undefined)
|
|
246
|
+
carried.item(item.kind ?? batch.kind, selected, item.key, body, answer?.account);
|
|
247
|
+
});
|
|
248
|
+
})),
|
|
249
|
+
]);
|
|
250
|
+
return done();
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* The data block, as the page carries it: JSON with every `<`, `>` and `&`
|
|
254
|
+
* written as its escape, and the two line separators JavaScript once took
|
|
255
|
+
* for line ends, so no value — a row's text is anybody's — can close the
|
|
256
|
+
* script element, open a comment inside it, or be read as markup.
|
|
257
|
+
*/
|
|
258
|
+
export function firstPaintBlock(id, json) {
|
|
259
|
+
return `<script type="application/json" id="${id}">${escapeData(json)}</script>`;
|
|
260
|
+
}
|
|
261
|
+
/** Count the same escaped UTF-8 bytes that will be sent, including hostile text. */
|
|
262
|
+
const escapeData = (json) => json.replace(/[<>&\u2028\u2029]/g, (c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, '0')}`);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PostContext } from './context.js';
|
|
2
|
+
/** Why this request cannot try an API, or undefined when it can. */
|
|
3
|
+
export declare function operationRefusal(request: {
|
|
4
|
+
appConfigured: boolean;
|
|
5
|
+
dialect: string;
|
|
6
|
+
rowsKept: boolean;
|
|
7
|
+
}): {
|
|
8
|
+
status: number;
|
|
9
|
+
error: string;
|
|
10
|
+
} | undefined;
|
|
11
|
+
export declare function httpOperationRoutes(post: PostContext): Promise<boolean>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { send } from './reply.js';
|
|
2
|
+
const DESCRIBE = '/api/http/operations';
|
|
3
|
+
const TRY = '/api/http/operation';
|
|
4
|
+
/** Why this request cannot try an API, or undefined when it can. */
|
|
5
|
+
export function operationRefusal(request) {
|
|
6
|
+
if (request.appConfigured)
|
|
7
|
+
return { status: 403, error: 'Trying an API is part of the database browser; an application does not offer it.' };
|
|
8
|
+
if (request.dialect !== 'http')
|
|
9
|
+
return { status: 400, error: 'This connection is a database, not an API, so it has no operations to try.' };
|
|
10
|
+
if (request.rowsKept)
|
|
11
|
+
return {
|
|
12
|
+
status: 403,
|
|
13
|
+
error: 'This connection keeps its rows in ("rows": false), and an API\'s answer is rows, so it is not tried here.',
|
|
14
|
+
};
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
const isParams = (value) => typeof value === 'object' && value !== null && !Array.isArray(value) && Object.values(value).every((each) => typeof each === 'string');
|
|
18
|
+
export async function httpOperationRoutes(post) {
|
|
19
|
+
const { res, path, body, adapter, schema, registry, connection, appConfigured } = post;
|
|
20
|
+
if (path !== DESCRIBE && path !== TRY)
|
|
21
|
+
return false;
|
|
22
|
+
const refused = operationRefusal({ appConfigured, dialect: schema.dialect, rowsKept: registry.configOf(connection)?.rows === false });
|
|
23
|
+
if (refused) {
|
|
24
|
+
send(res, refused.status, { error: refused.error });
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
const api = adapter;
|
|
28
|
+
if (typeof api.operations !== 'function' || typeof api.operation !== 'function') {
|
|
29
|
+
send(res, 501, { error: 'This connection cannot describe its API operations in this build.' });
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
const resource = String(body.resource ?? '');
|
|
33
|
+
// Refusals (an unknown resource, an undeclared parameter) and API failures throw, and server.ts maps them.
|
|
34
|
+
if (path === DESCRIBE) {
|
|
35
|
+
send(res, 200, api.operations.call(adapter, resource));
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
const kind = body.operation;
|
|
39
|
+
if (kind !== 'list' && kind !== 'item') {
|
|
40
|
+
send(res, 400, { error: 'An operation is "list" or "item".' });
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
const params = body.params ?? {};
|
|
44
|
+
if (!isParams(params)) {
|
|
45
|
+
send(res, 400, { error: "An operation's parameters are names and text values." });
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
send(res, 200, await api.operation.call(adapter, resource, kind, params));
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The GET routes both products serve that shape a page rather than read its
|
|
3
|
+
* rows: what could point at a table, its suggested page, the stored record
|
|
4
|
+
* layouts and saved pages, and a list's saved filters.
|
|
5
|
+
*
|
|
6
|
+
* What a product decides of them is `PageReadHooks`: the page a table opens
|
|
7
|
+
* on when nobody wrote one (an App's record anatomy, the database browser's
|
|
8
|
+
* counts and lists), and whether the App signs people in, whose filters are
|
|
9
|
+
* then each account's own.
|
|
10
|
+
*/
|
|
11
|
+
import { type PageDef } from '../../shared/page.js';
|
|
12
|
+
import { type DatabaseSchema } from '../../shared/schema.js';
|
|
13
|
+
import type { RequestContext, ResolvedSource } from './context.js';
|
|
14
|
+
export interface PageReadHooks {
|
|
15
|
+
/** A table's page when nobody wrote one. */
|
|
16
|
+
suggested(source: ResolvedSource, schema: DatabaseSchema, table: string): PageDef | null;
|
|
17
|
+
/** Whether the App this source belongs to signs people in. */
|
|
18
|
+
signsIn(ctx: RequestContext, source: ResolvedSource): boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare function pageReadRoutes(ctx: RequestContext, source: ResolvedSource, hooks: PageReadHooks): Promise<boolean>;
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The GET routes both products serve that shape a page rather than read its
|
|
3
|
+
* rows: what could point at a table, its suggested page, the stored record
|
|
4
|
+
* layouts and saved pages, and a list's saved filters.
|
|
5
|
+
*
|
|
6
|
+
* What a product decides of them is `PageReadHooks`: the page a table opens
|
|
7
|
+
* on when nobody wrote one (an App's record anatomy, the database browser's
|
|
8
|
+
* counts and lists), and whether the App signs people in, whose filters are
|
|
9
|
+
* then each account's own.
|
|
10
|
+
*/
|
|
11
|
+
import { defaultColumns, metricColumns, relationsTo, resolvePath } from '../../shared/page.js';
|
|
12
|
+
import { filtersPath, filtersSection, layoutsFor, pagesPath } from '../layouts.js';
|
|
13
|
+
import { referencesFrom, referencesTo, findTable, tableNamed } from '../../shared/schema.js';
|
|
14
|
+
import { send } from './reply.js';
|
|
15
|
+
export async function pageReadRoutes(ctx, source, hooks) {
|
|
16
|
+
const { res, url, path, configLayouts, identity, policyContext } = ctx;
|
|
17
|
+
const { schema, access, connectionId, publicScope } = source;
|
|
18
|
+
/**
|
|
19
|
+
* The page for a table nobody has written one for.
|
|
20
|
+
*
|
|
21
|
+
* Asked for by table rather than shipped with the list, because it is
|
|
22
|
+
* derived from the schema and the client has the schema — but the rule that
|
|
23
|
+
* derives it lives in shared/page.ts, and a second copy in the browser is
|
|
24
|
+
* the drift this codebase has paid for repeatedly.
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* What a page about this table could show.
|
|
28
|
+
*
|
|
29
|
+
* The path is the one field nobody guesses when writing a page by hand, so
|
|
30
|
+
* the builder does not ask for it — it asks the schema what points here and
|
|
31
|
+
* offers the answers with their paths already written. Computed on the
|
|
32
|
+
* server because the rules that resolve a path live in shared/page.ts, and
|
|
33
|
+
* a second copy of them in the browser is the drift this codebase has paid
|
|
34
|
+
* for in every feature that tried it.
|
|
35
|
+
*/
|
|
36
|
+
if (path === '/api/pages/relations') {
|
|
37
|
+
const table = String(url.searchParams.get('table') ?? '');
|
|
38
|
+
if (!findTable(schema, table)) {
|
|
39
|
+
send(res, 404, { error: `Unknown table "${table}"` });
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
const relations = relationsTo(schema, table);
|
|
43
|
+
const describe = (r) => ({
|
|
44
|
+
...r,
|
|
45
|
+
/* Numeric columns, for what a `sum` could be about. */
|
|
46
|
+
columns: metricColumns(schema, r.from),
|
|
47
|
+
defaults: defaultColumns(findTable(schema, r.from), r.path, resolvePath(schema, r.from, r.path).path),
|
|
48
|
+
all: findTable(schema, r.from).columns.map((c) => c.name),
|
|
49
|
+
});
|
|
50
|
+
/* What points at each record this table points at, one reference out.
|
|
51
|
+
|
|
52
|
+
This is how a work-order page offers "tickets at its site": the site is
|
|
53
|
+
not the root, but the root names it, and the schema knows what points
|
|
54
|
+
at a site. Direct relations only — the two-hop tail on a foreign
|
|
55
|
+
record is a menu nobody has asked for yet. */
|
|
56
|
+
const references = referencesFrom(schema, table)
|
|
57
|
+
.filter((fk) => fk.to.table !== table && findTable(schema, fk.to.table))
|
|
58
|
+
.map((fk) => {
|
|
59
|
+
const target = findTable(schema, fk.to.table);
|
|
60
|
+
return {
|
|
61
|
+
of: fk.from.columns.length === 1 ? fk.from.columns[0] : fk.name,
|
|
62
|
+
target: target.id,
|
|
63
|
+
targetName: target.name,
|
|
64
|
+
via: fk.from.columns.join(', '),
|
|
65
|
+
relations: relationsTo(schema, target.id, 1).map(describe),
|
|
66
|
+
};
|
|
67
|
+
})
|
|
68
|
+
.filter((ref) => ref.relations.length);
|
|
69
|
+
send(res, 200, {
|
|
70
|
+
...publicScope,
|
|
71
|
+
references,
|
|
72
|
+
relations: relations.map((r) => ({
|
|
73
|
+
...r,
|
|
74
|
+
/* Numeric columns, for what a `sum` could be about. */
|
|
75
|
+
columns: metricColumns(schema, r.from),
|
|
76
|
+
/* And what a list of this relation shows when nobody has said —
|
|
77
|
+
computed here, with the resolved path, because the rule that drops
|
|
78
|
+
the constant column is the same one the planner uses. A builder
|
|
79
|
+
that guessed at it would be a copy, and the copy would be the one
|
|
80
|
+
that forgot composite keys. */
|
|
81
|
+
defaults: defaultColumns(findTable(schema, r.from), r.path, resolvePath(schema, r.from, r.path).path),
|
|
82
|
+
/* Every column, so the picker can offer the ones the default leaves
|
|
83
|
+
out without a second request. */
|
|
84
|
+
all: findTable(schema, r.from).columns.map((c) => c.name),
|
|
85
|
+
})),
|
|
86
|
+
});
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
if (path === '/api/pages/suggested') {
|
|
90
|
+
const table = String(url.searchParams.get('table') ?? '');
|
|
91
|
+
/* Two different failures, and they had one message between them: a table
|
|
92
|
+
this connection does not have was reported as a table without a primary
|
|
93
|
+
key, which sends the reader looking for a key on something that is not
|
|
94
|
+
there. */
|
|
95
|
+
if (!findTable(schema, table)) {
|
|
96
|
+
send(res, 404, { error: `Unknown table "${table}"` });
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
/* An App's resource with no page of its own opens on the record anatomy
|
|
100
|
+
(pageAnatomy.ts), dressed in the App's words; the Workbench keeps its
|
|
101
|
+
page of counts and lists, the database as it is. */
|
|
102
|
+
const suggested = hooks.suggested(source, schema, table);
|
|
103
|
+
if (!suggested) {
|
|
104
|
+
send(res, 404, {
|
|
105
|
+
error: `No page can be built for "${table}" — it needs a primary key to identify a record by.`,
|
|
106
|
+
});
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
send(res, 200, { ...publicScope, page: suggested });
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Every stored record layout for this connection.
|
|
114
|
+
*
|
|
115
|
+
* Sent as a set rather than one at a time: the client needs to know which
|
|
116
|
+
* tables have a layout to render the "Layout" affordance honestly, and a
|
|
117
|
+
* request per table would be one round trip per row you walk to.
|
|
118
|
+
*/
|
|
119
|
+
if (path === '/api/layouts') {
|
|
120
|
+
if (access) {
|
|
121
|
+
send(res, 200, { ...publicScope, layouts: {} });
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
const saved = await layoutsFor(connectionId);
|
|
125
|
+
/* Config layouts fill in for tables nobody has laid out here, and never
|
|
126
|
+
over one somebody has. A committed layout is the default a team starts
|
|
127
|
+
from; the copy in this browser is what its reader chose afterwards, and
|
|
128
|
+
silently replacing that would make the config file feel like it was
|
|
129
|
+
fighting them. */
|
|
130
|
+
const merged = { ...saved };
|
|
131
|
+
for (const layout of configLayouts) {
|
|
132
|
+
if (layout.connection && layout.connection !== connectionId)
|
|
133
|
+
continue;
|
|
134
|
+
const table = tableNamed(schema, layout.table);
|
|
135
|
+
if (!table)
|
|
136
|
+
continue;
|
|
137
|
+
if (merged[table.id])
|
|
138
|
+
continue;
|
|
139
|
+
merged[table.id] = resolveConfigLayout(schema, table.id, layout);
|
|
140
|
+
}
|
|
141
|
+
send(res, 200, { ...publicScope, layouts: merged });
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
/** Every page saved for this connection, from the same kind of file. */
|
|
145
|
+
if (path === '/api/pages/saved') {
|
|
146
|
+
send(res, 200, { ...publicScope, pages: access ? {} : await layoutsFor(connectionId, pagesPath()) });
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* The saved list filters — an App list's saved views, list → [{name, query}]
|
|
151
|
+
* — and whose they are (`store`): the list the connection shares, the
|
|
152
|
+
* signed-in account's own, or none where nothing may be kept.
|
|
153
|
+
*/
|
|
154
|
+
if (path === '/api/filters') {
|
|
155
|
+
const account = typeof identity.id === 'string' ? identity.id : undefined;
|
|
156
|
+
const section = filtersSection(connectionId, { signIn: hooks.signsIn(ctx, source), account, rowPolicy: Boolean(policyContext) });
|
|
157
|
+
const store = section === null ? 'none' : section === connectionId ? 'shared' : 'account';
|
|
158
|
+
send(res, 200, { ...publicScope, store, filters: section === null ? {} : await layoutsFor(section, filtersPath()) });
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* A config layout, with its list sections keyed the way the client expects.
|
|
165
|
+
*
|
|
166
|
+
* A list is stored against the constraint name of the foreign key pointing
|
|
167
|
+
* back at the record — the right key, because a child can point at a parent
|
|
168
|
+
* twice and the column alone would not say which — and the wrong thing to ask
|
|
169
|
+
* anyone to type into a file. So a config may name the pair instead
|
|
170
|
+
* (`"from": "invoice", "whose": "customer_id"`, parsed to the internal
|
|
171
|
+
* `path`) and it is turned into the constraint here, where there is a schema
|
|
172
|
+
* to turn it with.
|
|
173
|
+
*
|
|
174
|
+
* A pair that names no real relationship keeps its section and gains an
|
|
175
|
+
* `error`, rather than disappearing: the same choice `/api/views` makes for a
|
|
176
|
+
* view that will not compile. A layout that silently lost a list is a layout
|
|
177
|
+
* nobody can debug.
|
|
178
|
+
*/
|
|
179
|
+
function resolveConfigLayout(schema, tableId, layout) {
|
|
180
|
+
const incoming = referencesTo(schema, tableId);
|
|
181
|
+
const sections = layout.sections.map((section) => {
|
|
182
|
+
if (section.kind !== 'list' || section.via)
|
|
183
|
+
return section;
|
|
184
|
+
const from = String(section.from ?? '');
|
|
185
|
+
const column = String(section.path ?? '');
|
|
186
|
+
const child = tableNamed(schema, from);
|
|
187
|
+
const match = child && incoming.find((fk) => fk.from.table === child.id && fk.from.columns.some((c) => c.toLowerCase() === column.toLowerCase()));
|
|
188
|
+
const { from: _from, path: _path, ...rest } = section;
|
|
189
|
+
if (!match) {
|
|
190
|
+
return {
|
|
191
|
+
...rest,
|
|
192
|
+
via: '',
|
|
193
|
+
error: `No foreign key from ${from}.${column} back to ${tableId}` + `${child ? '' : ` — and no table called "${from}"`}.`,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
return { ...rest, via: match.name };
|
|
197
|
+
});
|
|
198
|
+
return {
|
|
199
|
+
id: `config-${layout.table}`,
|
|
200
|
+
name: layout.name ?? 'From config',
|
|
201
|
+
base: tableId,
|
|
202
|
+
sections,
|
|
203
|
+
source: 'config',
|
|
204
|
+
};
|
|
205
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The POST routes both products serve that plan or keep rather than change
|
|
3
|
+
* data: a page's section plans, a record's incoming references, and a list's
|
|
4
|
+
* saved filters.
|
|
5
|
+
*
|
|
6
|
+
* What an App decides of them is `PageRules` (mistri: http/appAuthoring.ts):
|
|
7
|
+
* whether its reader's fields reach a page, the record a row policy admits,
|
|
8
|
+
* whether it signs people in (whose filters are each account's own), and its
|
|
9
|
+
* failures said by code. The database browser plans what its connection
|
|
10
|
+
* reads, and says a failure in the database's words.
|
|
11
|
+
*/
|
|
12
|
+
import type { Adapter } from '../../adapters/adapter.js';
|
|
13
|
+
import { type PageDef } from '../../shared/page.js';
|
|
14
|
+
import { type DatabaseSchema } from '../../shared/schema.js';
|
|
15
|
+
import type { PostContext } from './context.js';
|
|
16
|
+
/** An App's rules for the page routes. Absent, the database browser's. */
|
|
17
|
+
interface PageRules {
|
|
18
|
+
/** Whether the App this request names signs people in: its saved filters are then each account's own. */
|
|
19
|
+
signsIn(post: PostContext): boolean;
|
|
20
|
+
/** Whether a reader whose grant names fields reads every field `page` shows (appFieldProjection.ts). */
|
|
21
|
+
readsPage(schema: DatabaseSchema, page: PageDef): boolean;
|
|
22
|
+
/** The record a row policy admits, or a refusal (appPolicyHttp.ts). */
|
|
23
|
+
requireRecord(adapter: Adapter, schema: DatabaseSchema, table: string, key: Record<string, string | number>): Promise<unknown>;
|
|
24
|
+
/** The record's own row, read as a row policy admits it, with the columns asked. */
|
|
25
|
+
readRecord(adapter: Adapter, schema: DatabaseSchema, table: string, key: Record<string, string | number>, columns: string[]): Promise<Record<string, unknown>>;
|
|
26
|
+
/** A failure said by code, never in a driver's words (appErrors.ts). */
|
|
27
|
+
said(error: unknown): {
|
|
28
|
+
message: string;
|
|
29
|
+
code: string;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/** What a product decides of the page routes. */
|
|
33
|
+
export interface PageHooks {
|
|
34
|
+
/** A table's suggested page (`suggested:<table>`): the App's anatomy of it, or the schema's. */
|
|
35
|
+
suggested(post: PostContext, table: string): PageDef | null;
|
|
36
|
+
readonly rules?: PageRules;
|
|
37
|
+
}
|
|
38
|
+
export declare function pageRoutes(post: PostContext, hooks: PageHooks): Promise<boolean>;
|
|
39
|
+
export {};
|