@mistriwork/engine 0.0.0 → 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 +16 -1
- 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 +262 -3
- package/schema/model.d.ts +298 -0
- package/schema/theme.d.ts +587 -0
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A record template: one row, with its references pulled in around it.
|
|
3
|
+
*
|
|
4
|
+
* The view composer as built answers "give me a table of X with columns from
|
|
5
|
+
* the things X points at" — one row per base record, joins flattened into
|
|
6
|
+
* columns. That is a useful shape and the wrong one for the question tablewalk
|
|
7
|
+
* actually exists to answer, which is "show me *this* work order, properly".
|
|
8
|
+
*
|
|
9
|
+
* That question wants a page: the work order's own fields, the customer's
|
|
10
|
+
* details inline because a work order without its customer's name is a
|
|
11
|
+
* riddle, and its parts and notes as tables underneath because there are
|
|
12
|
+
* several of each and a count is not enough.
|
|
13
|
+
*
|
|
14
|
+
* The difference from a list view is not cosmetic — it is what the thing is
|
|
15
|
+
* bound to. A list view is a *query*: it produces rows and you read them. A
|
|
16
|
+
* record template is bound to a **table**, not to a row, and applies to every
|
|
17
|
+
* row of it. Configure `work_order` once and every work order you ever walk
|
|
18
|
+
* to is laid out that way. That is what makes it worth configuring at all.
|
|
19
|
+
*
|
|
20
|
+
* Two consequences fall out, and both are why this shape earns its place:
|
|
21
|
+
*
|
|
22
|
+
* - A has-many relationship is finally answerable. In a list view it either
|
|
23
|
+
* multiplies rows or collapses to a count; here it is simply a table on
|
|
24
|
+
* the page, which is what anyone asking for "the order and its lines"
|
|
25
|
+
* meant in the first place.
|
|
26
|
+
* - Views stop being a dead end. A list view is somewhere you look; a
|
|
27
|
+
* record template is where a walk *arrives*, so views become part of the
|
|
28
|
+
* navigation rather than a parallel product beside it.
|
|
29
|
+
*/
|
|
30
|
+
import { findTable, labelColumn, looksLikeDate, primaryKey, referencesFrom, referencesTo, } from './schema.js';
|
|
31
|
+
import { parseSortText } from './sortText.js';
|
|
32
|
+
/** Rows to show in an embedded list before it needs its own page. */
|
|
33
|
+
export const DEFAULT_LIST_LIMIT = 10;
|
|
34
|
+
/**
|
|
35
|
+
* Below this many columns, grouping costs more than it saves.
|
|
36
|
+
*
|
|
37
|
+
* A four-column table split into "Identity" and "Details" is two headings and
|
|
38
|
+
* a divider to organise four fields — more ceremony than content, and slower
|
|
39
|
+
* to read than the flat list it replaced.
|
|
40
|
+
*/
|
|
41
|
+
const GROUP_THRESHOLD = 12;
|
|
42
|
+
const AUDIT_NAME = /^(sys_|created|updated|modified|deleted|inserted)|_(at|by)$|^(version|etag|revision)$/i;
|
|
43
|
+
/**
|
|
44
|
+
* How a table's own columns divide into blocks.
|
|
45
|
+
*
|
|
46
|
+
* Derived from what the schema already says rather than from a stored layout:
|
|
47
|
+
* keys and the label column identify, foreign keys link, dates measure, and
|
|
48
|
+
* anything named like an audit column is bookkeeping. Ordering is by what
|
|
49
|
+
* gets looked at first, not by declaration order.
|
|
50
|
+
*
|
|
51
|
+
* Lives here rather than in the renderer because it *is* the default
|
|
52
|
+
* template. Having the derivation in one place and the stored layout in
|
|
53
|
+
* another is how the two start disagreeing about what a record looks like.
|
|
54
|
+
*/
|
|
55
|
+
export function groupOwnColumns(table) {
|
|
56
|
+
const columns = table.columns;
|
|
57
|
+
if (columns.length < GROUP_THRESHOLD)
|
|
58
|
+
return [[null, columns]];
|
|
59
|
+
const label = labelColumn(table);
|
|
60
|
+
const groups = new Map([
|
|
61
|
+
['Identity', []],
|
|
62
|
+
['Bookkeeping', []],
|
|
63
|
+
['References', []],
|
|
64
|
+
['Details', []],
|
|
65
|
+
['Dates', []],
|
|
66
|
+
]);
|
|
67
|
+
for (const col of columns) {
|
|
68
|
+
if (col.primaryKey || col.name === label)
|
|
69
|
+
groups.get('Identity').push(col);
|
|
70
|
+
else if (col.references)
|
|
71
|
+
groups.get('References').push(col);
|
|
72
|
+
else if (AUDIT_NAME.test(col.name))
|
|
73
|
+
groups.get('Bookkeeping').push(col);
|
|
74
|
+
else if (looksLikeDate(col))
|
|
75
|
+
groups.get('Dates').push(col);
|
|
76
|
+
else
|
|
77
|
+
groups.get('Details').push(col);
|
|
78
|
+
}
|
|
79
|
+
// A section with nothing in it is a heading that means nothing.
|
|
80
|
+
return [...groups].filter(([, cols]) => cols.length);
|
|
81
|
+
}
|
|
82
|
+
/* ---------- deriving a starting template ---------- */
|
|
83
|
+
/**
|
|
84
|
+
* The template a table gets before anyone configures one.
|
|
85
|
+
*
|
|
86
|
+
* Derived rather than blank, because a blank record page is a worse starting
|
|
87
|
+
* point than the default layout the record view already produces, and because
|
|
88
|
+
* the fastest way to explain what a template *is* is to show someone one made
|
|
89
|
+
* of their own data.
|
|
90
|
+
*
|
|
91
|
+
* The rules are the ones the record view already uses, made explicit: the
|
|
92
|
+
* record's own fields first, then each to-one reference as its own labelled
|
|
93
|
+
* block, then each incoming relationship as a table.
|
|
94
|
+
*/
|
|
95
|
+
export function deriveTemplate(schema, tableId) {
|
|
96
|
+
const table = findTable(schema, tableId);
|
|
97
|
+
if (!table)
|
|
98
|
+
return undefined;
|
|
99
|
+
const sections = groupOwnColumns(table).map(([title, columns]) => ({
|
|
100
|
+
kind: 'fields',
|
|
101
|
+
title: title ?? undefined,
|
|
102
|
+
paths: columns.map((c) => c.name),
|
|
103
|
+
}));
|
|
104
|
+
/* One block per outgoing reference, holding a few readable columns of the
|
|
105
|
+
row it points at. Not every column: pulling a customer's forty fields
|
|
106
|
+
into a work order buries the work order. */
|
|
107
|
+
for (const fk of referencesFrom(schema, tableId)) {
|
|
108
|
+
if (fk.to.table === tableId)
|
|
109
|
+
continue; // a self-reference adds no context
|
|
110
|
+
const target = findTable(schema, fk.to.table);
|
|
111
|
+
if (!target)
|
|
112
|
+
continue;
|
|
113
|
+
const via = fk.from.columns.join('+');
|
|
114
|
+
sections.push({
|
|
115
|
+
kind: 'fields',
|
|
116
|
+
title: `${target.name} · via ${fk.from.columns.join(', ')}`,
|
|
117
|
+
paths: summaryColumns(target).map((c) => `${via}.${c}`),
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
for (const fk of referencesTo(schema, tableId)) {
|
|
121
|
+
const child = findTable(schema, fk.from.table);
|
|
122
|
+
if (!child)
|
|
123
|
+
continue;
|
|
124
|
+
sections.push({
|
|
125
|
+
kind: 'list',
|
|
126
|
+
title: `${child.name} · via ${fk.from.columns.join(', ')}`,
|
|
127
|
+
via: fk.name,
|
|
128
|
+
columns: listColumns(child, fk.from.columns),
|
|
129
|
+
limit: DEFAULT_LIST_LIMIT,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
return { id: `derived:${tableId}`, name: table.name, base: tableId, sections };
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Every column of a child table worth showing, in declaration order.
|
|
136
|
+
*
|
|
137
|
+
* All of them, not a summary. A summary is the right shape for a reference
|
|
138
|
+
* pulled *into* a record — a customer's forty fields would bury the work order
|
|
139
|
+
* they are attached to — and the wrong shape for a table of children, which is
|
|
140
|
+
* the thing you opened the record to read. `work_order_part` summarised down
|
|
141
|
+
* to one column of quantities is a list of numbers with nothing to attach them
|
|
142
|
+
* to.
|
|
143
|
+
*
|
|
144
|
+
* The join columns are still dropped: every row here carries the same value
|
|
145
|
+
* for them, so a column of one repeated value is width spent on nothing. The
|
|
146
|
+
* key stays, because it is what distinguishes the rows.
|
|
147
|
+
*
|
|
148
|
+
* Anyone who wants fewer can say so in the layout builder, which is the right
|
|
149
|
+
* order for a default — start from everything and subtract, rather than start
|
|
150
|
+
* from a guess and hunt for what is missing.
|
|
151
|
+
*/
|
|
152
|
+
export function listColumns(table, exclude = []) {
|
|
153
|
+
const skip = new Set(exclude);
|
|
154
|
+
const chosen = table.columns.filter((c) => !skip.has(c.name)).map((c) => c.name);
|
|
155
|
+
// Everything was part of the join: the key is better than an empty table.
|
|
156
|
+
return chosen.length ? chosen : primaryKey(table).slice(0, 1);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* A few columns that say what a row *is*.
|
|
160
|
+
*
|
|
161
|
+
* Keys and the columns forming the join are dropped: in a table of a work
|
|
162
|
+
* order's parts, every row has the same `work_order_id`, so a column of it is
|
|
163
|
+
* a column of one repeated value. What is left is what distinguishes the rows
|
|
164
|
+
* from each other, which is the only thing the section is there to show.
|
|
165
|
+
*/
|
|
166
|
+
export function summaryColumns(table, exclude = [], max = 5) {
|
|
167
|
+
const skip = new Set(exclude);
|
|
168
|
+
const chosen = [];
|
|
169
|
+
for (const column of table.columns) {
|
|
170
|
+
if (skip.has(column.name))
|
|
171
|
+
continue;
|
|
172
|
+
if (column.primaryKey && table.columns.some((c) => !c.primaryKey && !skip.has(c.name)))
|
|
173
|
+
continue;
|
|
174
|
+
chosen.push(column.name);
|
|
175
|
+
if (chosen.length >= max)
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
// Everything was a key or excluded: the key is better than nothing.
|
|
179
|
+
return chosen.length ? chosen : primaryKey(table).slice(0, 1);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Match each list section to the foreign key it names.
|
|
183
|
+
*
|
|
184
|
+
* A section whose constraint has since been dropped is returned as an error
|
|
185
|
+
* rather than skipped: a template that quietly stops showing a table looks
|
|
186
|
+
* exactly like a record that has no rows in it.
|
|
187
|
+
*/
|
|
188
|
+
export function resolveLists(schema, template) {
|
|
189
|
+
const lists = [];
|
|
190
|
+
const errors = [];
|
|
191
|
+
for (const section of template.sections) {
|
|
192
|
+
if (section.kind !== 'list')
|
|
193
|
+
continue;
|
|
194
|
+
const fk = referencesTo(schema, template.base).find((f) => f.name === section.via);
|
|
195
|
+
if (!fk) {
|
|
196
|
+
errors.push(`${template.name}: nothing called "${section.via}" points at ${template.base} any more. ` +
|
|
197
|
+
`The section was left in place so it can be removed or repointed.`);
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
const child = findTable(schema, fk.from.table);
|
|
201
|
+
if (!child) {
|
|
202
|
+
errors.push(`${template.name}: ${fk.from.table} is not in this schema.`);
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
lists.push({
|
|
206
|
+
section,
|
|
207
|
+
fk,
|
|
208
|
+
child,
|
|
209
|
+
join: fk.to.columns.map((parentColumn, i) => ({
|
|
210
|
+
parentColumn,
|
|
211
|
+
childColumn: fk.from.columns[i] ?? fk.from.columns[0],
|
|
212
|
+
})),
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
return { lists, errors };
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Every path the base row itself has to supply.
|
|
219
|
+
*
|
|
220
|
+
* Collected across field sections so the record can be fetched in one query
|
|
221
|
+
* rather than one per section — a page with six reference blocks should not
|
|
222
|
+
* be six round trips.
|
|
223
|
+
*/
|
|
224
|
+
export function fieldPaths(template) {
|
|
225
|
+
const seen = new Set();
|
|
226
|
+
for (const section of template.sections) {
|
|
227
|
+
if (section.kind !== 'fields')
|
|
228
|
+
continue;
|
|
229
|
+
for (const path of section.paths)
|
|
230
|
+
seen.add(path);
|
|
231
|
+
}
|
|
232
|
+
return [...seen];
|
|
233
|
+
}
|
|
234
|
+
/** Whether a template still says anything, after resolution. */
|
|
235
|
+
export function isEmpty(template) {
|
|
236
|
+
return !template.sections.some((s) => (s.kind === 'list' ? true : s.paths.length > 0));
|
|
237
|
+
}
|
|
238
|
+
/* The spellings a layout section may not use any more, each mapped to the
|
|
239
|
+
word that replaced it. Refused by name, in the parser's usual voice, the
|
|
240
|
+
same way parseSection in page.ts refuses them — a local copy rather than a
|
|
241
|
+
shared helper, because the two parsers name different examples and the
|
|
242
|
+
client mirror rules keep this file importing nothing it does not need.
|
|
243
|
+
`via` is NOT here: it names the foreign key's constraint, which is a
|
|
244
|
+
different fact from the direction `whose` writes down, and it keeps its
|
|
245
|
+
name. */
|
|
246
|
+
const RENAMED = {
|
|
247
|
+
path: '"whose" — the column of the child table that names this record, e.g. "customer_id"',
|
|
248
|
+
paths: '"show" — the fields to show, e.g. ["name", "customer_id.name"]',
|
|
249
|
+
columns: '"show" — the columns the list shows, e.g. ["invoice_date", "total"]',
|
|
250
|
+
orderBy: '"sort" — written like the query bar, e.g. "invoice_date desc, id"',
|
|
251
|
+
};
|
|
252
|
+
function refuseRenamed(s, at, keys) {
|
|
253
|
+
for (const key of keys) {
|
|
254
|
+
if (s[key] !== undefined)
|
|
255
|
+
throw new Error(`${at} has "${key}", which is now ${RENAMED[key]}.`);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
function parseSort(raw, at) {
|
|
259
|
+
return parseSortText(raw, at, 'invoice_date desc, id');
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Read the `layouts` section of a tablewalk.json.
|
|
263
|
+
*
|
|
264
|
+
* Throws on anything malformed rather than skipping it, naming the entry and
|
|
265
|
+
* the fix — the same rule `parsePagesConfig` follows, for the same reason: a
|
|
266
|
+
* layout that silently did not appear is a bug report that starts "I
|
|
267
|
+
* definitely wrote it".
|
|
268
|
+
*
|
|
269
|
+
* Structure only. Whether `customer_id` is a real column, or `invoice` a real
|
|
270
|
+
* table, needs a schema this runs long before — those are answered when the
|
|
271
|
+
* layout is served, and reported on the layout itself.
|
|
272
|
+
*/
|
|
273
|
+
export function parseLayoutsConfig(raw, where) {
|
|
274
|
+
const layouts = raw?.layouts;
|
|
275
|
+
if (layouts === undefined)
|
|
276
|
+
return [];
|
|
277
|
+
if (!Array.isArray(layouts))
|
|
278
|
+
throw new Error(`${where}: "layouts" must be an array.`);
|
|
279
|
+
const seen = new Set();
|
|
280
|
+
return layouts.map((entry, i) => {
|
|
281
|
+
const at = `${where}: layout ${i + 1}`;
|
|
282
|
+
if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
|
|
283
|
+
throw new Error(`${at} is not an object.`);
|
|
284
|
+
}
|
|
285
|
+
const l = entry;
|
|
286
|
+
if (typeof l.table !== 'string' || !l.table.trim()) {
|
|
287
|
+
throw new Error(`${at} has no "table" — a layout lays out one table's records.`);
|
|
288
|
+
}
|
|
289
|
+
const table = l.table.trim();
|
|
290
|
+
if (l.connection !== undefined && typeof l.connection !== 'string') {
|
|
291
|
+
throw new Error(`${at} ("${table}") has a "connection" that is not a string.`);
|
|
292
|
+
}
|
|
293
|
+
if (l.name !== undefined && typeof l.name !== 'string') {
|
|
294
|
+
throw new Error(`${at} ("${table}") has a "name" that is not a string.`);
|
|
295
|
+
}
|
|
296
|
+
/* One per table per connection: the store this fills is keyed that way,
|
|
297
|
+
so a second would silently win over the first. */
|
|
298
|
+
const key = `${l.connection ?? ''}::${table}`;
|
|
299
|
+
if (seen.has(key))
|
|
300
|
+
throw new Error(`${at} repeats a layout for "${table}".`);
|
|
301
|
+
seen.add(key);
|
|
302
|
+
if (!Array.isArray(l.sections) || !l.sections.length) {
|
|
303
|
+
throw new Error(`${at} ("${table}") has no "sections".`);
|
|
304
|
+
}
|
|
305
|
+
const sections = l.sections.map((raw2, j) => {
|
|
306
|
+
const sat = `${at} ("${table}"), section ${j + 1}`;
|
|
307
|
+
if (!raw2 || typeof raw2 !== 'object' || Array.isArray(raw2)) {
|
|
308
|
+
throw new Error(`${sat} is not an object.`);
|
|
309
|
+
}
|
|
310
|
+
const s = raw2;
|
|
311
|
+
if (s.kind !== 'fields' && s.kind !== 'list') {
|
|
312
|
+
throw new Error(`${sat} has "kind": ${JSON.stringify(s.kind)} — it must be "fields" or "list".`);
|
|
313
|
+
}
|
|
314
|
+
if (s.title !== undefined && typeof s.title !== 'string') {
|
|
315
|
+
throw new Error(`${sat} has a "title" that is not a string.`);
|
|
316
|
+
}
|
|
317
|
+
if (s.kind === 'fields') {
|
|
318
|
+
refuseRenamed(s, sat, ['paths']);
|
|
319
|
+
if (!Array.isArray(s.show) || !s.show.every((p) => typeof p === 'string' && p.trim())) {
|
|
320
|
+
throw new Error(`${sat} needs "show": a list of column names or paths like customer_id.name.`);
|
|
321
|
+
}
|
|
322
|
+
return { kind: 'fields', ...(s.title ? { title: s.title } : {}), paths: s.show.map((p) => String(p).trim()) };
|
|
323
|
+
}
|
|
324
|
+
/* A list says which relationship it shows, one way or the other. */
|
|
325
|
+
refuseRenamed(s, sat, ['path', 'columns', 'orderBy']);
|
|
326
|
+
const hasVia = typeof s.via === 'string' && s.via.trim();
|
|
327
|
+
const hasPair = typeof s.from === 'string' && s.from.trim() && typeof s.whose === 'string' && s.whose.trim();
|
|
328
|
+
if (!hasVia && !hasPair) {
|
|
329
|
+
throw new Error(`${sat} needs either "via" (a foreign key constraint name) or "from" and "whose" ` +
|
|
330
|
+
`— the child table and the column of it that points back here.`);
|
|
331
|
+
}
|
|
332
|
+
if (s.show !== undefined && (!Array.isArray(s.show) || !s.show.every((c) => typeof c === 'string'))) {
|
|
333
|
+
throw new Error(`${sat} has a "show" that is not a list of column names.`);
|
|
334
|
+
}
|
|
335
|
+
if (s.limit !== undefined && (typeof s.limit !== 'number' || !Number.isInteger(s.limit) || s.limit < 1)) {
|
|
336
|
+
throw new Error(`${sat} has a "limit" that is not a whole number of rows.`);
|
|
337
|
+
}
|
|
338
|
+
const orderBy = parseSort(s.sort, sat);
|
|
339
|
+
return {
|
|
340
|
+
kind: 'list',
|
|
341
|
+
...(s.title ? { title: s.title } : {}),
|
|
342
|
+
...(hasVia ? { via: String(s.via).trim() } : {}),
|
|
343
|
+
...(hasPair ? { from: String(s.from).trim(), path: String(s.whose).trim() } : {}),
|
|
344
|
+
columns: Array.isArray(s.show) ? s.show.map((c) => String(c)) : [],
|
|
345
|
+
...(s.limit !== undefined ? { limit: s.limit } : {}),
|
|
346
|
+
...(orderBy !== undefined ? { orderBy } : {}),
|
|
347
|
+
};
|
|
348
|
+
});
|
|
349
|
+
return {
|
|
350
|
+
table,
|
|
351
|
+
...(l.connection ? { connection: String(l.connection) } : {}),
|
|
352
|
+
...(l.name ? { name: String(l.name) } : {}),
|
|
353
|
+
sections,
|
|
354
|
+
};
|
|
355
|
+
});
|
|
356
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/** Reference paths and joined labels used when planning record and view reads. */
|
|
2
|
+
import { type DatabaseSchema, type TableMeta } from './schema.js';
|
|
3
|
+
/** Joined labels share the field query; never fetch each reference separately. */
|
|
4
|
+
export declare function referenceProjection(schema: DatabaseSchema, table: TableMeta, paths: readonly string[], enabled: boolean, namingPath?: (table: TableMeta) => string | undefined): {
|
|
5
|
+
fetched: string[];
|
|
6
|
+
labels: Map<string, string>;
|
|
7
|
+
};
|
|
8
|
+
/** Hidden label columns must not replace raw keys or collide with authored aliases. */
|
|
9
|
+
export declare function referenceView<T extends {
|
|
10
|
+
columns?: Array<{
|
|
11
|
+
path: string;
|
|
12
|
+
alias?: string;
|
|
13
|
+
}>;
|
|
14
|
+
}>(schema: DatabaseSchema, table: TableMeta, view: T, enabled: boolean, namingPath?: (table: TableMeta) => string | undefined): {
|
|
15
|
+
view: T;
|
|
16
|
+
labelColumns: Record<string, string>;
|
|
17
|
+
hidden: string[];
|
|
18
|
+
};
|
|
19
|
+
/** Navigation needs the complete authorized key, independently of authored show.
|
|
20
|
+
* Add labels first so hidden key columns do not introduce extra reference labels. */
|
|
21
|
+
export declare function recordView<T extends {
|
|
22
|
+
columns?: Array<{
|
|
23
|
+
path: string;
|
|
24
|
+
alias?: string;
|
|
25
|
+
}>;
|
|
26
|
+
}>(schema: DatabaseSchema, table: TableMeta, view: T, enabled: boolean, namingPath?: (table: TableMeta) => string | undefined, rootLabelPath?: (table: TableMeta) => string | undefined): {
|
|
27
|
+
labelColumns: Record<string, string>;
|
|
28
|
+
view: T & {
|
|
29
|
+
columns: {
|
|
30
|
+
path: string;
|
|
31
|
+
alias?: string;
|
|
32
|
+
}[];
|
|
33
|
+
};
|
|
34
|
+
hidden: string[];
|
|
35
|
+
keyColumns: {
|
|
36
|
+
column: string;
|
|
37
|
+
index: number;
|
|
38
|
+
}[];
|
|
39
|
+
labelColumn: {
|
|
40
|
+
path: string;
|
|
41
|
+
index: number;
|
|
42
|
+
} | undefined;
|
|
43
|
+
};
|
|
44
|
+
/** A private synthetic output is the only value record navigation may treat as
|
|
45
|
+
* the configured label. It deliberately does not copy or rename authored cells. */
|
|
46
|
+
export declare function recordViewLabel(labelColumn: {
|
|
47
|
+
path: string;
|
|
48
|
+
index: number;
|
|
49
|
+
} | undefined, outputs: readonly string[], row: Record<string, unknown>): Record<string, unknown>;
|
|
50
|
+
/** Returned output positions preserve aliases without narrowing numeric strings. */
|
|
51
|
+
export declare function recordViewKey(keyColumns: readonly {
|
|
52
|
+
column: string;
|
|
53
|
+
index: number;
|
|
54
|
+
}[], outputs: readonly string[], row: Record<string, unknown>): Record<string, string | number> | null;
|
|
55
|
+
/** A name that opens with the page record's, said without it. */
|
|
56
|
+
export declare function withoutParent<T>(value: T, parent: string | undefined): T | string;
|
|
57
|
+
/** The rows with every label that opens with the page record's name said without it. */
|
|
58
|
+
export declare function withoutParentName(rows: ReadonlyArray<Record<string, unknown>>, labelOutputs: readonly string[], parent: string | undefined): Array<Record<string, unknown>>;
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/** Reference paths and joined labels used when planning record and view reads. */
|
|
2
|
+
import { findTable, labelColumn, primaryKey } from './schema.js';
|
|
3
|
+
import { rollupColumnMeta } from './rollups.js';
|
|
4
|
+
import { MAX_PATH_DEPTH, tryResolvePath } from './viewPaths.js';
|
|
5
|
+
function viewOutputs(columns) {
|
|
6
|
+
const counts = new Map();
|
|
7
|
+
return columns.map((col) => {
|
|
8
|
+
const name = col.alias?.trim() || col.path;
|
|
9
|
+
const count = (counts.get(name) ?? 0) + 1;
|
|
10
|
+
counts.set(name, count);
|
|
11
|
+
return count === 1 ? name : `${name}_${count}`;
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
/** Joined labels share the field query; never fetch each reference separately. */
|
|
15
|
+
export function referenceProjection(schema, table, paths, enabled, namingPath = labelColumn) {
|
|
16
|
+
const fetched = [...new Set(paths)];
|
|
17
|
+
const labels = new Map();
|
|
18
|
+
if (!enabled)
|
|
19
|
+
return { fetched, labels };
|
|
20
|
+
/* A single column cannot safely traverse one leg of a composite foreign
|
|
21
|
+
key — unless it is also a key of its own: a tenant's `vehicle_id` is both
|
|
22
|
+
the composite `(tenant_id, vehicle_id)`, which keeps it in its tenant, and
|
|
23
|
+
the single key its path walks, and was drawn as its opaque id. */
|
|
24
|
+
const composite = (tableId) => {
|
|
25
|
+
const single = new Set(schema.foreignKeys.filter((fk) => fk.from.table === tableId && fk.from.columns.length === 1).map((fk) => fk.from.columns[0]));
|
|
26
|
+
return new Set(schema.foreignKeys
|
|
27
|
+
.filter((fk) => fk.from.table === tableId && fk.from.columns.length > 1)
|
|
28
|
+
.flatMap((fk) => fk.from.columns)
|
|
29
|
+
.filter((column) => !single.has(column)));
|
|
30
|
+
};
|
|
31
|
+
for (const path of paths) {
|
|
32
|
+
/* A reference reached through others — `employee_id.department_id` —
|
|
33
|
+
is named the same way as one on the row itself: its record's label,
|
|
34
|
+
read one hop further along, while the path stays within reach. */
|
|
35
|
+
let column;
|
|
36
|
+
let owner = table.id;
|
|
37
|
+
let hops = 0;
|
|
38
|
+
let derived = false;
|
|
39
|
+
if (!path.includes('.')) {
|
|
40
|
+
column = table.columns.find((col) => col.name === path);
|
|
41
|
+
/* A latest of a reference column is the record's key too (rollups.ts): named as the column it reads is, by a
|
|
42
|
+
column of that record (`resident.name`, viewPaths.ts); a template or a path past it is not a column to read. */
|
|
43
|
+
const rollup = !column && table.rollups && Object.hasOwn(table.rollups, path) ? table.rollups[path] : undefined;
|
|
44
|
+
if (rollup?.fn === 'latest' && rollup.references && !rollup.of) {
|
|
45
|
+
column = rollupColumnMeta(path, rollup);
|
|
46
|
+
derived = true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
const { resolved } = tryResolvePath(schema, table.id, path);
|
|
51
|
+
if (!resolved)
|
|
52
|
+
continue;
|
|
53
|
+
column = resolved.column;
|
|
54
|
+
owner = resolved.table.id;
|
|
55
|
+
hops = resolved.hops.length;
|
|
56
|
+
}
|
|
57
|
+
if (!column?.references || composite(owner).has(column.name))
|
|
58
|
+
continue;
|
|
59
|
+
const target = findTable(schema, column.references.table);
|
|
60
|
+
const naming = target && namingPath(target);
|
|
61
|
+
if (derived && (!naming || naming.includes('.') || !target?.columns.some((col) => col.name === naming)))
|
|
62
|
+
continue;
|
|
63
|
+
if (!naming || hops + 1 + naming.split('.').length - 1 > MAX_PATH_DEPTH)
|
|
64
|
+
continue;
|
|
65
|
+
const labelAt = `${path}.${naming}`;
|
|
66
|
+
labels.set(path, labelAt);
|
|
67
|
+
if (!fetched.includes(labelAt))
|
|
68
|
+
fetched.push(labelAt);
|
|
69
|
+
}
|
|
70
|
+
return { fetched, labels };
|
|
71
|
+
}
|
|
72
|
+
/** Hidden label columns must not replace raw keys or collide with authored aliases. */
|
|
73
|
+
export function referenceView(schema, table, view, enabled, namingPath = labelColumn) {
|
|
74
|
+
const columns = view.columns ?? [];
|
|
75
|
+
const projection = referenceProjection(schema, table, columns.map((col) => col.path), enabled, namingPath);
|
|
76
|
+
const labelColumns = {};
|
|
77
|
+
const hidden = [];
|
|
78
|
+
const outputs = viewOutputs(columns);
|
|
79
|
+
const used = new Set(outputs);
|
|
80
|
+
const extra = [];
|
|
81
|
+
columns.forEach((col, index) => {
|
|
82
|
+
const label = projection.labels.get(col.path);
|
|
83
|
+
if (!label)
|
|
84
|
+
return;
|
|
85
|
+
let alias = `__tw_reference_${index}`;
|
|
86
|
+
while (used.has(alias))
|
|
87
|
+
alias += '_';
|
|
88
|
+
used.add(alias);
|
|
89
|
+
extra.push({ path: label, alias });
|
|
90
|
+
labelColumns[outputs[index]] = alias;
|
|
91
|
+
hidden.push(alias);
|
|
92
|
+
});
|
|
93
|
+
return { view: extra.length ? { ...view, columns: [...columns, ...extra] } : view, labelColumns, hidden };
|
|
94
|
+
}
|
|
95
|
+
/** Navigation needs the complete authorized key, independently of authored show.
|
|
96
|
+
* Add labels first so hidden key columns do not introduce extra reference labels. */
|
|
97
|
+
export function recordView(schema, table, view, enabled, namingPath = labelColumn, rootLabelPath) {
|
|
98
|
+
const shown = view.columns?.length ? view : { ...view, columns: table.columns.map((column) => ({ path: column.name })) };
|
|
99
|
+
const presentation = referenceView(schema, table, shown, enabled, namingPath);
|
|
100
|
+
const columns = [...(presentation.view.columns ?? [])];
|
|
101
|
+
const outputs = viewOutputs(columns);
|
|
102
|
+
const used = new Set(outputs);
|
|
103
|
+
const hidden = [...presentation.hidden];
|
|
104
|
+
// A record's configured label may be a joined path and the view may have
|
|
105
|
+
// named an unrelated column or alias the same way. Carry it in a private
|
|
106
|
+
// output so navigation never reads an authored cell as the record's name.
|
|
107
|
+
const naming = rootLabelPath?.(table);
|
|
108
|
+
let labelColumn;
|
|
109
|
+
if (naming) {
|
|
110
|
+
let alias = '__tw_label';
|
|
111
|
+
while (used.has(alias))
|
|
112
|
+
alias += '_';
|
|
113
|
+
used.add(alias);
|
|
114
|
+
labelColumn = { path: naming, index: columns.length };
|
|
115
|
+
columns.push({ path: naming, alias });
|
|
116
|
+
outputs.push(alias);
|
|
117
|
+
hidden.push(alias);
|
|
118
|
+
}
|
|
119
|
+
const keyColumns = primaryKey(table).map((column, keyIndex) => {
|
|
120
|
+
// A colliding authored output cannot be trusted to contain this path's value.
|
|
121
|
+
let index = columns.findIndex((col, i) => col.path === column && outputs.filter((name) => name === outputs[i]).length === 1);
|
|
122
|
+
if (index < 0) {
|
|
123
|
+
let alias = `__tw_key_${keyIndex}`;
|
|
124
|
+
while (used.has(alias))
|
|
125
|
+
alias += '_';
|
|
126
|
+
used.add(alias);
|
|
127
|
+
index = columns.length;
|
|
128
|
+
columns.push({ path: column, alias });
|
|
129
|
+
outputs.push(alias);
|
|
130
|
+
hidden.push(alias);
|
|
131
|
+
}
|
|
132
|
+
return { column, index };
|
|
133
|
+
});
|
|
134
|
+
return { ...presentation, view: { ...presentation.view, columns }, hidden, keyColumns, labelColumn };
|
|
135
|
+
}
|
|
136
|
+
/** A private synthetic output is the only value record navigation may treat as
|
|
137
|
+
* the configured label. It deliberately does not copy or rename authored cells. */
|
|
138
|
+
export function recordViewLabel(labelColumn, outputs, row) {
|
|
139
|
+
if (!labelColumn)
|
|
140
|
+
return {};
|
|
141
|
+
const output = outputs[labelColumn.index];
|
|
142
|
+
if (output === undefined || outputs.filter((name) => name === output).length !== 1 || !Object.hasOwn(row, output))
|
|
143
|
+
return {};
|
|
144
|
+
return { [labelColumn.path]: row[output] };
|
|
145
|
+
}
|
|
146
|
+
/** Returned output positions preserve aliases without narrowing numeric strings. */
|
|
147
|
+
export function recordViewKey(keyColumns, outputs, row) {
|
|
148
|
+
if (!keyColumns.length)
|
|
149
|
+
return null;
|
|
150
|
+
const entries = [];
|
|
151
|
+
for (const { column, index } of keyColumns) {
|
|
152
|
+
const output = outputs[index];
|
|
153
|
+
if (output === undefined || outputs.filter((name) => name === output).length !== 1 || !Object.hasOwn(row, output))
|
|
154
|
+
return null;
|
|
155
|
+
const value = row[output];
|
|
156
|
+
if (typeof value !== 'string' && (typeof value !== 'number' || !Number.isFinite(value)))
|
|
157
|
+
return null;
|
|
158
|
+
entries.push([column, value]);
|
|
159
|
+
}
|
|
160
|
+
return Object.fromEntries(entries);
|
|
161
|
+
}
|
|
162
|
+
/* A child is named by its parent and a word that tells it from its siblings
|
|
163
|
+
("Ada Park · follow-up", docs/design.md). On the parent's own page every
|
|
164
|
+
sibling repeats the page's title, so the list says the word alone; a name
|
|
165
|
+
of some other parent, or one that is the parent's name and nothing more,
|
|
166
|
+
is left as it is. */
|
|
167
|
+
const AFTER_PARENT = /^\s*[·•–—:|/-]\s*/u;
|
|
168
|
+
/** A name that opens with the page record's, said without it. */
|
|
169
|
+
export function withoutParent(value, parent) {
|
|
170
|
+
const name = parent?.trim();
|
|
171
|
+
if (!name || typeof value !== 'string' || !value.startsWith(name))
|
|
172
|
+
return value;
|
|
173
|
+
const rest = value.slice(name.length);
|
|
174
|
+
const cut = AFTER_PARENT.exec(rest);
|
|
175
|
+
const word = cut ? rest.slice(cut[0].length) : '';
|
|
176
|
+
return cut && word.trim() ? word : value;
|
|
177
|
+
}
|
|
178
|
+
/** The rows with every label that opens with the page record's name said without it. */
|
|
179
|
+
export function withoutParentName(rows, labelOutputs, parent) {
|
|
180
|
+
if (!parent?.trim() || !labelOutputs.length)
|
|
181
|
+
return rows;
|
|
182
|
+
const trim = (value) => withoutParent(value, parent);
|
|
183
|
+
return rows.map((row) => {
|
|
184
|
+
let next;
|
|
185
|
+
for (const output of labelOutputs) {
|
|
186
|
+
if (!Object.hasOwn(row, output))
|
|
187
|
+
continue;
|
|
188
|
+
const said = trim(row[output]);
|
|
189
|
+
if (said !== row[output])
|
|
190
|
+
(next ??= { ...row })[output] = said;
|
|
191
|
+
}
|
|
192
|
+
return next ?? row;
|
|
193
|
+
});
|
|
194
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A request an adapter will not carry out.
|
|
3
|
+
*
|
|
4
|
+
* Distinct from a database failure, and the distinction is the whole point:
|
|
5
|
+
* "that is not the whole primary key" and "the database is down" are both
|
|
6
|
+
* exceptions, and a server that cannot tell them apart answers both with a
|
|
7
|
+
* 500. The first is something the caller can fix by asking differently.
|
|
8
|
+
*
|
|
9
|
+
* Ordinary adapter guards run before a statement. Private scoped transactions
|
|
10
|
+
* also use this for stored-image checks: those failures poison the transaction
|
|
11
|
+
* and require rollback. The error class alone never proves a write outcome.
|
|
12
|
+
*/
|
|
13
|
+
export declare class Refusal extends Error {
|
|
14
|
+
/** The column names the message quotes, so a surface that calls them something else (an App's captions) can say them its way. Never values. */
|
|
15
|
+
readonly columns?: readonly string[];
|
|
16
|
+
/** `cause`: a database failure that kept the check from being made. The
|
|
17
|
+
* request is still refused — the boundary does not move — but an owner that
|
|
18
|
+
* answers a caller can tell "refused" from "could not answer". */
|
|
19
|
+
constructor(message: string, options?: {
|
|
20
|
+
columns?: readonly string[];
|
|
21
|
+
cause?: unknown;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/** Record why a refusal happened on the refusal itself, for the trusted reader
|
|
25
|
+
* only. Every opaque refusal takes its reason this way — a tenant denial, a
|
|
26
|
+
* row policy that did not load, a command the database would not take — so
|
|
27
|
+
* the one reader below can say it to the operator. A string is a sentence for
|
|
28
|
+
* that operator, written here and naming the rule, table or column. */
|
|
29
|
+
export declare function recordRefusalCause<E extends object>(error: E, cause: unknown): E;
|
|
30
|
+
/** The recorded reason behind a refusal, for a trusted diagnostic only. */
|
|
31
|
+
export declare const refusalCause: (error: unknown) => unknown;
|
|
32
|
+
/**
|
|
33
|
+
* What the operator is told about a refusal: each reason under it, outermost
|
|
34
|
+
* first — a recorded cause before `cause`, since the recorded one is the
|
|
35
|
+
* refusal's own — as messages, never objects, because a driver error's object
|
|
36
|
+
* can carry connection detail a console should not. Repeats are said once:
|
|
37
|
+
* a refusal rethrown as the same sentence is one reason, not two.
|
|
38
|
+
*/
|
|
39
|
+
export declare function refusalReasons(error: unknown): string[];
|
|
40
|
+
/**
|
|
41
|
+
* The refusal's one line for a startup headline: the fixed sentence, then the
|
|
42
|
+
* reason behind it. The `because:` lines under it carry the whole chain, but a
|
|
43
|
+
* reader (or a log that keeps one line) stopped at "could not be loaded or is
|
|
44
|
+
* invalid" and went to bisect the module; the headline now says the cause.
|
|
45
|
+
*/
|
|
46
|
+
export declare function refusalHeadline(error: unknown): string;
|
|
47
|
+
/** The `because:` lines under a refusalHeadline: the chain past the cause the headline says already, which
|
|
48
|
+
printed again beneath it read as two reasons. */
|
|
49
|
+
export declare const refusalReasonsBelow: (error: unknown) => string[];
|
|
50
|
+
/**
|
|
51
|
+
* A startup failure as the operator's terminal says it: the headline, then
|
|
52
|
+
* each further reason on a `because:` line. Every startup print goes through
|
|
53
|
+
* this, so a refusal that recorded why (a tenant denial's `"fonts" is not a
|
|
54
|
+
* key this takes`) is never said as its fixed sentence alone. The terminal of
|
|
55
|
+
* the person who started the server only: never an HTTP answer.
|
|
56
|
+
*/
|
|
57
|
+
export declare function startupReport(error: unknown): string;
|
|
58
|
+
/** Where an unexpected fault in `error` (or the chain under it) happened: its first stack frames, or none for a refusal.
|
|
59
|
+
Read by name, not `instanceof`: an App module's errors are another realm's. */
|
|
60
|
+
export declare function faultFrames(error: unknown, most?: number): string[];
|
|
61
|
+
/** Record the sentence this refusal's caller is told: see above. The first one recorded stands. */
|
|
62
|
+
export declare function sayRefusal<E extends object>(error: E, sentence: string): E;
|
|
63
|
+
/** The sentence a refusal's caller may read about why, if the code that refused said one. */
|
|
64
|
+
export declare const refusalSaid: (error: unknown) => string | undefined;
|