@clayroach/effect 3.19.14-source-capture.8 → 3.19.14-source-trace.2
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/SourceLocation/package.json +6 -0
- package/dist/cjs/Effect.js +2 -28
- package/dist/cjs/Effect.js.map +1 -1
- package/dist/cjs/FiberRef.js +12 -1
- package/dist/cjs/FiberRef.js.map +1 -1
- package/dist/cjs/Layer.js +2 -24
- package/dist/cjs/Layer.js.map +1 -1
- package/dist/cjs/RuntimeFlags.js +1 -29
- package/dist/cjs/RuntimeFlags.js.map +1 -1
- package/dist/cjs/SourceLocation.js +60 -0
- package/dist/cjs/SourceLocation.js.map +1 -0
- package/dist/cjs/Tracer.js +1 -15
- package/dist/cjs/Tracer.js.map +1 -1
- package/dist/cjs/Utils.js +1 -1
- package/dist/cjs/Utils.js.map +1 -1
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/internal/clock.js +1 -1
- package/dist/cjs/internal/clock.js.map +1 -1
- package/dist/cjs/internal/core.js +17 -50
- package/dist/cjs/internal/core.js.map +1 -1
- package/dist/cjs/internal/effect/circular.js +18 -30
- package/dist/cjs/internal/effect/circular.js.map +1 -1
- package/dist/cjs/internal/fiberRuntime.js +16 -65
- package/dist/cjs/internal/fiberRuntime.js.map +1 -1
- package/dist/cjs/internal/layer/circular.js +1 -5
- package/dist/cjs/internal/layer/circular.js.map +1 -1
- package/dist/cjs/internal/layer.js +1 -3
- package/dist/cjs/internal/layer.js.map +1 -1
- package/dist/cjs/internal/logger.js +25 -2
- package/dist/cjs/internal/logger.js.map +1 -1
- package/dist/cjs/internal/runtimeFlags.js +2 -11
- package/dist/cjs/internal/runtimeFlags.js.map +1 -1
- package/dist/cjs/internal/tracer.js +1 -114
- package/dist/cjs/internal/tracer.js.map +1 -1
- package/dist/dts/Config.d.ts +2 -2
- package/dist/dts/Config.d.ts.map +1 -1
- package/dist/dts/Effect.d.ts +8 -29
- package/dist/dts/Effect.d.ts.map +1 -1
- package/dist/dts/FiberRef.d.ts +12 -0
- package/dist/dts/FiberRef.d.ts.map +1 -1
- package/dist/dts/Layer.d.ts +0 -22
- package/dist/dts/Layer.d.ts.map +1 -1
- package/dist/dts/RuntimeFlags.d.ts +0 -28
- package/dist/dts/RuntimeFlags.d.ts.map +1 -1
- package/dist/dts/SourceLocation.d.ts +88 -0
- package/dist/dts/SourceLocation.d.ts.map +1 -0
- package/dist/dts/Tracer.d.ts +0 -15
- package/dist/dts/Tracer.d.ts.map +1 -1
- package/dist/dts/index.d.ts +6 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/core.d.ts.map +1 -1
- package/dist/dts/internal/layer.d.ts.map +1 -1
- package/dist/dts/internal/runtimeFlags.d.ts.map +1 -1
- package/dist/esm/Effect.js +0 -26
- package/dist/esm/Effect.js.map +1 -1
- package/dist/esm/FiberRef.js +11 -0
- package/dist/esm/FiberRef.js.map +1 -1
- package/dist/esm/Layer.js +0 -22
- package/dist/esm/Layer.js.map +1 -1
- package/dist/esm/RuntimeFlags.js +0 -28
- package/dist/esm/RuntimeFlags.js.map +1 -1
- package/dist/esm/SourceLocation.js +51 -0
- package/dist/esm/SourceLocation.js.map +1 -0
- package/dist/esm/Tracer.js +0 -14
- package/dist/esm/Tracer.js.map +1 -1
- package/dist/esm/Utils.js +1 -1
- package/dist/esm/Utils.js.map +1 -1
- package/dist/esm/index.js +6 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/clock.js +1 -1
- package/dist/esm/internal/clock.js.map +1 -1
- package/dist/esm/internal/core.js +12 -45
- package/dist/esm/internal/core.js.map +1 -1
- package/dist/esm/internal/effect/circular.js +18 -30
- package/dist/esm/internal/effect/circular.js.map +1 -1
- package/dist/esm/internal/fiberRuntime.js +13 -60
- package/dist/esm/internal/fiberRuntime.js.map +1 -1
- package/dist/esm/internal/layer/circular.js +0 -4
- package/dist/esm/internal/layer/circular.js.map +1 -1
- package/dist/esm/internal/layer.js +0 -2
- package/dist/esm/internal/layer.js.map +1 -1
- package/dist/esm/internal/logger.js +25 -2
- package/dist/esm/internal/logger.js.map +1 -1
- package/dist/esm/internal/runtimeFlags.js +1 -9
- package/dist/esm/internal/runtimeFlags.js.map +1 -1
- package/dist/esm/internal/tracer.js +0 -111
- package/dist/esm/internal/tracer.js.map +1 -1
- package/package.json +12 -1
- package/src/Arbitrary.ts +1101 -0
- package/src/Array.ts +3589 -0
- package/src/BigDecimal.ts +1349 -0
- package/src/BigInt.ts +643 -0
- package/src/Boolean.ts +287 -0
- package/src/Brand.ts +360 -0
- package/src/Cache.ts +281 -0
- package/src/Cause.ts +1555 -0
- package/src/Channel.ts +2355 -0
- package/src/ChildExecutorDecision.ts +146 -0
- package/src/Chunk.ts +1495 -0
- package/src/Clock.ts +111 -0
- package/src/Config.ts +542 -0
- package/src/ConfigError.ts +270 -0
- package/src/ConfigProvider.ts +333 -0
- package/src/ConfigProviderPathPatch.ts +100 -0
- package/src/Console.ts +226 -0
- package/src/Context.ts +585 -0
- package/src/Cron.ts +706 -0
- package/src/Data.ts +596 -0
- package/src/DateTime.ts +1686 -0
- package/src/DefaultServices.ts +34 -0
- package/src/Deferred.ts +301 -0
- package/src/Differ.ts +450 -0
- package/src/Duration.ts +1000 -0
- package/src/Effect.ts +14817 -0
- package/src/Effectable.ts +107 -0
- package/src/Either.ts +1040 -0
- package/src/Encoding.ts +195 -0
- package/src/Equal.ts +98 -0
- package/src/Equivalence.ts +235 -0
- package/src/ExecutionPlan.ts +308 -0
- package/src/ExecutionStrategy.ts +119 -0
- package/src/Exit.ts +467 -0
- package/src/FastCheck.ts +9 -0
- package/src/Fiber.ts +744 -0
- package/src/FiberHandle.ts +540 -0
- package/src/FiberId.ts +195 -0
- package/src/FiberMap.ts +656 -0
- package/src/FiberRef.ts +444 -0
- package/src/FiberRefs.ts +204 -0
- package/src/FiberRefsPatch.ts +105 -0
- package/src/FiberSet.ts +491 -0
- package/src/FiberStatus.ts +108 -0
- package/src/Function.ts +1222 -0
- package/src/GlobalValue.ts +53 -0
- package/src/Graph.ts +3732 -0
- package/src/GroupBy.ts +103 -0
- package/src/HKT.ts +45 -0
- package/src/Hash.ts +195 -0
- package/src/HashMap.ts +519 -0
- package/src/HashRing.ts +317 -0
- package/src/HashSet.ts +2346 -0
- package/src/Inspectable.ts +287 -0
- package/src/Iterable.ts +1119 -0
- package/src/JSONSchema.ts +1044 -0
- package/src/KeyedPool.ts +167 -0
- package/src/Layer.ts +1228 -0
- package/src/LayerMap.ts +436 -0
- package/src/List.ts +977 -0
- package/src/LogLevel.ts +285 -0
- package/src/LogSpan.ts +25 -0
- package/src/Logger.ts +702 -0
- package/src/Mailbox.ts +268 -0
- package/src/ManagedRuntime.ts +180 -0
- package/src/Match.ts +1477 -0
- package/src/MergeDecision.ts +95 -0
- package/src/MergeState.ts +172 -0
- package/src/MergeStrategy.ts +107 -0
- package/src/Metric.ts +780 -0
- package/src/MetricBoundaries.ts +69 -0
- package/src/MetricHook.ts +151 -0
- package/src/MetricKey.ts +224 -0
- package/src/MetricKeyType.ts +262 -0
- package/src/MetricLabel.ts +47 -0
- package/src/MetricPair.ts +71 -0
- package/src/MetricPolling.ts +148 -0
- package/src/MetricRegistry.ts +48 -0
- package/src/MetricState.ts +257 -0
- package/src/Micro.ts +4405 -0
- package/src/ModuleVersion.ts +18 -0
- package/src/MutableHashMap.ts +411 -0
- package/src/MutableHashSet.ts +706 -0
- package/src/MutableList.ts +297 -0
- package/src/MutableQueue.ts +227 -0
- package/src/MutableRef.ts +202 -0
- package/src/NonEmptyIterable.ts +32 -0
- package/src/Number.ts +1071 -0
- package/src/Option.ts +2170 -0
- package/src/Order.ts +373 -0
- package/src/Ordering.ts +111 -0
- package/src/ParseResult.ts +2031 -0
- package/src/PartitionedSemaphore.ts +200 -0
- package/src/Pipeable.ts +566 -0
- package/src/Pool.ts +204 -0
- package/src/Predicate.ts +1405 -0
- package/src/Pretty.ts +205 -0
- package/src/PrimaryKey.ts +23 -0
- package/src/PubSub.ts +182 -0
- package/src/Queue.ts +644 -0
- package/src/Random.ts +204 -0
- package/src/RateLimiter.ts +138 -0
- package/src/RcMap.ts +141 -0
- package/src/RcRef.ts +122 -0
- package/src/Readable.ts +93 -0
- package/src/Record.ts +1274 -0
- package/src/RedBlackTree.ts +421 -0
- package/src/Redacted.ts +144 -0
- package/src/Ref.ts +180 -0
- package/src/RegExp.ts +38 -0
- package/src/Reloadable.ts +127 -0
- package/src/Request.ts +347 -0
- package/src/RequestBlock.ts +118 -0
- package/src/RequestResolver.ts +366 -0
- package/src/Resource.ts +119 -0
- package/src/Runtime.ts +383 -0
- package/src/RuntimeFlags.ts +336 -0
- package/src/RuntimeFlagsPatch.ts +183 -0
- package/src/STM.ts +2045 -0
- package/src/Schedule.ts +2219 -0
- package/src/ScheduleDecision.ts +62 -0
- package/src/ScheduleInterval.ts +151 -0
- package/src/ScheduleIntervals.ts +122 -0
- package/src/Scheduler.ts +353 -0
- package/src/Schema.ts +10914 -0
- package/src/SchemaAST.ts +3043 -0
- package/src/Scope.ts +204 -0
- package/src/ScopedCache.ts +151 -0
- package/src/ScopedRef.ts +117 -0
- package/src/Secret.ts +88 -0
- package/src/SingleProducerAsyncInput.ts +67 -0
- package/src/Sink.ts +1461 -0
- package/src/SortedMap.ts +287 -0
- package/src/SortedSet.ts +390 -0
- package/src/SourceLocation.ts +108 -0
- package/src/Stream.ts +6468 -0
- package/src/StreamEmit.ts +136 -0
- package/src/StreamHaltStrategy.ts +123 -0
- package/src/Streamable.ts +45 -0
- package/src/String.ts +778 -0
- package/src/Struct.ts +243 -0
- package/src/Subscribable.ts +100 -0
- package/src/SubscriptionRef.ts +298 -0
- package/src/Supervisor.ts +240 -0
- package/src/Symbol.ts +29 -0
- package/src/SynchronizedRef.ts +270 -0
- package/src/TArray.ts +495 -0
- package/src/TDeferred.ts +100 -0
- package/src/TMap.ts +515 -0
- package/src/TPriorityQueue.ts +223 -0
- package/src/TPubSub.ts +200 -0
- package/src/TQueue.ts +432 -0
- package/src/TRandom.ts +129 -0
- package/src/TReentrantLock.ts +224 -0
- package/src/TRef.ts +178 -0
- package/src/TSemaphore.ts +129 -0
- package/src/TSet.ts +365 -0
- package/src/TSubscriptionRef.ts +192 -0
- package/src/Take.ts +258 -0
- package/src/TestAnnotation.ts +158 -0
- package/src/TestAnnotationMap.ts +119 -0
- package/src/TestAnnotations.ts +117 -0
- package/src/TestClock.ts +556 -0
- package/src/TestConfig.ts +47 -0
- package/src/TestContext.ts +36 -0
- package/src/TestLive.ts +53 -0
- package/src/TestServices.ts +390 -0
- package/src/TestSized.ts +55 -0
- package/src/Tracer.ts +182 -0
- package/src/Trie.ts +840 -0
- package/src/Tuple.ts +305 -0
- package/src/Types.ts +353 -0
- package/src/Unify.ts +113 -0
- package/src/UpstreamPullRequest.ts +117 -0
- package/src/UpstreamPullStrategy.ts +121 -0
- package/src/Utils.ts +809 -0
- package/src/index.ts +1568 -0
- package/src/internal/array.ts +8 -0
- package/src/internal/blockedRequests.ts +520 -0
- package/src/internal/cache.ts +733 -0
- package/src/internal/cause.ts +1050 -0
- package/src/internal/channel/channelExecutor.ts +1200 -0
- package/src/internal/channel/channelState.ts +134 -0
- package/src/internal/channel/childExecutorDecision.ts +96 -0
- package/src/internal/channel/continuation.ts +200 -0
- package/src/internal/channel/mergeDecision.ts +113 -0
- package/src/internal/channel/mergeState.ts +120 -0
- package/src/internal/channel/mergeStrategy.ts +72 -0
- package/src/internal/channel/singleProducerAsyncInput.ts +259 -0
- package/src/internal/channel/subexecutor.ts +229 -0
- package/src/internal/channel/upstreamPullRequest.ts +84 -0
- package/src/internal/channel/upstreamPullStrategy.ts +87 -0
- package/src/internal/channel.ts +2603 -0
- package/src/internal/clock.ts +95 -0
- package/src/internal/completedRequestMap.ts +9 -0
- package/src/internal/concurrency.ts +54 -0
- package/src/internal/config.ts +716 -0
- package/src/internal/configError.ts +304 -0
- package/src/internal/configProvider/pathPatch.ts +97 -0
- package/src/internal/configProvider.ts +799 -0
- package/src/internal/console.ts +153 -0
- package/src/internal/context.ts +337 -0
- package/src/internal/core-effect.ts +2293 -0
- package/src/internal/core-stream.ts +998 -0
- package/src/internal/core.ts +3189 -0
- package/src/internal/data.ts +36 -0
- package/src/internal/dataSource.ts +327 -0
- package/src/internal/dateTime.ts +1277 -0
- package/src/internal/defaultServices/console.ts +100 -0
- package/src/internal/defaultServices.ts +163 -0
- package/src/internal/deferred.ts +46 -0
- package/src/internal/differ/chunkPatch.ts +211 -0
- package/src/internal/differ/contextPatch.ts +232 -0
- package/src/internal/differ/hashMapPatch.ts +220 -0
- package/src/internal/differ/hashSetPatch.ts +176 -0
- package/src/internal/differ/orPatch.ts +311 -0
- package/src/internal/differ/readonlyArrayPatch.ts +210 -0
- package/src/internal/differ.ts +200 -0
- package/src/internal/doNotation.ts +80 -0
- package/src/internal/effect/circular.ts +895 -0
- package/src/internal/effectable.ts +131 -0
- package/src/internal/either.ts +110 -0
- package/src/internal/encoding/base64.ts +286 -0
- package/src/internal/encoding/base64Url.ts +29 -0
- package/src/internal/encoding/common.ts +51 -0
- package/src/internal/encoding/hex.ts +315 -0
- package/src/internal/errors.ts +7 -0
- package/src/internal/executionPlan.ts +114 -0
- package/src/internal/executionStrategy.ts +74 -0
- package/src/internal/fiber.ts +388 -0
- package/src/internal/fiberId.ts +267 -0
- package/src/internal/fiberMessage.ts +82 -0
- package/src/internal/fiberRefs/patch.ts +144 -0
- package/src/internal/fiberRefs.ts +297 -0
- package/src/internal/fiberRuntime.ts +3842 -0
- package/src/internal/fiberScope.ts +71 -0
- package/src/internal/fiberStatus.ts +119 -0
- package/src/internal/groupBy.ts +530 -0
- package/src/internal/hashMap/array.ts +49 -0
- package/src/internal/hashMap/bitwise.ts +32 -0
- package/src/internal/hashMap/config.ts +14 -0
- package/src/internal/hashMap/keySet.ts +8 -0
- package/src/internal/hashMap/node.ts +391 -0
- package/src/internal/hashMap.ts +586 -0
- package/src/internal/hashSet.ts +323 -0
- package/src/internal/keyedPool.ts +244 -0
- package/src/internal/layer/circular.ts +214 -0
- package/src/internal/layer.ts +1483 -0
- package/src/internal/logSpan.ts +20 -0
- package/src/internal/logger-circular.ts +24 -0
- package/src/internal/logger.ts +522 -0
- package/src/internal/mailbox.ts +561 -0
- package/src/internal/managedRuntime/circular.ts +6 -0
- package/src/internal/managedRuntime.ts +134 -0
- package/src/internal/matcher.ts +652 -0
- package/src/internal/metric/boundaries.ts +75 -0
- package/src/internal/metric/hook.ts +483 -0
- package/src/internal/metric/key.ts +167 -0
- package/src/internal/metric/keyType.ts +238 -0
- package/src/internal/metric/label.ts +41 -0
- package/src/internal/metric/pair.ts +48 -0
- package/src/internal/metric/polling.ts +149 -0
- package/src/internal/metric/registry.ts +187 -0
- package/src/internal/metric/state.ts +290 -0
- package/src/internal/metric.ts +577 -0
- package/src/internal/opCodes/cause.ts +35 -0
- package/src/internal/opCodes/channel.ts +83 -0
- package/src/internal/opCodes/channelChildExecutorDecision.ts +17 -0
- package/src/internal/opCodes/channelMergeDecision.ts +11 -0
- package/src/internal/opCodes/channelMergeState.ts +17 -0
- package/src/internal/opCodes/channelMergeStrategy.ts +11 -0
- package/src/internal/opCodes/channelState.ts +23 -0
- package/src/internal/opCodes/channelUpstreamPullRequest.ts +11 -0
- package/src/internal/opCodes/channelUpstreamPullStrategy.ts +11 -0
- package/src/internal/opCodes/config.ts +65 -0
- package/src/internal/opCodes/configError.ts +35 -0
- package/src/internal/opCodes/continuation.ts +11 -0
- package/src/internal/opCodes/deferred.ts +11 -0
- package/src/internal/opCodes/effect.ts +89 -0
- package/src/internal/opCodes/layer.ts +59 -0
- package/src/internal/opCodes/streamHaltStrategy.ts +23 -0
- package/src/internal/option.ts +80 -0
- package/src/internal/pool.ts +432 -0
- package/src/internal/pubsub.ts +1762 -0
- package/src/internal/query.ts +204 -0
- package/src/internal/queue.ts +766 -0
- package/src/internal/random.ts +161 -0
- package/src/internal/rateLimiter.ts +93 -0
- package/src/internal/rcMap.ts +285 -0
- package/src/internal/rcRef.ts +192 -0
- package/src/internal/redBlackTree/iterator.ts +200 -0
- package/src/internal/redBlackTree/node.ts +68 -0
- package/src/internal/redBlackTree.ts +1245 -0
- package/src/internal/redacted.ts +73 -0
- package/src/internal/ref.ts +171 -0
- package/src/internal/reloadable.ts +140 -0
- package/src/internal/request.ts +177 -0
- package/src/internal/resource.ts +76 -0
- package/src/internal/ringBuffer.ts +68 -0
- package/src/internal/runtime.ts +558 -0
- package/src/internal/runtimeFlags.ts +178 -0
- package/src/internal/runtimeFlagsPatch.ts +103 -0
- package/src/internal/schedule/decision.ts +47 -0
- package/src/internal/schedule/interval.ts +101 -0
- package/src/internal/schedule/intervals.ts +180 -0
- package/src/internal/schedule.ts +2199 -0
- package/src/internal/schema/errors.ts +191 -0
- package/src/internal/schema/schemaId.ts +106 -0
- package/src/internal/schema/util.ts +50 -0
- package/src/internal/scopedCache.ts +644 -0
- package/src/internal/scopedRef.ts +118 -0
- package/src/internal/secret.ts +89 -0
- package/src/internal/singleShotGen.ts +35 -0
- package/src/internal/sink.ts +2120 -0
- package/src/internal/stack.ts +10 -0
- package/src/internal/stm/core.ts +817 -0
- package/src/internal/stm/entry.ts +59 -0
- package/src/internal/stm/journal.ts +123 -0
- package/src/internal/stm/opCodes/stm.ts +71 -0
- package/src/internal/stm/opCodes/stmState.ts +17 -0
- package/src/internal/stm/opCodes/strategy.ts +17 -0
- package/src/internal/stm/opCodes/tExit.ts +29 -0
- package/src/internal/stm/opCodes/tryCommit.ts +11 -0
- package/src/internal/stm/stm.ts +1453 -0
- package/src/internal/stm/stmState.ts +136 -0
- package/src/internal/stm/tArray.ts +550 -0
- package/src/internal/stm/tDeferred.ts +81 -0
- package/src/internal/stm/tExit.ts +190 -0
- package/src/internal/stm/tMap.ts +824 -0
- package/src/internal/stm/tPriorityQueue.ts +267 -0
- package/src/internal/stm/tPubSub.ts +551 -0
- package/src/internal/stm/tQueue.ts +393 -0
- package/src/internal/stm/tRandom.ts +140 -0
- package/src/internal/stm/tReentrantLock.ts +352 -0
- package/src/internal/stm/tRef.ts +195 -0
- package/src/internal/stm/tSemaphore.ts +113 -0
- package/src/internal/stm/tSet.ts +259 -0
- package/src/internal/stm/tSubscriptionRef.ts +286 -0
- package/src/internal/stm/tryCommit.ts +34 -0
- package/src/internal/stm/txnId.ts +14 -0
- package/src/internal/stm/versioned.ts +4 -0
- package/src/internal/stream/debounceState.ts +57 -0
- package/src/internal/stream/emit.ts +123 -0
- package/src/internal/stream/haltStrategy.ts +94 -0
- package/src/internal/stream/handoff.ts +187 -0
- package/src/internal/stream/handoffSignal.ts +59 -0
- package/src/internal/stream/pull.ts +34 -0
- package/src/internal/stream/sinkEndReason.ts +30 -0
- package/src/internal/stream/zipAllState.ts +88 -0
- package/src/internal/stream/zipChunksState.ts +56 -0
- package/src/internal/stream.ts +8801 -0
- package/src/internal/string-utils.ts +107 -0
- package/src/internal/subscriptionRef.ts +138 -0
- package/src/internal/supervisor/patch.ts +190 -0
- package/src/internal/supervisor.ts +303 -0
- package/src/internal/synchronizedRef.ts +114 -0
- package/src/internal/take.ts +199 -0
- package/src/internal/testing/sleep.ts +27 -0
- package/src/internal/testing/suspendedWarningData.ts +85 -0
- package/src/internal/testing/warningData.ts +94 -0
- package/src/internal/tracer.ts +150 -0
- package/src/internal/trie.ts +722 -0
- package/src/internal/version.ts +7 -0
|
@@ -0,0 +1,1044 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since 3.10.0
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import * as Arr from "./Array.js"
|
|
6
|
+
import * as errors_ from "./internal/schema/errors.js"
|
|
7
|
+
import * as schemaId_ from "./internal/schema/schemaId.js"
|
|
8
|
+
import * as Option from "./Option.js"
|
|
9
|
+
import * as ParseResult from "./ParseResult.js"
|
|
10
|
+
import * as Predicate from "./Predicate.js"
|
|
11
|
+
import * as Record from "./Record.js"
|
|
12
|
+
import type * as Schema from "./Schema.js"
|
|
13
|
+
import * as AST from "./SchemaAST.js"
|
|
14
|
+
|
|
15
|
+
type JsonValue = string | number | boolean | null | Array<JsonValue> | { [key: string]: JsonValue }
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @category model
|
|
19
|
+
* @since 3.10.0
|
|
20
|
+
*/
|
|
21
|
+
export interface JsonSchemaAnnotations {
|
|
22
|
+
title?: string
|
|
23
|
+
description?: string
|
|
24
|
+
default?: JsonValue
|
|
25
|
+
examples?: Array<JsonValue>
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @category model
|
|
30
|
+
* @since 3.11.5
|
|
31
|
+
*/
|
|
32
|
+
export interface JsonSchema7Never extends JsonSchemaAnnotations {
|
|
33
|
+
$id: "/schemas/never"
|
|
34
|
+
not: {}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @category model
|
|
39
|
+
* @since 3.10.0
|
|
40
|
+
*/
|
|
41
|
+
export interface JsonSchema7Any extends JsonSchemaAnnotations {
|
|
42
|
+
$id: "/schemas/any"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @category model
|
|
47
|
+
* @since 3.10.0
|
|
48
|
+
*/
|
|
49
|
+
export interface JsonSchema7Unknown extends JsonSchemaAnnotations {
|
|
50
|
+
$id: "/schemas/unknown"
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @category model
|
|
55
|
+
* @since 3.10.0
|
|
56
|
+
*/
|
|
57
|
+
export interface JsonSchema7Void extends JsonSchemaAnnotations {
|
|
58
|
+
$id: "/schemas/void"
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @category model
|
|
63
|
+
* @since 3.10.0
|
|
64
|
+
*/
|
|
65
|
+
export interface JsonSchema7object extends JsonSchemaAnnotations {
|
|
66
|
+
$id: "/schemas/object"
|
|
67
|
+
anyOf: [
|
|
68
|
+
{ type: "object" },
|
|
69
|
+
{ type: "array" }
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @category model
|
|
75
|
+
* @since 3.10.0
|
|
76
|
+
*/
|
|
77
|
+
export interface JsonSchema7empty extends JsonSchemaAnnotations {
|
|
78
|
+
$id: "/schemas/%7B%7D"
|
|
79
|
+
anyOf: [
|
|
80
|
+
{ type: "object" },
|
|
81
|
+
{ type: "array" }
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @category model
|
|
87
|
+
* @since 3.10.0
|
|
88
|
+
*/
|
|
89
|
+
export interface JsonSchema7Ref extends JsonSchemaAnnotations {
|
|
90
|
+
$ref: string
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @category model
|
|
95
|
+
* @since 3.11.7
|
|
96
|
+
*/
|
|
97
|
+
export interface JsonSchema7Null extends JsonSchemaAnnotations {
|
|
98
|
+
type: "null"
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @category model
|
|
103
|
+
* @since 3.10.0
|
|
104
|
+
*/
|
|
105
|
+
export interface JsonSchema7String extends JsonSchemaAnnotations {
|
|
106
|
+
type: "string"
|
|
107
|
+
minLength?: number
|
|
108
|
+
maxLength?: number
|
|
109
|
+
pattern?: string
|
|
110
|
+
format?: string
|
|
111
|
+
contentMediaType?: string
|
|
112
|
+
allOf?: Array<{
|
|
113
|
+
minLength?: number
|
|
114
|
+
maxLength?: number
|
|
115
|
+
pattern?: string
|
|
116
|
+
}>
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @category model
|
|
121
|
+
* @since 3.10.0
|
|
122
|
+
*/
|
|
123
|
+
export interface JsonSchema7Numeric extends JsonSchemaAnnotations {
|
|
124
|
+
minimum?: number
|
|
125
|
+
exclusiveMinimum?: number
|
|
126
|
+
maximum?: number
|
|
127
|
+
exclusiveMaximum?: number
|
|
128
|
+
multipleOf?: number
|
|
129
|
+
allOf?: Array<{
|
|
130
|
+
minimum?: number
|
|
131
|
+
exclusiveMinimum?: number
|
|
132
|
+
maximum?: number
|
|
133
|
+
exclusiveMaximum?: number
|
|
134
|
+
multipleOf?: number
|
|
135
|
+
}>
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @category model
|
|
140
|
+
* @since 3.10.0
|
|
141
|
+
*/
|
|
142
|
+
export interface JsonSchema7Number extends JsonSchema7Numeric {
|
|
143
|
+
type: "number"
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* @category model
|
|
148
|
+
* @since 3.10.0
|
|
149
|
+
*/
|
|
150
|
+
export interface JsonSchema7Integer extends JsonSchema7Numeric {
|
|
151
|
+
type: "integer"
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @category model
|
|
156
|
+
* @since 3.10.0
|
|
157
|
+
*/
|
|
158
|
+
export interface JsonSchema7Boolean extends JsonSchemaAnnotations {
|
|
159
|
+
type: "boolean"
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* @category model
|
|
164
|
+
* @since 3.10.0
|
|
165
|
+
*/
|
|
166
|
+
export interface JsonSchema7Array extends JsonSchemaAnnotations {
|
|
167
|
+
type: "array"
|
|
168
|
+
items?: JsonSchema7 | Array<JsonSchema7> | false
|
|
169
|
+
prefixItems?: Array<JsonSchema7>
|
|
170
|
+
minItems?: number
|
|
171
|
+
maxItems?: number
|
|
172
|
+
additionalItems?: JsonSchema7 | boolean
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* @category model
|
|
177
|
+
* @since 3.10.0
|
|
178
|
+
*/
|
|
179
|
+
export interface JsonSchema7Enum extends JsonSchemaAnnotations {
|
|
180
|
+
type?: "string" | "number" | "boolean"
|
|
181
|
+
enum: Array<string | number | boolean>
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* @category model
|
|
186
|
+
* @since 3.10.0
|
|
187
|
+
*/
|
|
188
|
+
export interface JsonSchema7Enums extends JsonSchemaAnnotations {
|
|
189
|
+
$comment: "/schemas/enums"
|
|
190
|
+
anyOf: Array<{
|
|
191
|
+
type: "string" | "number"
|
|
192
|
+
title: string
|
|
193
|
+
enum: [string | number]
|
|
194
|
+
}>
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* @category model
|
|
199
|
+
* @since 3.10.0
|
|
200
|
+
*/
|
|
201
|
+
export interface JsonSchema7AnyOf extends JsonSchemaAnnotations {
|
|
202
|
+
anyOf: Array<JsonSchema7>
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* @category model
|
|
207
|
+
* @since 3.10.0
|
|
208
|
+
*/
|
|
209
|
+
export interface JsonSchema7Object extends JsonSchemaAnnotations {
|
|
210
|
+
type: "object"
|
|
211
|
+
required: Array<string>
|
|
212
|
+
properties: Record<string, JsonSchema7>
|
|
213
|
+
additionalProperties?: boolean | JsonSchema7
|
|
214
|
+
patternProperties?: Record<string, JsonSchema7>
|
|
215
|
+
propertyNames?: JsonSchema7
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* @category model
|
|
220
|
+
* @since 3.10.0
|
|
221
|
+
*/
|
|
222
|
+
export type JsonSchema7 =
|
|
223
|
+
| JsonSchema7Never
|
|
224
|
+
| JsonSchema7Any
|
|
225
|
+
| JsonSchema7Unknown
|
|
226
|
+
| JsonSchema7Void
|
|
227
|
+
| JsonSchema7object
|
|
228
|
+
| JsonSchema7empty
|
|
229
|
+
| JsonSchema7Ref
|
|
230
|
+
| JsonSchema7Null
|
|
231
|
+
| JsonSchema7String
|
|
232
|
+
| JsonSchema7Number
|
|
233
|
+
| JsonSchema7Integer
|
|
234
|
+
| JsonSchema7Boolean
|
|
235
|
+
| JsonSchema7Array
|
|
236
|
+
| JsonSchema7Enum
|
|
237
|
+
| JsonSchema7Enums
|
|
238
|
+
| JsonSchema7AnyOf
|
|
239
|
+
| JsonSchema7Object
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* @category model
|
|
243
|
+
* @since 3.10.0
|
|
244
|
+
*/
|
|
245
|
+
export type JsonSchema7Root = JsonSchema7 & {
|
|
246
|
+
$schema?: string
|
|
247
|
+
$defs?: Record<string, JsonSchema7>
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Generates a JSON Schema from a schema.
|
|
252
|
+
*
|
|
253
|
+
* **Options**
|
|
254
|
+
*
|
|
255
|
+
* - `target`: The target JSON Schema version. Possible values are:
|
|
256
|
+
* - `"jsonSchema7"`: JSON Schema draft-07 (default behavior).
|
|
257
|
+
* - `"jsonSchema2019-09"`: JSON Schema draft-2019-09.
|
|
258
|
+
* - `"jsonSchema2020-12"`: JSON Schema draft-2020-12.
|
|
259
|
+
* - `"openApi3.1"`: OpenAPI 3.1.
|
|
260
|
+
*
|
|
261
|
+
* @category encoding
|
|
262
|
+
* @since 3.10.0
|
|
263
|
+
*/
|
|
264
|
+
export const make = <A, I, R>(schema: Schema.Schema<A, I, R>, options?: {
|
|
265
|
+
readonly target?: Target | undefined
|
|
266
|
+
}): JsonSchema7Root => {
|
|
267
|
+
const definitions: Record<string, any> = {}
|
|
268
|
+
const target = options?.target ?? "jsonSchema7"
|
|
269
|
+
const ast = AST.isTransformation(schema.ast) && isParseJsonTransformation(schema.ast.from)
|
|
270
|
+
// Special case top level `parseJson` transformations
|
|
271
|
+
? schema.ast.to
|
|
272
|
+
: schema.ast
|
|
273
|
+
const jsonSchema = fromAST(ast, {
|
|
274
|
+
definitions,
|
|
275
|
+
target
|
|
276
|
+
})
|
|
277
|
+
const out: JsonSchema7Root = {
|
|
278
|
+
$schema: getMetaSchemaUri(target),
|
|
279
|
+
$defs: {},
|
|
280
|
+
...jsonSchema
|
|
281
|
+
}
|
|
282
|
+
if (Record.isEmptyRecord(definitions)) {
|
|
283
|
+
delete out.$defs
|
|
284
|
+
} else {
|
|
285
|
+
out.$defs = definitions
|
|
286
|
+
}
|
|
287
|
+
return out
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
type Target = "jsonSchema7" | "jsonSchema2019-09" | "openApi3.1" | "jsonSchema2020-12"
|
|
291
|
+
|
|
292
|
+
type TopLevelReferenceStrategy = "skip" | "keep"
|
|
293
|
+
|
|
294
|
+
type AdditionalPropertiesStrategy = "allow" | "strict"
|
|
295
|
+
|
|
296
|
+
/** @internal */
|
|
297
|
+
export function getMetaSchemaUri(target: Target) {
|
|
298
|
+
switch (target) {
|
|
299
|
+
case "jsonSchema7":
|
|
300
|
+
return "http://json-schema.org/draft-07/schema#"
|
|
301
|
+
case "jsonSchema2019-09":
|
|
302
|
+
return "https://json-schema.org/draft/2019-09/schema"
|
|
303
|
+
case "jsonSchema2020-12":
|
|
304
|
+
case "openApi3.1":
|
|
305
|
+
return "https://json-schema.org/draft/2020-12/schema"
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Returns a JSON Schema with additional options and definitions.
|
|
311
|
+
*
|
|
312
|
+
* **Warning**
|
|
313
|
+
*
|
|
314
|
+
* This function is experimental and subject to change.
|
|
315
|
+
*
|
|
316
|
+
* **Options**
|
|
317
|
+
*
|
|
318
|
+
* - `definitions`: A record of definitions that are included in the schema.
|
|
319
|
+
* - `definitionPath`: The path to the definitions within the schema (defaults
|
|
320
|
+
* to "#/$defs/").
|
|
321
|
+
* - `target`: Which spec to target. Possible values are:
|
|
322
|
+
* - `'jsonSchema7'`: JSON Schema draft-07 (default behavior).
|
|
323
|
+
* - `'jsonSchema2019-09'`: JSON Schema draft-2019-09.
|
|
324
|
+
* - `'openApi3.1'`: OpenAPI 3.1.
|
|
325
|
+
* - `topLevelReferenceStrategy`: Controls the handling of the top-level
|
|
326
|
+
* reference. Possible values are:
|
|
327
|
+
* - `"keep"`: Keep the top-level reference (default behavior).
|
|
328
|
+
* - `"skip"`: Skip the top-level reference.
|
|
329
|
+
* - `additionalPropertiesStrategy`: Controls the handling of additional properties. Possible values are:
|
|
330
|
+
* - `"strict"`: Disallow additional properties (default behavior).
|
|
331
|
+
* - `"allow"`: Allow additional properties.
|
|
332
|
+
*
|
|
333
|
+
* @category encoding
|
|
334
|
+
* @since 3.11.5
|
|
335
|
+
* @experimental
|
|
336
|
+
*/
|
|
337
|
+
export const fromAST = (ast: AST.AST, options: {
|
|
338
|
+
readonly definitions: Record<string, JsonSchema7>
|
|
339
|
+
readonly definitionPath?: string | undefined
|
|
340
|
+
readonly target?: Target | undefined
|
|
341
|
+
readonly topLevelReferenceStrategy?: TopLevelReferenceStrategy | undefined
|
|
342
|
+
readonly additionalPropertiesStrategy?: AdditionalPropertiesStrategy | undefined
|
|
343
|
+
}): JsonSchema7 => {
|
|
344
|
+
const definitionPath = options.definitionPath ?? "#/$defs/"
|
|
345
|
+
const getRef = (id: string) => definitionPath + id
|
|
346
|
+
const target = options.target ?? "jsonSchema7"
|
|
347
|
+
const topLevelReferenceStrategy = options.topLevelReferenceStrategy ?? "keep"
|
|
348
|
+
const additionalPropertiesStrategy = options.additionalPropertiesStrategy ?? "strict"
|
|
349
|
+
return go(
|
|
350
|
+
ast,
|
|
351
|
+
options.definitions,
|
|
352
|
+
"handle-identifier",
|
|
353
|
+
[],
|
|
354
|
+
{
|
|
355
|
+
getRef,
|
|
356
|
+
target,
|
|
357
|
+
topLevelReferenceStrategy,
|
|
358
|
+
additionalPropertiesStrategy
|
|
359
|
+
},
|
|
360
|
+
"handle-annotation",
|
|
361
|
+
"handle-errors"
|
|
362
|
+
)
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const constNever: JsonSchema7Never = {
|
|
366
|
+
$id: "/schemas/never",
|
|
367
|
+
not: {}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
const constAny: JsonSchema7Any = {
|
|
371
|
+
$id: "/schemas/any"
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
const constUnknown: JsonSchema7Unknown = {
|
|
375
|
+
$id: "/schemas/unknown"
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
const constVoid: JsonSchema7Void = {
|
|
379
|
+
$id: "/schemas/void"
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
const constObject: JsonSchema7object = {
|
|
383
|
+
$id: "/schemas/object",
|
|
384
|
+
"anyOf": [
|
|
385
|
+
{ "type": "object" },
|
|
386
|
+
{ "type": "array" }
|
|
387
|
+
]
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
const constEmptyStruct: JsonSchema7empty = {
|
|
391
|
+
$id: "/schemas/%7B%7D",
|
|
392
|
+
"anyOf": [
|
|
393
|
+
{ "type": "object" },
|
|
394
|
+
{ "type": "array" }
|
|
395
|
+
]
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
function getRawDescription(annotated: AST.Annotated | undefined): string | undefined {
|
|
399
|
+
if (annotated !== undefined) return Option.getOrUndefined(AST.getDescriptionAnnotation(annotated))
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
function getRawTitle(annotated: AST.Annotated | undefined): string | undefined {
|
|
403
|
+
if (annotated !== undefined) return Option.getOrUndefined(AST.getTitleAnnotation(annotated))
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
function getRawDefault(annotated: AST.Annotated | undefined): Option.Option<unknown> {
|
|
407
|
+
if (annotated !== undefined) return AST.getDefaultAnnotation(annotated)
|
|
408
|
+
return Option.none()
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
function encodeDefault(ast: AST.AST, def: unknown): Option.Option<unknown> {
|
|
412
|
+
const getOption = ParseResult.getOption(ast, false)
|
|
413
|
+
return getOption(def)
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
function getRawExamples(annotated: AST.Annotated | undefined): ReadonlyArray<unknown> | undefined {
|
|
417
|
+
if (annotated !== undefined) return Option.getOrUndefined(AST.getExamplesAnnotation(annotated))
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
function encodeExamples(ast: AST.AST, examples: ReadonlyArray<unknown>): Array<JsonValue> | undefined {
|
|
421
|
+
const getOption = ParseResult.getOption(ast, false)
|
|
422
|
+
const out = Arr.filterMap(examples, (e) => getOption(e).pipe(Option.filter(isJsonValue)))
|
|
423
|
+
return out.length > 0 ? out : undefined
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
function filterBuiltIn(ast: AST.AST, annotation: string | undefined, key: symbol): string | undefined {
|
|
427
|
+
if (annotation !== undefined) {
|
|
428
|
+
switch (ast._tag) {
|
|
429
|
+
case "StringKeyword":
|
|
430
|
+
return annotation !== AST.stringKeyword.annotations[key] ? annotation : undefined
|
|
431
|
+
case "NumberKeyword":
|
|
432
|
+
return annotation !== AST.numberKeyword.annotations[key] ? annotation : undefined
|
|
433
|
+
case "BooleanKeyword":
|
|
434
|
+
return annotation !== AST.booleanKeyword.annotations[key] ? annotation : undefined
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
return annotation
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
function isJsonValue(value: unknown, visited: Set<unknown> = new Set()): value is JsonValue {
|
|
441
|
+
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
442
|
+
return true
|
|
443
|
+
}
|
|
444
|
+
if (Array.isArray(value) || typeof value === "object") {
|
|
445
|
+
// Check for cyclic references
|
|
446
|
+
if (visited.has(value)) {
|
|
447
|
+
return false
|
|
448
|
+
}
|
|
449
|
+
visited.add(value)
|
|
450
|
+
try {
|
|
451
|
+
if (Array.isArray(value)) {
|
|
452
|
+
return value.every((item) => isJsonValue(item, visited))
|
|
453
|
+
}
|
|
454
|
+
// Exclude non-plain objects (Date, RegExp, etc.) by checking constructor
|
|
455
|
+
const proto = Object.getPrototypeOf(value)
|
|
456
|
+
if (proto !== null && proto !== Object.prototype) {
|
|
457
|
+
return false
|
|
458
|
+
}
|
|
459
|
+
// JSON only allows string keys, so exclude objects with Symbol keys
|
|
460
|
+
if (Object.getOwnPropertySymbols(value).length > 0) {
|
|
461
|
+
return false
|
|
462
|
+
}
|
|
463
|
+
// Check all values are JSON values
|
|
464
|
+
return Object.values(value).every((v) => isJsonValue(v, visited))
|
|
465
|
+
} finally {
|
|
466
|
+
visited.delete(value)
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
return false
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
function pruneJsonSchemaAnnotations(
|
|
473
|
+
ast: AST.AST,
|
|
474
|
+
description: string | undefined,
|
|
475
|
+
title: string | undefined,
|
|
476
|
+
def: Option.Option<unknown>,
|
|
477
|
+
examples: ReadonlyArray<unknown> | undefined
|
|
478
|
+
): JsonSchemaAnnotations | undefined {
|
|
479
|
+
const out: JsonSchemaAnnotations = {}
|
|
480
|
+
if (description !== undefined) out.description = description
|
|
481
|
+
if (title !== undefined) out.title = title
|
|
482
|
+
if (Option.isSome(def)) {
|
|
483
|
+
const o = encodeDefault(ast, def.value)
|
|
484
|
+
if (Option.isSome(o) && isJsonValue(o.value)) {
|
|
485
|
+
out.default = o.value
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
if (examples !== undefined) {
|
|
489
|
+
const encodedExamples = encodeExamples(ast, examples)
|
|
490
|
+
if (encodedExamples !== undefined) {
|
|
491
|
+
out.examples = encodedExamples
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
if (Object.keys(out).length === 0) {
|
|
495
|
+
return undefined
|
|
496
|
+
}
|
|
497
|
+
return out
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
function getContextJsonSchemaAnnotations(ast: AST.AST, annotated: AST.Annotated): JsonSchemaAnnotations | undefined {
|
|
501
|
+
return pruneJsonSchemaAnnotations(
|
|
502
|
+
ast,
|
|
503
|
+
getRawDescription(annotated),
|
|
504
|
+
getRawTitle(annotated),
|
|
505
|
+
getRawDefault(annotated),
|
|
506
|
+
getRawExamples(annotated)
|
|
507
|
+
)
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
function getJsonSchemaAnnotations(ast: AST.AST): JsonSchemaAnnotations | undefined {
|
|
511
|
+
return pruneJsonSchemaAnnotations(
|
|
512
|
+
ast,
|
|
513
|
+
filterBuiltIn(ast, getRawDescription(ast), AST.DescriptionAnnotationId),
|
|
514
|
+
filterBuiltIn(ast, getRawTitle(ast), AST.TitleAnnotationId),
|
|
515
|
+
getRawDefault(ast),
|
|
516
|
+
getRawExamples(ast)
|
|
517
|
+
)
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
function mergeJsonSchemaAnnotations(
|
|
521
|
+
jsonSchema: JsonSchema7,
|
|
522
|
+
jsonSchemaAnnotations: JsonSchemaAnnotations | undefined
|
|
523
|
+
): JsonSchema7 {
|
|
524
|
+
if (jsonSchemaAnnotations) {
|
|
525
|
+
if ("$ref" in jsonSchema) {
|
|
526
|
+
return { allOf: [jsonSchema], ...jsonSchemaAnnotations } as any
|
|
527
|
+
}
|
|
528
|
+
return { ...jsonSchema, ...jsonSchemaAnnotations }
|
|
529
|
+
}
|
|
530
|
+
return jsonSchema
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
const pruneUndefined = (ast: AST.AST): AST.AST | undefined => {
|
|
534
|
+
if (Option.isNone(AST.getJSONSchemaAnnotation(ast))) {
|
|
535
|
+
return AST.pruneUndefined(ast, pruneUndefined, (ast) => pruneUndefined(ast.from))
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
const isParseJsonTransformation = (ast: AST.AST): boolean =>
|
|
540
|
+
ast.annotations[AST.SchemaIdAnnotationId] === AST.ParseJsonSchemaId
|
|
541
|
+
|
|
542
|
+
const isOverrideAnnotation = (ast: AST.AST, jsonSchema: JsonSchema7): boolean => {
|
|
543
|
+
if (AST.isRefinement(ast)) {
|
|
544
|
+
const schemaId = ast.annotations[AST.SchemaIdAnnotationId]
|
|
545
|
+
if (schemaId === schemaId_.IntSchemaId) {
|
|
546
|
+
return "type" in jsonSchema && jsonSchema.type !== "integer"
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
return ("type" in jsonSchema) || ("oneOf" in jsonSchema) || ("anyOf" in jsonSchema) || ("$ref" in jsonSchema)
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
const mergeRefinements = (from: any, jsonSchema: any, ast: AST.AST): any => {
|
|
553
|
+
const out: any = { ...from, ...getJsonSchemaAnnotations(ast), ...jsonSchema }
|
|
554
|
+
out.allOf ??= []
|
|
555
|
+
|
|
556
|
+
const handle = (name: string, filter: (i: any) => boolean) => {
|
|
557
|
+
if (name in jsonSchema && name in from) {
|
|
558
|
+
out.allOf.unshift({ [name]: from[name] })
|
|
559
|
+
out.allOf = out.allOf.filter(filter)
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
handle("minLength", (i) => i.minLength > jsonSchema.minLength)
|
|
564
|
+
handle("maxLength", (i) => i.maxLength < jsonSchema.maxLength)
|
|
565
|
+
handle("pattern", (i) => i.pattern !== jsonSchema.pattern)
|
|
566
|
+
handle("minItems", (i) => i.minItems > jsonSchema.minItems)
|
|
567
|
+
handle("maxItems", (i) => i.maxItems < jsonSchema.maxItems)
|
|
568
|
+
handle("minimum", (i) => i.minimum > jsonSchema.minimum)
|
|
569
|
+
handle("maximum", (i) => i.maximum < jsonSchema.maximum)
|
|
570
|
+
handle("exclusiveMinimum", (i) => i.exclusiveMinimum > jsonSchema.exclusiveMinimum)
|
|
571
|
+
handle("exclusiveMaximum", (i) => i.exclusiveMaximum < jsonSchema.exclusiveMaximum)
|
|
572
|
+
handle("multipleOf", (i) => i.multipleOf !== jsonSchema.multipleOf)
|
|
573
|
+
|
|
574
|
+
if (out.allOf.length === 0) {
|
|
575
|
+
delete out.allOf
|
|
576
|
+
}
|
|
577
|
+
return out
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
type GoOptions = {
|
|
581
|
+
readonly getRef: (id: string) => string
|
|
582
|
+
readonly target: Target
|
|
583
|
+
readonly topLevelReferenceStrategy: TopLevelReferenceStrategy
|
|
584
|
+
readonly additionalPropertiesStrategy: AdditionalPropertiesStrategy
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
function isContentSchemaSupported(options: GoOptions): boolean {
|
|
588
|
+
switch (options.target) {
|
|
589
|
+
case "jsonSchema7":
|
|
590
|
+
return false
|
|
591
|
+
case "jsonSchema2019-09":
|
|
592
|
+
case "jsonSchema2020-12":
|
|
593
|
+
case "openApi3.1":
|
|
594
|
+
return true
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
function getAdditionalProperties(options: GoOptions): boolean {
|
|
599
|
+
switch (options.additionalPropertiesStrategy) {
|
|
600
|
+
case "allow":
|
|
601
|
+
return true
|
|
602
|
+
case "strict":
|
|
603
|
+
return false
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
function addASTAnnotations(jsonSchema: JsonSchema7, ast: AST.AST): JsonSchema7 {
|
|
608
|
+
return addAnnotations(jsonSchema, getJsonSchemaAnnotations(ast))
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
function addAnnotations(jsonSchema: JsonSchema7, annotations: JsonSchemaAnnotations | undefined): JsonSchema7 {
|
|
612
|
+
if (annotations === undefined || Object.keys(annotations).length === 0) {
|
|
613
|
+
return jsonSchema
|
|
614
|
+
}
|
|
615
|
+
if ("$ref" in jsonSchema) {
|
|
616
|
+
return { allOf: [jsonSchema], ...annotations } as any
|
|
617
|
+
}
|
|
618
|
+
return { ...jsonSchema, ...annotations }
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
function getIdentifierAnnotation(ast: AST.AST): string | undefined {
|
|
622
|
+
const identifier = Option.getOrUndefined(AST.getJSONIdentifier(ast))
|
|
623
|
+
if (identifier === undefined) {
|
|
624
|
+
if (AST.isSuspend(ast)) {
|
|
625
|
+
return getIdentifierAnnotation(ast.f())
|
|
626
|
+
}
|
|
627
|
+
if (AST.isTransformation(ast) && AST.isTypeLiteral(ast.from) && AST.isDeclaration(ast.to)) {
|
|
628
|
+
const to = ast.to
|
|
629
|
+
const surrogate = AST.getSurrogateAnnotation(to)
|
|
630
|
+
if (Option.isSome(surrogate)) {
|
|
631
|
+
return getIdentifierAnnotation(to)
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
return identifier
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
function go(
|
|
639
|
+
ast: AST.AST,
|
|
640
|
+
$defs: Record<string, JsonSchema7>,
|
|
641
|
+
identifier: "handle-identifier" | "ignore-identifier",
|
|
642
|
+
path: ReadonlyArray<PropertyKey>,
|
|
643
|
+
options: GoOptions,
|
|
644
|
+
annotation: "handle-annotation" | "ignore-annotation",
|
|
645
|
+
errors: "handle-errors" | "ignore-errors"
|
|
646
|
+
): JsonSchema7 {
|
|
647
|
+
if (
|
|
648
|
+
identifier === "handle-identifier" &&
|
|
649
|
+
(options.topLevelReferenceStrategy !== "skip" || AST.isSuspend(ast))
|
|
650
|
+
) {
|
|
651
|
+
const id = getIdentifierAnnotation(ast)
|
|
652
|
+
if (id !== undefined) {
|
|
653
|
+
const escapedId = id.replace(/~/ig, "~0").replace(/\//ig, "~1")
|
|
654
|
+
const out = { $ref: options.getRef(escapedId) }
|
|
655
|
+
if (!Record.has($defs, id)) {
|
|
656
|
+
$defs[id] = out
|
|
657
|
+
$defs[id] = go(ast, $defs, "ignore-identifier", path, options, "handle-annotation", errors)
|
|
658
|
+
}
|
|
659
|
+
return out
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
if (annotation === "handle-annotation") {
|
|
663
|
+
const hook = AST.getJSONSchemaAnnotation(ast)
|
|
664
|
+
if (Option.isSome(hook)) {
|
|
665
|
+
const handler = hook.value as JsonSchema7
|
|
666
|
+
if (isOverrideAnnotation(ast, handler)) {
|
|
667
|
+
switch (ast._tag) {
|
|
668
|
+
case "Declaration":
|
|
669
|
+
return addASTAnnotations(handler, ast)
|
|
670
|
+
default:
|
|
671
|
+
return handler
|
|
672
|
+
}
|
|
673
|
+
} else {
|
|
674
|
+
switch (ast._tag) {
|
|
675
|
+
case "Refinement": {
|
|
676
|
+
const t = AST.getTransformationFrom(ast)
|
|
677
|
+
if (t === undefined) {
|
|
678
|
+
return mergeRefinements(
|
|
679
|
+
go(ast.from, $defs, identifier, path, options, "handle-annotation", errors),
|
|
680
|
+
handler,
|
|
681
|
+
ast
|
|
682
|
+
)
|
|
683
|
+
} else {
|
|
684
|
+
return go(t, $defs, identifier, path, options, "handle-annotation", errors)
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
default:
|
|
688
|
+
return {
|
|
689
|
+
...go(ast, $defs, identifier, path, options, "ignore-annotation", errors),
|
|
690
|
+
...handler
|
|
691
|
+
} as any
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
const surrogate = AST.getSurrogateAnnotation(ast)
|
|
697
|
+
if (Option.isSome(surrogate)) {
|
|
698
|
+
return go(surrogate.value, $defs, identifier, path, options, "handle-annotation", errors)
|
|
699
|
+
}
|
|
700
|
+
switch (ast._tag) {
|
|
701
|
+
// Unsupported
|
|
702
|
+
case "Declaration":
|
|
703
|
+
case "UndefinedKeyword":
|
|
704
|
+
case "BigIntKeyword":
|
|
705
|
+
case "UniqueSymbol":
|
|
706
|
+
case "SymbolKeyword": {
|
|
707
|
+
if (errors === "ignore-errors") return addASTAnnotations(constAny, ast)
|
|
708
|
+
throw new Error(errors_.getJSONSchemaMissingAnnotationErrorMessage(path, ast))
|
|
709
|
+
}
|
|
710
|
+
case "Suspend": {
|
|
711
|
+
if (identifier === "handle-identifier") {
|
|
712
|
+
if (errors === "ignore-errors") return addASTAnnotations(constAny, ast)
|
|
713
|
+
throw new Error(errors_.getJSONSchemaMissingIdentifierAnnotationErrorMessage(path, ast))
|
|
714
|
+
}
|
|
715
|
+
return go(ast.f(), $defs, "ignore-identifier", path, options, "handle-annotation", errors)
|
|
716
|
+
}
|
|
717
|
+
// Primitives
|
|
718
|
+
case "NeverKeyword":
|
|
719
|
+
return addASTAnnotations(constNever, ast)
|
|
720
|
+
case "VoidKeyword":
|
|
721
|
+
return addASTAnnotations(constVoid, ast)
|
|
722
|
+
case "UnknownKeyword":
|
|
723
|
+
return addASTAnnotations(constUnknown, ast)
|
|
724
|
+
case "AnyKeyword":
|
|
725
|
+
return addASTAnnotations(constAny, ast)
|
|
726
|
+
case "ObjectKeyword":
|
|
727
|
+
return addASTAnnotations(constObject, ast)
|
|
728
|
+
case "StringKeyword":
|
|
729
|
+
return addASTAnnotations({ type: "string" }, ast)
|
|
730
|
+
case "NumberKeyword":
|
|
731
|
+
return addASTAnnotations({ type: "number" }, ast)
|
|
732
|
+
case "BooleanKeyword":
|
|
733
|
+
return addASTAnnotations({ type: "boolean" }, ast)
|
|
734
|
+
case "Literal": {
|
|
735
|
+
const literal = ast.literal
|
|
736
|
+
if (literal === null) {
|
|
737
|
+
return addASTAnnotations({ type: "null" }, ast)
|
|
738
|
+
} else if (Predicate.isString(literal)) {
|
|
739
|
+
return addASTAnnotations({ type: "string", enum: [literal] }, ast)
|
|
740
|
+
} else if (Predicate.isNumber(literal)) {
|
|
741
|
+
return addASTAnnotations({ type: "number", enum: [literal] }, ast)
|
|
742
|
+
} else if (Predicate.isBoolean(literal)) {
|
|
743
|
+
return addASTAnnotations({ type: "boolean", enum: [literal] }, ast)
|
|
744
|
+
}
|
|
745
|
+
if (errors === "ignore-errors") return addASTAnnotations(constAny, ast)
|
|
746
|
+
throw new Error(errors_.getJSONSchemaMissingAnnotationErrorMessage(path, ast))
|
|
747
|
+
}
|
|
748
|
+
case "Enums": {
|
|
749
|
+
const anyOf = ast.enums.map((e) => {
|
|
750
|
+
const type: "string" | "number" = Predicate.isNumber(e[1]) ? "number" : "string"
|
|
751
|
+
return { type, title: e[0], enum: [e[1]] }
|
|
752
|
+
})
|
|
753
|
+
return anyOf.length >= 1 ?
|
|
754
|
+
addASTAnnotations({
|
|
755
|
+
$comment: "/schemas/enums",
|
|
756
|
+
anyOf
|
|
757
|
+
}, ast) :
|
|
758
|
+
addASTAnnotations(constNever, ast)
|
|
759
|
+
}
|
|
760
|
+
case "TupleType": {
|
|
761
|
+
const elements = ast.elements.map((e, i) =>
|
|
762
|
+
mergeJsonSchemaAnnotations(
|
|
763
|
+
go(e.type, $defs, "handle-identifier", path.concat(i), options, "handle-annotation", errors),
|
|
764
|
+
getContextJsonSchemaAnnotations(e.type, e)
|
|
765
|
+
)
|
|
766
|
+
)
|
|
767
|
+
const rest = ast.rest.map((type) =>
|
|
768
|
+
mergeJsonSchemaAnnotations(
|
|
769
|
+
go(type.type, $defs, "handle-identifier", path, options, "handle-annotation", errors),
|
|
770
|
+
getContextJsonSchemaAnnotations(type.type, type)
|
|
771
|
+
)
|
|
772
|
+
)
|
|
773
|
+
const output: JsonSchema7Array = { type: "array" }
|
|
774
|
+
// ---------------------------------------------
|
|
775
|
+
// handle elements
|
|
776
|
+
// ---------------------------------------------
|
|
777
|
+
const len = ast.elements.length
|
|
778
|
+
if (len > 0) {
|
|
779
|
+
output.minItems = len - ast.elements.filter((element) => element.isOptional).length
|
|
780
|
+
if (options.target === "jsonSchema7") {
|
|
781
|
+
output.items = elements
|
|
782
|
+
} else {
|
|
783
|
+
output.prefixItems = elements
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
// ---------------------------------------------
|
|
787
|
+
// handle rest element
|
|
788
|
+
// ---------------------------------------------
|
|
789
|
+
const restLength = rest.length
|
|
790
|
+
if (restLength > 0) {
|
|
791
|
+
const head = rest[0]
|
|
792
|
+
const isHomogeneous = restLength === 1 && ast.elements.every((e) => e.type === ast.rest[0].type)
|
|
793
|
+
if (isHomogeneous) {
|
|
794
|
+
if (options.target === "jsonSchema7") {
|
|
795
|
+
output.items = head
|
|
796
|
+
} else {
|
|
797
|
+
output.items = head
|
|
798
|
+
delete output.prefixItems
|
|
799
|
+
}
|
|
800
|
+
} else {
|
|
801
|
+
if (options.target === "jsonSchema7") {
|
|
802
|
+
output.additionalItems = head
|
|
803
|
+
} else {
|
|
804
|
+
output.items = head
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
// ---------------------------------------------
|
|
809
|
+
// handle post rest elements
|
|
810
|
+
// ---------------------------------------------
|
|
811
|
+
if (restLength > 1) {
|
|
812
|
+
if (errors === "ignore-errors") return addASTAnnotations(constAny, ast)
|
|
813
|
+
throw new Error(errors_.getJSONSchemaUnsupportedPostRestElementsErrorMessage(path))
|
|
814
|
+
}
|
|
815
|
+
} else {
|
|
816
|
+
if (len > 0) {
|
|
817
|
+
if (options.target === "jsonSchema7") {
|
|
818
|
+
output.additionalItems = false
|
|
819
|
+
} else {
|
|
820
|
+
output.items = false
|
|
821
|
+
}
|
|
822
|
+
} else {
|
|
823
|
+
output.maxItems = 0
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
return addASTAnnotations(output, ast)
|
|
828
|
+
}
|
|
829
|
+
case "TypeLiteral": {
|
|
830
|
+
if (ast.propertySignatures.length === 0 && ast.indexSignatures.length === 0) {
|
|
831
|
+
return addASTAnnotations(constEmptyStruct, ast)
|
|
832
|
+
}
|
|
833
|
+
const output: JsonSchema7Object = {
|
|
834
|
+
type: "object",
|
|
835
|
+
required: [],
|
|
836
|
+
properties: {},
|
|
837
|
+
additionalProperties: getAdditionalProperties(options)
|
|
838
|
+
}
|
|
839
|
+
let patternProperties: JsonSchema7 | undefined = undefined
|
|
840
|
+
let propertyNames: JsonSchema7 | undefined = undefined
|
|
841
|
+
for (const is of ast.indexSignatures) {
|
|
842
|
+
const pruned = pruneUndefined(is.type) ?? is.type
|
|
843
|
+
const parameter = is.parameter
|
|
844
|
+
switch (parameter._tag) {
|
|
845
|
+
case "StringKeyword": {
|
|
846
|
+
output.additionalProperties = go(
|
|
847
|
+
pruned,
|
|
848
|
+
$defs,
|
|
849
|
+
"handle-identifier",
|
|
850
|
+
path,
|
|
851
|
+
options,
|
|
852
|
+
"handle-annotation",
|
|
853
|
+
errors
|
|
854
|
+
)
|
|
855
|
+
break
|
|
856
|
+
}
|
|
857
|
+
case "TemplateLiteral": {
|
|
858
|
+
patternProperties = go(pruned, $defs, "handle-identifier", path, options, "handle-annotation", errors)
|
|
859
|
+
propertyNames = {
|
|
860
|
+
type: "string",
|
|
861
|
+
pattern: AST.getTemplateLiteralRegExp(parameter).source
|
|
862
|
+
}
|
|
863
|
+
break
|
|
864
|
+
}
|
|
865
|
+
case "Refinement": {
|
|
866
|
+
patternProperties = go(pruned, $defs, "handle-identifier", path, options, "handle-annotation", errors)
|
|
867
|
+
propertyNames = go(parameter, $defs, "handle-identifier", path, options, "handle-annotation", errors)
|
|
868
|
+
break
|
|
869
|
+
}
|
|
870
|
+
case "SymbolKeyword": {
|
|
871
|
+
const indexSignaturePath = path.concat("[symbol]")
|
|
872
|
+
output.additionalProperties = go(
|
|
873
|
+
pruned,
|
|
874
|
+
$defs,
|
|
875
|
+
"handle-identifier",
|
|
876
|
+
indexSignaturePath,
|
|
877
|
+
options,
|
|
878
|
+
"handle-annotation",
|
|
879
|
+
errors
|
|
880
|
+
)
|
|
881
|
+
propertyNames = go(
|
|
882
|
+
parameter,
|
|
883
|
+
$defs,
|
|
884
|
+
"handle-identifier",
|
|
885
|
+
indexSignaturePath,
|
|
886
|
+
options,
|
|
887
|
+
"handle-annotation",
|
|
888
|
+
errors
|
|
889
|
+
)
|
|
890
|
+
break
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
// ---------------------------------------------
|
|
895
|
+
// handle property signatures
|
|
896
|
+
// ---------------------------------------------
|
|
897
|
+
for (let i = 0; i < ast.propertySignatures.length; i++) {
|
|
898
|
+
const ps = ast.propertySignatures[i]
|
|
899
|
+
const name = ps.name
|
|
900
|
+
if (Predicate.isString(name)) {
|
|
901
|
+
const pruned = pruneUndefined(ps.type)
|
|
902
|
+
const type = pruned ?? ps.type
|
|
903
|
+
output.properties[name] = mergeJsonSchemaAnnotations(
|
|
904
|
+
go(type, $defs, "handle-identifier", path.concat(ps.name), options, "handle-annotation", errors),
|
|
905
|
+
getContextJsonSchemaAnnotations(type, ps)
|
|
906
|
+
)
|
|
907
|
+
// ---------------------------------------------
|
|
908
|
+
// handle optional property signatures
|
|
909
|
+
// ---------------------------------------------
|
|
910
|
+
if (!ps.isOptional && pruned === undefined) {
|
|
911
|
+
output.required.push(name)
|
|
912
|
+
}
|
|
913
|
+
} else {
|
|
914
|
+
if (errors === "ignore-errors") return addASTAnnotations(constAny, ast)
|
|
915
|
+
throw new Error(errors_.getJSONSchemaUnsupportedKeyErrorMessage(name, path))
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
// ---------------------------------------------
|
|
919
|
+
// handle index signatures
|
|
920
|
+
// ---------------------------------------------
|
|
921
|
+
if (patternProperties !== undefined) {
|
|
922
|
+
delete output.additionalProperties
|
|
923
|
+
output.patternProperties = { "": patternProperties }
|
|
924
|
+
}
|
|
925
|
+
if (propertyNames !== undefined) {
|
|
926
|
+
output.propertyNames = propertyNames
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
return addASTAnnotations(output, ast)
|
|
930
|
+
}
|
|
931
|
+
case "Union": {
|
|
932
|
+
const members: Array<JsonSchema7> = ast.types.map((t) =>
|
|
933
|
+
go(t, $defs, "handle-identifier", path, options, "handle-annotation", errors)
|
|
934
|
+
)
|
|
935
|
+
const anyOf = compactUnion(members)
|
|
936
|
+
switch (anyOf.length) {
|
|
937
|
+
case 0:
|
|
938
|
+
return constNever
|
|
939
|
+
case 1:
|
|
940
|
+
return addASTAnnotations(anyOf[0], ast)
|
|
941
|
+
default:
|
|
942
|
+
return addASTAnnotations({ anyOf }, ast)
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
case "Refinement":
|
|
946
|
+
return go(ast.from, $defs, identifier, path, options, "handle-annotation", errors)
|
|
947
|
+
case "TemplateLiteral": {
|
|
948
|
+
const regex = AST.getTemplateLiteralRegExp(ast)
|
|
949
|
+
return addASTAnnotations({
|
|
950
|
+
type: "string",
|
|
951
|
+
title: String(ast),
|
|
952
|
+
description: "a template literal",
|
|
953
|
+
pattern: regex.source
|
|
954
|
+
}, ast)
|
|
955
|
+
}
|
|
956
|
+
case "Transformation": {
|
|
957
|
+
if (isParseJsonTransformation(ast.from)) {
|
|
958
|
+
const out: JsonSchema7String & { contentSchema?: JsonSchema7 } = {
|
|
959
|
+
"type": "string",
|
|
960
|
+
"contentMediaType": "application/json"
|
|
961
|
+
}
|
|
962
|
+
if (isContentSchemaSupported(options)) {
|
|
963
|
+
out["contentSchema"] = go(ast.to, $defs, identifier, path, options, "handle-annotation", errors)
|
|
964
|
+
}
|
|
965
|
+
return out
|
|
966
|
+
}
|
|
967
|
+
const from = go(ast.from, $defs, identifier, path, options, "handle-annotation", errors)
|
|
968
|
+
if (
|
|
969
|
+
ast.transformation._tag === "TypeLiteralTransformation" &&
|
|
970
|
+
isJsonSchema7Object(from)
|
|
971
|
+
) {
|
|
972
|
+
const to = go(ast.to, {}, "ignore-identifier", path, options, "handle-annotation", "ignore-errors")
|
|
973
|
+
if (isJsonSchema7Object(to)) {
|
|
974
|
+
for (const t of ast.transformation.propertySignatureTransformations) {
|
|
975
|
+
const toKey = t.to
|
|
976
|
+
const fromKey = t.from
|
|
977
|
+
if (Predicate.isString(toKey) && Predicate.isString(fromKey)) {
|
|
978
|
+
const toProperty = to.properties[toKey]
|
|
979
|
+
if (Predicate.isRecord(toProperty)) {
|
|
980
|
+
const fromProperty = from.properties[fromKey]
|
|
981
|
+
if (Predicate.isRecord(fromProperty)) {
|
|
982
|
+
const annotations: JsonSchemaAnnotations = {}
|
|
983
|
+
if (Predicate.isString(toProperty.title)) annotations.title = toProperty.title
|
|
984
|
+
if (Predicate.isString(toProperty.description)) annotations.description = toProperty.description
|
|
985
|
+
if (Array.isArray(toProperty.examples)) annotations.examples = toProperty.examples
|
|
986
|
+
if (Object.hasOwn(toProperty, "default") && toProperty.default !== undefined) {
|
|
987
|
+
annotations.default = toProperty.default
|
|
988
|
+
}
|
|
989
|
+
from.properties[fromKey] = addAnnotations(fromProperty, annotations)
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
return addASTAnnotations(from, ast)
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
function isJsonSchema7Object(jsonSchema: unknown): jsonSchema is JsonSchema7Object {
|
|
1002
|
+
return Predicate.isRecord(jsonSchema) && jsonSchema.type === "object" && Predicate.isRecord(jsonSchema.properties)
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
function isNeverWithoutCustomAnnotations(jsonSchema: JsonSchema7): boolean {
|
|
1006
|
+
return jsonSchema === constNever || (Predicate.hasProperty(jsonSchema, "$id") && jsonSchema.$id === constNever.$id &&
|
|
1007
|
+
Object.keys(jsonSchema).length === 3 && jsonSchema.title === AST.neverKeyword.annotations[AST.TitleAnnotationId])
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
function isAny(jsonSchema: JsonSchema7): jsonSchema is JsonSchema7Any {
|
|
1011
|
+
return "$id" in jsonSchema && jsonSchema.$id === constAny.$id
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
function isUnknown(jsonSchema: JsonSchema7): jsonSchema is JsonSchema7Unknown {
|
|
1015
|
+
return "$id" in jsonSchema && jsonSchema.$id === constUnknown.$id
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
function isVoid(jsonSchema: JsonSchema7): jsonSchema is JsonSchema7Void {
|
|
1019
|
+
return "$id" in jsonSchema && jsonSchema.$id === constVoid.$id
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
function isCompactableLiteral(jsonSchema: JsonSchema7 | undefined): jsonSchema is JsonSchema7Enum {
|
|
1023
|
+
return Predicate.hasProperty(jsonSchema, "enum") && "type" in jsonSchema && Object.keys(jsonSchema).length === 2
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
function compactUnion(members: Array<JsonSchema7>): Array<JsonSchema7> {
|
|
1027
|
+
const out: Array<JsonSchema7> = []
|
|
1028
|
+
for (const m of members) {
|
|
1029
|
+
if (isNeverWithoutCustomAnnotations(m)) continue
|
|
1030
|
+
if (isAny(m) || isUnknown(m) || isVoid(m)) return [m]
|
|
1031
|
+
if (isCompactableLiteral(m) && out.length > 0) {
|
|
1032
|
+
const last = out[out.length - 1]
|
|
1033
|
+
if (isCompactableLiteral(last) && last.type === m.type) {
|
|
1034
|
+
out[out.length - 1] = {
|
|
1035
|
+
type: last.type,
|
|
1036
|
+
enum: [...last.enum, ...m.enum]
|
|
1037
|
+
} as JsonSchema7Enum
|
|
1038
|
+
continue
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
out.push(m)
|
|
1042
|
+
}
|
|
1043
|
+
return out
|
|
1044
|
+
}
|