import "testLib" as testLib; def typecheckingEnabled: if $ENV["JQ_TYPECHECKING"] != null and (["true", "1", "debug"] | any(index($ENV["JQ_TYPECHECKING"]))) then true else false end; def typecheckingDebug: if $ENV["JQ_TYPECHECKING"] == "debug" then true else false end; def dumpType: if (. | type) == "object" then . | [to_entries | sort_by(.key)[] | {"\(.key)": (.value|dumpType)}] | add elif (. | type) == "array" then [.[] | dumpType] as $array | if ($array | length > 0) then if ($array | all(select(. == $array[0]))) then [$array[0]] else $array end else "array:empty/unknown" end else . | type end; def typeErrorText: . as $type | "Type Error Checking '\($type)'"; def typeErrorText($type): $type | typeErrorText; def typeError($type): if typecheckingDebug then debug({typeName: $type, value: ., valueType: . | dumpType}) end | error($type | typeErrorText); def ensureNull: if typecheckingEnabled and (. | type != "null") then typeError("null") end; def ensureBool: if typecheckingEnabled and (. | type) != "boolean" then typeError("bool") end; def ensureString: if typecheckingEnabled and (. | type) != "string" then typeError("string") end; def ensureArray: if typecheckingEnabled and (. | type) != "array" then typeError("array") end; def ensureObject: if typecheckingEnabled and (. | type) != "object" then typeError("object") end; def ensureNumber: if typecheckingEnabled and (. | type) != "number" then typeError("number") end; def ensureNull($value): $value | ensureNull; def ensureBool($value): $value | ensureBool; def ensureString($value): $value | ensureString; def ensureArray($value): $value | ensureArray; def ensureObject($value): $value | ensureObject; def ensureNumber($value): $value | ensureNumber; def ensureNullOr(ensureType): if . == null then . else . | ensureType end; def ensureKey($type; $key): if (. | has($key) | not) then typeError("\($type):\($key)") end; def ensureKey($value; $type; $key): $value | ensureKey($type; $key); def ensureWrapError($newType; ensureType): . as $value | try (. | ensureType) catch ( . as $prevError | if typecheckingDebug then debug({$newType, $prevError}) end | error(typeErrorText($newType)) ); def ensureWrapError($value; $newType; ensureType): $value | ensureWrapError($newType; ensureType); # JQ_TYPECHECKING=true required for tests def typeLibTests: testLib::expectPassed(testLib::runTest( "null is null"; (null | ensureNull); true; false )) | testLib::expectPassed(testLib::runTest( "boolean is not null"; (true | ensureNull); (. == typeErrorText("null")); true ));