@mistriwork/engine 0.0.0-stage → 1.0.0-rc.10
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 +64 -0
- package/dist/shared/keysetPage.js +161 -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,130 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
import type { ResourceHttpPath, ResourceHttpReply } from '../../shared/resourceHttp.js';
|
|
3
|
+
export declare const policyResponses: WeakMap<ServerResponse<IncomingMessage>, {
|
|
4
|
+
reply?: () => void;
|
|
5
|
+
}>;
|
|
6
|
+
export declare function sendResource<Path extends ResourceHttpPath>(res: ServerResponse, _route: Path, status: number, body: ResourceHttpReply<NoInfer<Path>>): void;
|
|
7
|
+
/**
|
|
8
|
+
* A write that waited out another transaction's lock (writeLanes.ts,
|
|
9
|
+
* `--lock-timeout`): its statement failed and its transaction rolled back,
|
|
10
|
+
* so nothing landed, and the same request will very likely go through in a
|
|
11
|
+
* moment. 503 with Retry-After, which is what an HTTP client retries; the
|
|
12
|
+
* body is a write refusal's, with its own code. `extra` is the route's own
|
|
13
|
+
* fields (`deleted: false`).
|
|
14
|
+
*/
|
|
15
|
+
export declare function sendRowLocked(res: ServerResponse, extra?: Record<string, unknown>): void;
|
|
16
|
+
/**
|
|
17
|
+
* A request the pool refused (poolMetrics.ts, PoolBusy): every connection was
|
|
18
|
+
* in use and the queue behind them was too long or had waited too long.
|
|
19
|
+
* Nothing was leased, so nothing ran: 503 with Retry-After, which is what an
|
|
20
|
+
* HTTP client retries, and for a write `outcome: 'not_applied'`, since it
|
|
21
|
+
* never began and the same request may be sent again. `extra` is the route's
|
|
22
|
+
* own fields (`deleted: false`); `write` is for a route that writes; `refusal` is the PoolBusy, which says how long to wait.
|
|
23
|
+
*/
|
|
24
|
+
export declare function sendBusy(res: ServerResponse, extra?: Record<string, unknown>, write?: boolean, refusal?: unknown): void;
|
|
25
|
+
/**
|
|
26
|
+
* Where a failure's trace can be read, while something serves traces (the App
|
|
27
|
+
* framework's dev observer, observe/mount.ts, sets it when it runs): a refusal
|
|
28
|
+
* then says where, beside its own words. None otherwise, which is every
|
|
29
|
+
* production start and every database browser start.
|
|
30
|
+
*/
|
|
31
|
+
declare let traceLink: ((traceId: string | undefined, req: IncomingMessage) => string | undefined) | undefined;
|
|
32
|
+
/** Set (or, with none, clear) where a failure's trace is read. */
|
|
33
|
+
export declare function linkTraces(link: typeof traceLink): void;
|
|
34
|
+
export declare function send(res: ServerResponse, status: number, body: unknown): void;
|
|
35
|
+
/**
|
|
36
|
+
* A GET whose answer changes only when the catalog, the App or the principal
|
|
37
|
+
* does — the schema, the App, its pages, the runtime — sent with a strong
|
|
38
|
+
* ETag so a browser that has it asks again with If-None-Match and is told
|
|
39
|
+
* 304 instead of being sent the same bytes: 349 KB of schema on a wide
|
|
40
|
+
* catalog, on every load.
|
|
41
|
+
*
|
|
42
|
+
* The answer is still computed, authorized and compared on every request —
|
|
43
|
+
* `no-cache` means the browser may keep it but never use it unasked — so a
|
|
44
|
+
* revoked grant or a reload is seen at once. The tag is a digest of the body
|
|
45
|
+
* together with `principal`, so one person's copy never validates for
|
|
46
|
+
* another even where the bytes agree, and `private` with `Vary: Cookie`
|
|
47
|
+
* keeps it out of any shared cache. A reply the request already marked
|
|
48
|
+
* `no-store` — every row-policy and tenant reply (handler.ts) — keeps that:
|
|
49
|
+
* it gets no tag and is not stored at all.
|
|
50
|
+
*/
|
|
51
|
+
export declare function sendRevalidated(res: ServerResponse, body: unknown, principal: string): void;
|
|
52
|
+
/**
|
|
53
|
+
* Brotli at quality 4 or gzip at level 6, whichever the request weights
|
|
54
|
+
* higher: 7–70 times fewer bytes than the JSON they carry, for a few
|
|
55
|
+
* milliseconds. Brotli wins a tie, being the smaller. `q=0` excludes an
|
|
56
|
+
* encoding, `*` weights the ones not named, and an `identity` the request
|
|
57
|
+
* names above both means it would rather have the bytes plain. Static assets
|
|
58
|
+
* are precompressed at build time (clientHttp.ts); a reply is compressed as
|
|
59
|
+
* it is sent.
|
|
60
|
+
*/
|
|
61
|
+
export declare function acceptedEncoding(res: ServerResponse): 'br' | 'gzip' | undefined;
|
|
62
|
+
/** Files obey the same settlement boundary as JSON. Even their headers wait:
|
|
63
|
+
* a failed policy context must not publish file metadata or a partial body. */
|
|
64
|
+
export declare function sendBytes(res: ServerResponse, status: number, bytes: Uint8Array, headers: Record<string, string | number>, head?: boolean): void;
|
|
65
|
+
/**
|
|
66
|
+
* Bytes that arrive as a stream (a file passed on from its bucket), sent as
|
|
67
|
+
* they come. A reply a policy holds until its transaction ends cannot start
|
|
68
|
+
* early, so there the stream is read whole first and sent like any other.
|
|
69
|
+
*/
|
|
70
|
+
export declare function sendStream(res: ServerResponse, status: number, body: ReadableStream<Uint8Array>, headers: Record<string, string | number>, head?: boolean): Promise<void>;
|
|
71
|
+
/**
|
|
72
|
+
* A written record as its reply shows it: a file's bytes as the `<n bytes>` label every read gives a blob (adapters/
|
|
73
|
+
* postgresValues.ts), never the bytes. An upload's reply otherwise echoed the file back as a JSON Buffer, three times
|
|
74
|
+
* its size. Anything that is not a record passes as it is.
|
|
75
|
+
*/
|
|
76
|
+
export declare function bytesLabelled<T>(record: T): T;
|
|
77
|
+
/** A file upload, the one body allowed past that: base64 of the largest file an App may accept, and room for the rest. */
|
|
78
|
+
export declare const FILE_UPLOAD_PATH = "/api/file/upload";
|
|
79
|
+
export declare const FILE_UPLOAD_BODY: number;
|
|
80
|
+
/**
|
|
81
|
+
* A tenant App's read of one file (tenant/tenantHttp.ts): the bytes come back
|
|
82
|
+
* as base64 in JSON, on the lease, like every other tenant read — a tenant
|
|
83
|
+
* page never addresses a file by URL, so no tenant's file is ever a link.
|
|
84
|
+
*/
|
|
85
|
+
export declare const FILE_READ_PATH = "/api/file/read";
|
|
86
|
+
/**
|
|
87
|
+
* The most bytes a tenant App's upload carries, whatever the resource's own
|
|
88
|
+
* cap: a tenant request is captured whole before it is judged (evidence.ts
|
|
89
|
+
* `captureTenantData`, 16 MiB of text), and base64 of this fits in it.
|
|
90
|
+
*/
|
|
91
|
+
export declare const TENANT_FILE_MOST: number;
|
|
92
|
+
export declare const TENANT_FILE_UPLOAD_BODY: number;
|
|
93
|
+
/** Only diagnostics emitted by the request service are public. Provider errors
|
|
94
|
+
* are stripped of ResourceReadError inside that service; failures elsewhere in
|
|
95
|
+
* auth/policy startup never pass through this conversion. */
|
|
96
|
+
export declare function httpRead<R>(work: () => Promise<R>): Promise<R>;
|
|
97
|
+
/**
|
|
98
|
+
* An error that already knows what status it deserves.
|
|
99
|
+
*
|
|
100
|
+
* Without this everything that was not a `PathError` fell out of `createApp`'s
|
|
101
|
+
* catch as a 500, so a body the caller sent malformed — or one they sent too
|
|
102
|
+
* much of — was reported to them as an outage on this end. The status is the
|
|
103
|
+
* only part of a failure most clients branch on; getting it wrong sends
|
|
104
|
+
* people to look at the wrong machine.
|
|
105
|
+
*/
|
|
106
|
+
export declare class HttpError extends Error {
|
|
107
|
+
readonly status: number;
|
|
108
|
+
constructor(status: number, message: string);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* A refusal that answers to both names.
|
|
112
|
+
*
|
|
113
|
+
* The view endpoints report their failures as `errors: [{message}]`, because
|
|
114
|
+
* a half-built view can be wrong in several places at once; every other
|
|
115
|
+
* endpoint reports `error`. A client that branches on the status and then
|
|
116
|
+
* reads `.error` showed a blank message on exactly the endpoints where the
|
|
117
|
+
* message mattered most. Both are sent — the list stays the shape the view
|
|
118
|
+
* editor reads, and `error` is the first of them.
|
|
119
|
+
*/
|
|
120
|
+
export declare function refuse(res: ServerResponse, status: number, messages: string[]): void;
|
|
121
|
+
/**
|
|
122
|
+
* A request body, at most `limit` bytes; undefined when it is longer. The rest of a longer body is still read, to be
|
|
123
|
+
* dropped: a reader that stopped at the limit left it on a keep-alive connection, where the server read the next
|
|
124
|
+
* request out of its leftovers, and that request hung or was reset (a live load test). So the 413 goes out on a
|
|
125
|
+
* connection that is clean. Not unboundedly: past OVERSIZE_DRAIN_MOST beyond the limit the connection is closed
|
|
126
|
+
* instead, which is what a client sending that much to a bounded route gets.
|
|
127
|
+
*/
|
|
128
|
+
export declare function readBounded(req: IncomingMessage, limit: number): Promise<Buffer | undefined>;
|
|
129
|
+
export declare function readJson(req: IncomingMessage, limit?: number): Promise<Record<string, unknown>>;
|
|
130
|
+
export {};
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a reply leaves: JSON with a status, a bounded body read, and the error
|
|
3
|
+
* that already knows its status. Nothing here knows what a request means.
|
|
4
|
+
*/
|
|
5
|
+
import { currentSpan } from '../../adapters/telemetry/trace.js';
|
|
6
|
+
import { FILE_MAX_BYTES_CEILING } from '../../shared/fileBounds.js';
|
|
7
|
+
import { createHash } from 'node:crypto';
|
|
8
|
+
import { brotliCompress, brotliCompressSync, constants as zlib, gzip, gzipSync } from 'node:zlib';
|
|
9
|
+
import { Readable } from 'node:stream';
|
|
10
|
+
import { pipeline } from 'node:stream/promises';
|
|
11
|
+
import { ResourceReadError } from '../resourceReadOperations.js';
|
|
12
|
+
import { ROW_LOCKED_MESSAGE, ROW_LOCKED_RETRY_AFTER_SECONDS } from '../../adapters/writeLanes.js';
|
|
13
|
+
import { POOL_BUSY_MESSAGE, poolBusyRetryAfterSeconds } from '../../adapters/poolMetrics.js';
|
|
14
|
+
// Policy callbacks may catch an operation failure, but the context still owns
|
|
15
|
+
// its outcome. Do not publish a partial success before that context settles.
|
|
16
|
+
export const policyResponses = new WeakMap();
|
|
17
|
+
export function sendResource(res, _route, status, body) {
|
|
18
|
+
send(res, status, body);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A write that waited out another transaction's lock (writeLanes.ts,
|
|
22
|
+
* `--lock-timeout`): its statement failed and its transaction rolled back,
|
|
23
|
+
* so nothing landed, and the same request will very likely go through in a
|
|
24
|
+
* moment. 503 with Retry-After, which is what an HTTP client retries; the
|
|
25
|
+
* body is a write refusal's, with its own code. `extra` is the route's own
|
|
26
|
+
* fields (`deleted: false`).
|
|
27
|
+
*/
|
|
28
|
+
export function sendRowLocked(res, extra = {}) {
|
|
29
|
+
currentSpan()?.event('lock timeout', { 'mistri.write.refusal': 'row_locked' });
|
|
30
|
+
if (!res.headersSent)
|
|
31
|
+
res.setHeader('retry-after', String(ROW_LOCKED_RETRY_AFTER_SECONDS));
|
|
32
|
+
send(res, 503, {
|
|
33
|
+
...extra,
|
|
34
|
+
error: ROW_LOCKED_MESSAGE,
|
|
35
|
+
code: 'row_locked',
|
|
36
|
+
errors: [{ code: 'row_locked', message: ROW_LOCKED_MESSAGE }],
|
|
37
|
+
outcome: 'not_applied',
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* A request the pool refused (poolMetrics.ts, PoolBusy): every connection was
|
|
42
|
+
* in use and the queue behind them was too long or had waited too long.
|
|
43
|
+
* Nothing was leased, so nothing ran: 503 with Retry-After, which is what an
|
|
44
|
+
* HTTP client retries, and for a write `outcome: 'not_applied'`, since it
|
|
45
|
+
* never began and the same request may be sent again. `extra` is the route's
|
|
46
|
+
* own fields (`deleted: false`); `write` is for a route that writes; `refusal` is the PoolBusy, which says how long to wait.
|
|
47
|
+
*/
|
|
48
|
+
export function sendBusy(res, extra = {}, write = false, refusal) {
|
|
49
|
+
currentSpan()?.event('pool busy', { 'mistri.refusal': 'server_busy' });
|
|
50
|
+
if (!res.headersSent)
|
|
51
|
+
res.setHeader('retry-after', String(poolBusyRetryAfterSeconds(refusal)));
|
|
52
|
+
send(res, 503, {
|
|
53
|
+
...extra,
|
|
54
|
+
error: POOL_BUSY_MESSAGE,
|
|
55
|
+
code: 'server_busy',
|
|
56
|
+
...(write ? { errors: [{ code: 'server_busy', message: POOL_BUSY_MESSAGE }], outcome: 'not_applied' } : {}),
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Where a failure's trace can be read, while something serves traces (the App
|
|
61
|
+
* framework's dev observer, observe/mount.ts, sets it when it runs): a refusal
|
|
62
|
+
* then says where, beside its own words. None otherwise, which is every
|
|
63
|
+
* production start and every database browser start.
|
|
64
|
+
*/
|
|
65
|
+
let traceLink;
|
|
66
|
+
/** Set (or, with none, clear) where a failure's trace is read. */
|
|
67
|
+
export function linkTraces(link) {
|
|
68
|
+
traceLink = link;
|
|
69
|
+
}
|
|
70
|
+
export function send(res, status, body) {
|
|
71
|
+
const deferred = policyResponses.get(res);
|
|
72
|
+
if (deferred) {
|
|
73
|
+
deferred.reply = () => send(res, status, body);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (res.destroyed || res.writableEnded)
|
|
77
|
+
return;
|
|
78
|
+
/* While the dev observer runs, a failure says where its trace is: the
|
|
79
|
+
"Open in observer" link beside the refusal (observe/mount.ts). */
|
|
80
|
+
const observe = traceLink && status >= 400 && body && typeof body === 'object' && !Array.isArray(body)
|
|
81
|
+
? traceLink(currentSpan()?.traceId, res.req)
|
|
82
|
+
: undefined;
|
|
83
|
+
writeJson(res, status, Buffer.from(JSON.stringify(observe ? { ...body, observe } : body)));
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* A GET whose answer changes only when the catalog, the App or the principal
|
|
87
|
+
* does — the schema, the App, its pages, the runtime — sent with a strong
|
|
88
|
+
* ETag so a browser that has it asks again with If-None-Match and is told
|
|
89
|
+
* 304 instead of being sent the same bytes: 349 KB of schema on a wide
|
|
90
|
+
* catalog, on every load.
|
|
91
|
+
*
|
|
92
|
+
* The answer is still computed, authorized and compared on every request —
|
|
93
|
+
* `no-cache` means the browser may keep it but never use it unasked — so a
|
|
94
|
+
* revoked grant or a reload is seen at once. The tag is a digest of the body
|
|
95
|
+
* together with `principal`, so one person's copy never validates for
|
|
96
|
+
* another even where the bytes agree, and `private` with `Vary: Cookie`
|
|
97
|
+
* keeps it out of any shared cache. A reply the request already marked
|
|
98
|
+
* `no-store` — every row-policy and tenant reply (handler.ts) — keeps that:
|
|
99
|
+
* it gets no tag and is not stored at all.
|
|
100
|
+
*/
|
|
101
|
+
export function sendRevalidated(res, body, principal) {
|
|
102
|
+
const deferred = policyResponses.get(res);
|
|
103
|
+
if (deferred) {
|
|
104
|
+
deferred.reply = () => sendRevalidated(res, body, principal);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (res.destroyed || res.writableEnded)
|
|
108
|
+
return;
|
|
109
|
+
const json = Buffer.from(JSON.stringify(body));
|
|
110
|
+
if (String(res.getHeader('cache-control') ?? '').includes('no-store')) {
|
|
111
|
+
writeJson(res, 200, json);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const tag = `"${createHash('sha256').update(principal).update('\0').update(json).digest('base64url').slice(0, 32)}"`;
|
|
115
|
+
const headers = { 'cache-control': 'private, no-cache', etag: tag };
|
|
116
|
+
addVary(res, 'Cookie');
|
|
117
|
+
const asked = res.req?.headers['if-none-match'];
|
|
118
|
+
if (typeof asked === 'string' && asked.split(',').some((one) => one.trim().replace(/^W\//, '') === tag)) {
|
|
119
|
+
addVary(res, 'Accept-Encoding');
|
|
120
|
+
res.writeHead(304, headers);
|
|
121
|
+
res.end();
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
writeJson(res, 200, json, headers, tag);
|
|
125
|
+
}
|
|
126
|
+
/** JSON this size or larger is compressed when the request accepts it. Below
|
|
127
|
+
* it the header costs more than the saving. */
|
|
128
|
+
const COMPRESS_FROM = 1024;
|
|
129
|
+
/** Past this a body is compressed off the event loop: brotli at quality 4 is
|
|
130
|
+
* about 4 ms for a wide schema's 349 KB, and a 100,000-row read is far more;
|
|
131
|
+
* 32 KB is roughly a millisecond, the most a request should hold the loop for. */
|
|
132
|
+
const COMPRESS_INLINE_BELOW = 32 * 1024;
|
|
133
|
+
/** Compressed metadata, by tag and encoding: a revisit that is not a 304 (a
|
|
134
|
+
* new tab, a cleared cache) is sent the bytes compressed the first time. */
|
|
135
|
+
const compressed = new Map();
|
|
136
|
+
const COMPRESSED_KEPT = 64;
|
|
137
|
+
/**
|
|
138
|
+
* Brotli at quality 4 or gzip at level 6, whichever the request weights
|
|
139
|
+
* higher: 7–70 times fewer bytes than the JSON they carry, for a few
|
|
140
|
+
* milliseconds. Brotli wins a tie, being the smaller. `q=0` excludes an
|
|
141
|
+
* encoding, `*` weights the ones not named, and an `identity` the request
|
|
142
|
+
* names above both means it would rather have the bytes plain. Static assets
|
|
143
|
+
* are precompressed at build time (clientHttp.ts); a reply is compressed as
|
|
144
|
+
* it is sent.
|
|
145
|
+
*/
|
|
146
|
+
export function acceptedEncoding(res) {
|
|
147
|
+
const weights = new Map();
|
|
148
|
+
for (const part of String(res.req?.headers['accept-encoding'] ?? '')
|
|
149
|
+
.toLowerCase()
|
|
150
|
+
.split(',')) {
|
|
151
|
+
const [token, ...params] = part.trim().split(';');
|
|
152
|
+
const name = token.trim();
|
|
153
|
+
if (!name)
|
|
154
|
+
continue;
|
|
155
|
+
const q = params.map((p) => p.trim()).find((p) => p.startsWith('q='));
|
|
156
|
+
const weight = q ? Number(q.slice(2)) : 1;
|
|
157
|
+
weights.set(name, Number.isFinite(weight) ? Math.min(weight, 1) : 0);
|
|
158
|
+
}
|
|
159
|
+
const weightOf = (name) => weights.get(name) ?? weights.get('*') ?? 0;
|
|
160
|
+
const br = weightOf('br');
|
|
161
|
+
const gzip = weightOf('gzip');
|
|
162
|
+
const best = br >= gzip ? 'br' : 'gzip';
|
|
163
|
+
const quality = Math.max(br, gzip);
|
|
164
|
+
if (quality <= 0 || (weights.get('identity') ?? 0) > quality)
|
|
165
|
+
return undefined;
|
|
166
|
+
return best;
|
|
167
|
+
}
|
|
168
|
+
function addVary(res, name) {
|
|
169
|
+
const current = String(res.getHeader('vary') ?? '');
|
|
170
|
+
const names = current
|
|
171
|
+
.split(',')
|
|
172
|
+
.map((part) => part.trim())
|
|
173
|
+
.filter(Boolean);
|
|
174
|
+
if (!names.some((part) => part.toLowerCase() === name.toLowerCase()))
|
|
175
|
+
res.setHeader('vary', [...names, name].join(', '));
|
|
176
|
+
}
|
|
177
|
+
function writeJson(res, status, json, extra = {}, tag) {
|
|
178
|
+
const headers = {
|
|
179
|
+
'content-type': 'application/json; charset=utf-8',
|
|
180
|
+
'x-content-type-options': 'nosniff',
|
|
181
|
+
...extra,
|
|
182
|
+
};
|
|
183
|
+
const encoding = json.length >= COMPRESS_FROM ? acceptedEncoding(res) : undefined;
|
|
184
|
+
if (json.length >= COMPRESS_FROM)
|
|
185
|
+
addVary(res, 'Accept-Encoding');
|
|
186
|
+
const finish = (bytes, applied) => {
|
|
187
|
+
if (res.destroyed || res.writableEnded)
|
|
188
|
+
return;
|
|
189
|
+
res.writeHead(status, { ...headers, ...(applied ? { 'content-encoding': applied } : {}), 'content-length': bytes.length });
|
|
190
|
+
res.end(bytes);
|
|
191
|
+
};
|
|
192
|
+
if (!encoding)
|
|
193
|
+
return finish(json);
|
|
194
|
+
const key = tag && `${tag}:${encoding}`;
|
|
195
|
+
const kept = key ? compressed.get(key) : undefined;
|
|
196
|
+
if (kept)
|
|
197
|
+
return finish(kept, encoding);
|
|
198
|
+
const keep = (bytes) => {
|
|
199
|
+
if (!key)
|
|
200
|
+
return;
|
|
201
|
+
if (compressed.size >= COMPRESSED_KEPT)
|
|
202
|
+
compressed.delete(compressed.keys().next().value);
|
|
203
|
+
compressed.set(key, bytes);
|
|
204
|
+
};
|
|
205
|
+
const options = encoding === 'br'
|
|
206
|
+
? {
|
|
207
|
+
params: {
|
|
208
|
+
[zlib.BROTLI_PARAM_QUALITY]: 4,
|
|
209
|
+
[zlib.BROTLI_PARAM_SIZE_HINT]: json.length,
|
|
210
|
+
[zlib.BROTLI_PARAM_MODE]: zlib.BROTLI_MODE_TEXT,
|
|
211
|
+
},
|
|
212
|
+
}
|
|
213
|
+
: { level: 6 };
|
|
214
|
+
if (json.length < COMPRESS_INLINE_BELOW) {
|
|
215
|
+
const bytes = encoding === 'br' ? brotliCompressSync(json, options) : gzipSync(json, options);
|
|
216
|
+
keep(bytes);
|
|
217
|
+
return finish(bytes, encoding);
|
|
218
|
+
}
|
|
219
|
+
const done = (error, bytes) => {
|
|
220
|
+
if (error)
|
|
221
|
+
return finish(json);
|
|
222
|
+
keep(bytes);
|
|
223
|
+
finish(bytes, encoding);
|
|
224
|
+
};
|
|
225
|
+
if (encoding === 'br')
|
|
226
|
+
brotliCompress(json, options, done);
|
|
227
|
+
else
|
|
228
|
+
gzip(json, options, done);
|
|
229
|
+
}
|
|
230
|
+
/** Files obey the same settlement boundary as JSON. Even their headers wait:
|
|
231
|
+
* a failed policy context must not publish file metadata or a partial body. */
|
|
232
|
+
export function sendBytes(res, status, bytes, headers, head = false) {
|
|
233
|
+
const deferred = policyResponses.get(res);
|
|
234
|
+
if (deferred) {
|
|
235
|
+
const body = Buffer.from(bytes);
|
|
236
|
+
const capturedHeaders = { ...headers };
|
|
237
|
+
deferred.reply = () => sendBytes(res, status, body, capturedHeaders, head);
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
if (res.destroyed || res.writableEnded)
|
|
241
|
+
return;
|
|
242
|
+
res.writeHead(status, headers);
|
|
243
|
+
res.end(head ? undefined : bytes);
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Bytes that arrive as a stream (a file passed on from its bucket), sent as
|
|
247
|
+
* they come. A reply a policy holds until its transaction ends cannot start
|
|
248
|
+
* early, so there the stream is read whole first and sent like any other.
|
|
249
|
+
*/
|
|
250
|
+
export async function sendStream(res, status, body, headers, head = false) {
|
|
251
|
+
if (head || res.destroyed || res.writableEnded) {
|
|
252
|
+
await body.cancel().catch(() => { });
|
|
253
|
+
sendBytes(res, status, new Uint8Array(0), headers, true);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
if (policyResponses.get(res)) {
|
|
257
|
+
sendBytes(res, status, new Uint8Array(await new Response(body).arrayBuffer()), headers);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
res.writeHead(status, headers);
|
|
261
|
+
await pipeline(Readable.fromWeb(body), res).catch(() => res.destroy());
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* A written record as its reply shows it: a file's bytes as the `<n bytes>` label every read gives a blob (adapters/
|
|
265
|
+
* postgresValues.ts), never the bytes. An upload's reply otherwise echoed the file back as a JSON Buffer, three times
|
|
266
|
+
* its size. Anything that is not a record passes as it is.
|
|
267
|
+
*/
|
|
268
|
+
export function bytesLabelled(record) {
|
|
269
|
+
if (!record || typeof record !== 'object' || Array.isArray(record) || record instanceof Uint8Array)
|
|
270
|
+
return record;
|
|
271
|
+
const entries = Object.entries(record);
|
|
272
|
+
if (!entries.some(([, value]) => value instanceof Uint8Array))
|
|
273
|
+
return record;
|
|
274
|
+
return Object.fromEntries(entries.map(([column, value]) => [column, value instanceof Uint8Array ? `<${value.byteLength} bytes>` : value]));
|
|
275
|
+
}
|
|
276
|
+
/** Bounded, because an unbounded request body is a denial of service. */
|
|
277
|
+
const MAX_BODY = 1024 * 256;
|
|
278
|
+
/** A file upload, the one body allowed past that: base64 of the largest file an App may accept, and room for the rest. */
|
|
279
|
+
export const FILE_UPLOAD_PATH = '/api/file/upload';
|
|
280
|
+
export const FILE_UPLOAD_BODY = Math.ceil(FILE_MAX_BYTES_CEILING / 3) * 4 + 64 * 1024;
|
|
281
|
+
/**
|
|
282
|
+
* A tenant App's read of one file (tenant/tenantHttp.ts): the bytes come back
|
|
283
|
+
* as base64 in JSON, on the lease, like every other tenant read — a tenant
|
|
284
|
+
* page never addresses a file by URL, so no tenant's file is ever a link.
|
|
285
|
+
*/
|
|
286
|
+
export const FILE_READ_PATH = '/api/file/read';
|
|
287
|
+
/**
|
|
288
|
+
* The most bytes a tenant App's upload carries, whatever the resource's own
|
|
289
|
+
* cap: a tenant request is captured whole before it is judged (evidence.ts
|
|
290
|
+
* `captureTenantData`, 16 MiB of text), and base64 of this fits in it.
|
|
291
|
+
*/
|
|
292
|
+
export const TENANT_FILE_MOST = 10 * 1024 * 1024;
|
|
293
|
+
export const TENANT_FILE_UPLOAD_BODY = Math.ceil(TENANT_FILE_MOST / 3) * 4 + 64 * 1024;
|
|
294
|
+
/** Only diagnostics emitted by the request service are public. Provider errors
|
|
295
|
+
* are stripped of ResourceReadError inside that service; failures elsewhere in
|
|
296
|
+
* auth/policy startup never pass through this conversion. */
|
|
297
|
+
export async function httpRead(work) {
|
|
298
|
+
try {
|
|
299
|
+
return await work();
|
|
300
|
+
}
|
|
301
|
+
catch (error) {
|
|
302
|
+
if (error instanceof ResourceReadError)
|
|
303
|
+
throw new HttpError(error.status, error.message);
|
|
304
|
+
throw error;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* An error that already knows what status it deserves.
|
|
309
|
+
*
|
|
310
|
+
* Without this everything that was not a `PathError` fell out of `createApp`'s
|
|
311
|
+
* catch as a 500, so a body the caller sent malformed — or one they sent too
|
|
312
|
+
* much of — was reported to them as an outage on this end. The status is the
|
|
313
|
+
* only part of a failure most clients branch on; getting it wrong sends
|
|
314
|
+
* people to look at the wrong machine.
|
|
315
|
+
*/
|
|
316
|
+
export class HttpError extends Error {
|
|
317
|
+
status;
|
|
318
|
+
constructor(status, message) {
|
|
319
|
+
super(message);
|
|
320
|
+
this.status = status;
|
|
321
|
+
this.name = 'HttpError';
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* A refusal that answers to both names.
|
|
326
|
+
*
|
|
327
|
+
* The view endpoints report their failures as `errors: [{message}]`, because
|
|
328
|
+
* a half-built view can be wrong in several places at once; every other
|
|
329
|
+
* endpoint reports `error`. A client that branches on the status and then
|
|
330
|
+
* reads `.error` showed a blank message on exactly the endpoints where the
|
|
331
|
+
* message mattered most. Both are sent — the list stays the shape the view
|
|
332
|
+
* editor reads, and `error` is the first of them.
|
|
333
|
+
*/
|
|
334
|
+
export function refuse(res, status, messages) {
|
|
335
|
+
send(res, status, {
|
|
336
|
+
error: messages[0],
|
|
337
|
+
errors: messages.map((message) => ({ message })),
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
/** How much of a body past its limit is still read off the wire, to be dropped (readBounded). */
|
|
341
|
+
const OVERSIZE_DRAIN_MOST = 16 * 1024 * 1024;
|
|
342
|
+
/**
|
|
343
|
+
* A request body, at most `limit` bytes; undefined when it is longer. The rest of a longer body is still read, to be
|
|
344
|
+
* dropped: a reader that stopped at the limit left it on a keep-alive connection, where the server read the next
|
|
345
|
+
* request out of its leftovers, and that request hung or was reset (a live load test). So the 413 goes out on a
|
|
346
|
+
* connection that is clean. Not unboundedly: past OVERSIZE_DRAIN_MOST beyond the limit the connection is closed
|
|
347
|
+
* instead, which is what a client sending that much to a bounded route gets.
|
|
348
|
+
*/
|
|
349
|
+
export async function readBounded(req, limit) {
|
|
350
|
+
const chunks = [];
|
|
351
|
+
let size = 0;
|
|
352
|
+
for await (const part of req) {
|
|
353
|
+
const chunk = Buffer.isBuffer(part) ? part : Buffer.from(part);
|
|
354
|
+
size += chunk.length;
|
|
355
|
+
if (size <= limit)
|
|
356
|
+
chunks.push(chunk);
|
|
357
|
+
else if (size > limit + OVERSIZE_DRAIN_MOST) {
|
|
358
|
+
req.socket?.destroy();
|
|
359
|
+
return undefined;
|
|
360
|
+
}
|
|
361
|
+
else
|
|
362
|
+
chunks.length = 0;
|
|
363
|
+
}
|
|
364
|
+
return size > limit ? undefined : Buffer.concat(chunks);
|
|
365
|
+
}
|
|
366
|
+
export async function readJson(req, limit = MAX_BODY) {
|
|
367
|
+
const read = await readBounded(req, limit);
|
|
368
|
+
if (!read)
|
|
369
|
+
throw new HttpError(413, 'Request body too large.');
|
|
370
|
+
if (!read.length)
|
|
371
|
+
return {};
|
|
372
|
+
try {
|
|
373
|
+
/* JSON.parse itself preserves literal keys safely. Some downstream maps
|
|
374
|
+
still use keyed assignment on ordinary objects, though, so admitting
|
|
375
|
+
these names would not preserve their values end to end. Refuse the
|
|
376
|
+
whole request rather than silently deleting an intended write. Literal
|
|
377
|
+
column support needs those consumers hardened before this can relax. */
|
|
378
|
+
const body = JSON.parse(read.toString('utf8'), (key, value) => {
|
|
379
|
+
if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
|
|
380
|
+
throw new HttpError(400, `Request body property "${key}" is not supported.`);
|
|
381
|
+
}
|
|
382
|
+
return value;
|
|
383
|
+
});
|
|
384
|
+
if (body === null || typeof body !== 'object' || Array.isArray(body)) {
|
|
385
|
+
throw new HttpError(400, 'Request body must be a JSON object.');
|
|
386
|
+
}
|
|
387
|
+
return body;
|
|
388
|
+
}
|
|
389
|
+
catch (error) {
|
|
390
|
+
if (error instanceof HttpError)
|
|
391
|
+
throw error;
|
|
392
|
+
throw new HttpError(400, 'Request body was not valid JSON.');
|
|
393
|
+
}
|
|
394
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The origin a request was made to, as the browser that made it wrote it:
|
|
3
|
+
* what a sitemap's `<loc>` and a link preview's `og:url` must be, since both
|
|
4
|
+
* are read away from the page and need an absolute address. The Host header
|
|
5
|
+
* has already been held to the server's allowed hosts by the gate
|
|
6
|
+
* (trust.ts); the scheme is https when the request arrived over https
|
|
7
|
+
* (trust.ts `arrivedOverHttps`), and http otherwise.
|
|
8
|
+
*/
|
|
9
|
+
import type { IncomingMessage } from 'node:http';
|
|
10
|
+
import { type Bound } from './trust.js';
|
|
11
|
+
export declare function requestOrigin(req: Pick<IncomingMessage, 'headers' | 'socket'>, bound: Pick<Bound, 'trustedProxies'>): string | undefined;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { arrivedOverHttps } from './trust.js';
|
|
2
|
+
export function requestOrigin(req, bound) {
|
|
3
|
+
const host = String(req.headers.host ?? '').trim();
|
|
4
|
+
// A host, an optional port: anything else is not an origin to write into a page.
|
|
5
|
+
if (!/^(?:[a-z0-9.-]+|\[[0-9a-f:.]+\])(?::\d{1,5})?$/i.test(host))
|
|
6
|
+
return undefined;
|
|
7
|
+
return `${arrivedOverHttps(req, bound.trustedProxies) ? 'https' : 'http'}://${host.toLowerCase()}`;
|
|
8
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a dispatcher is put together: the door (door.ts) and then tables of
|
|
3
|
+
* routes, each tried in order until one answers. A route is a predicate
|
|
4
|
+
* that answers as it decides, so a table reads as the order requests are
|
|
5
|
+
* matched in, and moving a route moves its precedence with it — which is
|
|
6
|
+
* why the tables are lists rather than a map keyed by path.
|
|
7
|
+
*/
|
|
8
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
9
|
+
/** What every route is handed, whatever product's dispatcher it sits in: the request, and what that product adds. */
|
|
10
|
+
export type RequestContext<Ext = object> = {
|
|
11
|
+
readonly req: IncomingMessage;
|
|
12
|
+
readonly res: ServerResponse;
|
|
13
|
+
readonly url: URL;
|
|
14
|
+
readonly path: string;
|
|
15
|
+
} & Ext;
|
|
16
|
+
/** One route: true when it answered the request. */
|
|
17
|
+
export type Route<C extends RequestContext> = (ctx: C) => boolean | Promise<boolean>;
|
|
18
|
+
/** Try `routes` in order; true when one answered. */
|
|
19
|
+
export declare function route<C extends RequestContext>(ctx: C, routes: readonly Route<C>[]): Promise<boolean>;
|
|
20
|
+
/**
|
|
21
|
+
* Every dispatcher: a module that takes a request from a socket (or a host's
|
|
22
|
+
* server) and holds it to the door before any route reads it, in the door's
|
|
23
|
+
* order — the Host, the proxy's identity, the product's session, then a
|
|
24
|
+
* write's Origin and body. test/door.test.ts stands each up and sends it the
|
|
25
|
+
* same refusals; a new one is named here, and given a row there.
|
|
26
|
+
*/
|
|
27
|
+
export declare const DISPATCHERS: readonly [{
|
|
28
|
+
readonly module: 'packages/tablewalk/src/server/http/browserHandler.ts';
|
|
29
|
+
readonly serves: 'the database browser';
|
|
30
|
+
}, {
|
|
31
|
+
readonly module: 'packages/mistri/src/server/http/handler.ts';
|
|
32
|
+
readonly serves: 'the Apps of a deployment that serves them';
|
|
33
|
+
}, {
|
|
34
|
+
readonly module: 'packages/mistri/src/server/embed/handler.ts';
|
|
35
|
+
readonly serves: 'an App mounted inside somebody else’s server';
|
|
36
|
+
}, {
|
|
37
|
+
readonly module: 'packages/mistri/src/server/http/suite.ts';
|
|
38
|
+
readonly serves: 'several deployments under one origin, each behind its own dispatcher';
|
|
39
|
+
}, {
|
|
40
|
+
readonly module: 'packages/mistri/src/server/tenant/tenantAuthenticatedHttp.ts';
|
|
41
|
+
readonly serves: 'a tenant App’s browser host and its native sign-in';
|
|
42
|
+
}, {
|
|
43
|
+
readonly module: 'packages/mistri/src/server/tenant/tenantHttp.ts';
|
|
44
|
+
readonly serves: 'a tenant App’s data, inside its browser host';
|
|
45
|
+
}];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Try `routes` in order; true when one answered. */
|
|
2
|
+
export async function route(ctx, routes) {
|
|
3
|
+
for (const each of routes)
|
|
4
|
+
if (await each(ctx))
|
|
5
|
+
return true;
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Every dispatcher: a module that takes a request from a socket (or a host's
|
|
10
|
+
* server) and holds it to the door before any route reads it, in the door's
|
|
11
|
+
* order — the Host, the proxy's identity, the product's session, then a
|
|
12
|
+
* write's Origin and body. test/door.test.ts stands each up and sends it the
|
|
13
|
+
* same refusals; a new one is named here, and given a row there.
|
|
14
|
+
*/
|
|
15
|
+
export const DISPATCHERS = [
|
|
16
|
+
{ module: 'packages/tablewalk/src/server/http/browserHandler.ts', serves: 'the database browser' },
|
|
17
|
+
{ module: 'packages/mistri/src/server/http/handler.ts', serves: 'the Apps of a deployment that serves them' },
|
|
18
|
+
{ module: 'packages/mistri/src/server/embed/handler.ts', serves: 'an App mounted inside somebody else’s server' },
|
|
19
|
+
{ module: 'packages/mistri/src/server/http/suite.ts', serves: 'several deployments under one origin, each behind its own dispatcher' },
|
|
20
|
+
{ module: 'packages/mistri/src/server/tenant/tenantAuthenticatedHttp.ts', serves: 'a tenant App’s browser host and its native sign-in' },
|
|
21
|
+
{ module: 'packages/mistri/src/server/tenant/tenantHttp.ts', serves: 'a tenant App’s data, inside its browser host' },
|
|
22
|
+
];
|