§ The testGlobalRules shared by the example testdocs
({ scriptRoot: ["@$~gh.0123456789abcdef"], "&ofRelation": { tags: { routeRoot: ["@$~u4.aaaabbbb-cccc-dddd-eeee-ffffffffffff"], }, }, "&ofMethod": { POST: { "&ofRelation": { tags: { relationName: "TAG", }, }, }, }, })
§ Example test site configuration
({ api: { identity: { "!!!": "../../env/test/web-api-identity" }, sessionDuration: 86400, swaggerPrefix: "/openapi" }, serviceIndex: "valos://site.test.com/site?id=aaaabbbb-cccc", openapi: { openapi: "3.0.2", info: { name: "Test API", title: "Test API - Testem", description: "", version: "0.1.0", }, externalDocs: { url: "https://swagger.io", description: "Find more info here", }, servers: [], host: "127.0.0.1", schemes: ["http", "https"], consumes: ["application/json"], produces: ["application/json"], tags: [{ name: "user", description: "User end-points" }], securityDefinitions: { apiKey: { type: "apiKey", name: "apiKey", in: "header", } }, }, schemas: [ sharedSchemaOf(TestTagType), sharedSchemaOf(TestIndividualType), ], routes: [ sessionGETRoute(`/session`, { name: "session", rules: { clientRedirectPath: `/`, grantExpirationDelay: 300, tokenExpirationDelay: 86400 * 7, } }, testGlobalRules), sessionDELETERoute(`/session`, { name: "session", rules: { clientRedirectPath: `/`, } }, testGlobalRules), listingGETRoute(`/tags`, {}, testGlobalRules, TestTagType), resourceGETRoute(`/individuals/:resourceId`, { rules: { routeRoot: [], resource: ["@!ref", ["@!:request:params:resourceId"]], } }, testGlobalRules, TestIndividualType), mappingPOSTRoute(`/individuals/:resourceId/tags`, { enabledWithRules: ["relationName"], rules: { resource: ["@!ref", ["@!:request:params:resourceId"]], doCreateMappingAndTarget: ["@!new", [["@!:Relation"], { name: ["@!:relationName"], source: ["@!:resource"], target: ["@!new", ["@!:Entity"], [{ name: ["@!:request:body", "$V", "target", "name"], owner: ["@!:routeRoot"], properties: { name: ["@!:request:body", "$V", "target", "name"] }, }]], }]], }, }, testGlobalRules, TestIndividualType, TestIndividualType.tags), ], })
§ expanded schema of simple object type
we expecttoEqualexportSchemaOf({ [ObjectSchema]: { description: "simple object type", valospace: { reflection: ["@.:forwardedFields"], }, }, name: StringType, })
({ description: "simple object type", type: "object", valospace: { reflection: ["@.", ["forwardedFields"]], }, properties: { name: { type: "string" } }, })
§ expanded schema of an extended string
we expectviaextendType(StringType, { valospace: { reflection: ["@.$V.name@@"] } })
toEqualexportSchemaOf(type)
({ type: "string", valospace: { reflection: ["@.", [["@$V", "name"]]], }, })
This type contains the basic valospace selector under the key $V which contains the resource 'id' field.{ "$V": { "id": { "type": "string", "pattern": "^[a-zA-Z0-9\\-_.~]+$", "valospace": { "reflection": [ "@.$V.rawId@@" ] } } } }
§ expanded schema of a named resource
we expectvianamedResourceType("TestTag", [], { [ObjectSchema]: { description: "Test Tag resource", valospace: { gate: { name: "tags", projection: [["@-out:TAG"], ["@.$V.target"]], }, }, }, name: extendType(StringType, { summary: "Tag name" }), })
toEqualexportSchemaOf(type)
({ schemaName: "TestTag", description: "Test Tag resource", type: "object", valospace: { gate: { name: "tags", projection: ["@@", [["@-out", ["TAG"]], ["@.", [["@$V", "target"]]]]], }, }, properties: { $V: { type: "object", valospace: {}, properties: { id: { type: "string", pattern: "^[a-zA-Z0-9\\-_.~]+$", valospace: { reflection: ["@.", [["@$V", "rawId"]]] } }, }, }, name: { summary: "Tag name", type: "string" }, }, })
§ expanded schema of a named type reference
we expectvia({ tag: TestTagType })
toEqualexportSchemaOf(type)
{ "tag": { "$ref": "#TestTag" } }
§ expanded schema of a mapping property
we expectviamappingToManyOf("tags", TestTagType, ["@-out:TAG"], { highlight: BooleanType })
toEqualexportSchemaOf(type)
({ type: "array", valospace: { mappingName: "tags", reflection: ["@-out", ["TAG"]], }, items: { type: "object", properties: { highlight: { type: "boolean" }, $V: { type: "object", properties: { href: { type: "string" }, rel: { type: "string" }, target: { type: "object", valospace: { resourceType: "TestTag" }, properties: { $V: { type: "object", properties: { id: { type: "string", pattern: "^[a-zA-Z0-9\\-_.~]+$", valospace: { reflection: ["@.", [["@$V", "rawId"]]] }, }, } }, } }, } }, }, }, })
§ expanded schema of a complex resource type
we expectvianamedResourceType( "TestIndividual", exports.TestProfileType, { [ObjectSchema]: { description: "Test Individual resource", valospace: { gate: { name: "individuals", projection: [["@-out:INDIVIDUAL"], ["@.$V.target"]], filterCondition: [["@$valk.nullable"], ["@.:visible"]], }, }, }, title: StringType, company: StringType, interests: () => mappingToManyOf("interests", exports.TestTagType, [["@-out:INTEREST"], ["@$valk.nullable"]], { [ObjectSchema]: { valospace: { filterable: true } } }), })
toEqualexportSchemaOf(type)
({ schemaName: "TestIndividual", type: "object", description: "Test Individual resource", valospace: { gate: { name: "individuals", projection: ["@@", [["@-out", ["INDIVIDUAL"]], ["@.", [["@$V", "target"]]]]], filterCondition: [["@$valk.nullable"], ["@.:visible"]], }, }, properties: { $V: { type: "object", valospace: {}, properties: { id: { type: "string", pattern: "^[a-zA-Z0-9\\-_.~]+$", valospace: { reflection: ["@.", [["@$V", "rawId"]]], }, }, }, }, company: { type: "string" }, contact: { type: "object", properties: { email: { type: "string" }, phone: { type: "string" }, website: { type: "string" } }, }, description: { type: "string" }, icon: { type: "string" }, image: { type: "string", valospace: { reflection: ["@.", [["@$V", "name"]]] }, }, interests: { type: "array", valospace: { mappingName: "interests", reflection: ["@@", [["@-out", ["INTEREST"]], ["@$valk", "nullable"]]], }, items: { type: "object", valospace: { filterable: true }, properties: { $V: { type: "object", properties: { href: { type: "string" }, rel: { type: "string" }, target: { type: "object", valospace: { resourceType: "TestTag" }, properties: { $V: { type: "object", properties: { id: { type: "string", pattern: "^[a-zA-Z0-9\\-_.~]+$", valospace: { reflection: ["@.", [["@$V", "rawId"]]], }, }, } }, } }, } }, }, }, }, name: { type: "string" }, owned: { type: "object", valospace: { reflection: ["@@"] }, properties: { services: { type: "array", valospace: { mappingName: "owned/services", reflection: ["@@", [["@-out", ["SERVICE"]], ["@$valk", "nullable"]]], }, items: { properties: { highlight: { type: "boolean" }, $V: { type: "object", properties: { href: { type: "string" }, rel: { type: "string" }, target: { type: "object", valospace: { resourceType: "TestService" }, properties: { $V: { type: "object", properties: { id: { type: "string", pattern: "^[a-zA-Z0-9\\-_.~]+$", valospace: { reflection: ["@.", [["@$V", "rawId"]]], }, }, } }, } }, } }, }, type: "object", }, }, }, }, tags: { type: "array", valospace: { mappingName: "tags", reflection: ["@@", [["@-out", ["TAG"]], ["@$valk", "nullable"]]], }, items: { type: "object", valospace: { filterable: true }, properties: { highlight: { type: "boolean" }, $V: { type: "object", properties: { href: { type: "string" }, rel: { type: "string" }, target: { type: "object", valospace: { resourceType: "TestTag" }, properties: { $V: { type: "object", properties: { id: { type: "string", pattern: "^[a-zA-Z0-9\\-_.~]+$", valospace: { reflection: ["@.", [["@$V", "rawId"]]], }, }, } }, } }, } }, }, }, }, title: { type: "string" }, visible: { type: "boolean" }, }, })
§ Data common to all route testdoc examples
({ TestTagType, TestIndividualType, gate: TestIndividualType[ObjectSchema].valospace.gate, mappingName: "tags", testThingTagsMapping: TestIndividualType.tags, })
§ route of a simple resource GET
we expecttoEqualresourceGETRoute(`/${gate.name}/:resourceId`, { rules: { routeRoot: null, resource: ["@!ref", ["@!:request:params:resourceId"]], }, }, {}, TestIndividualType)
({ name: "individuals", method: "GET", projector: "resource", url: "/individuals/:resourceId", schema: { description: "Get the contents of a TestIndividual route resource", querystring: { fields: { type: "string", pattern: "^([a-zA-Z0-9\\-_.~/*$]*(\\,([a-zA-Z0-9\\-_.~/*$])*)*)?$" }, }, response: { 200: { $ref: "#TestIndividual" }, 403: { type: "string" }, 404: { type: "string" }, } }, config: { requiredRules: ["routeRoot"], valueAssertedRules: ["resource"], runtimeRules: [], resource: { name: "TestIndividual", schema: { $ref: "#TestIndividual" }, gate: { name: "individuals", projection: ["@@", [["@-out", ["INDIVIDUAL"]], ["@.", [["@$V", "target"]]]]], filterCondition: [["@$valk.nullable"], ["@.:visible"]], }, }, rules: { resource: ["@!ref", [ ["@!", ["request", "params", "resourceId"]], ]], routeRoot: null, }, }, })
§ route of a complex POST mapping
we expecttoEqualmappingPOSTRoute(`/${gate.name}/:resourceId/${mappingName}`, { enabledWithRules: ["relationName"], rules: { resource: ["@!ref", ["@!:request:params:resourceId"]], doCreateMappingAndTarget: ["@!new", ["@!:Relation"], [{ name: ["@!:relationName"], source: ["@!:resource"], target: ["@!new", ["@!:Entity"], [{ name: ["@!:request:body", "$V", "target", "name"], owner: ["@!:routeRoot"], properties: { name: ["@!:request:body", "$V", "target", "name"] }, }]], }]], }, }, testGlobalRules, TestIndividualType, testThingTagsMapping)
({ name: "individuals", method: "POST", projector: "mapping", url: "/individuals/:resourceId/tags", schema: { description: `Create a new TestTag resource *using **body.$V.target** as content* and then a new 'tags' mapping to it from the source TestIndividual route resource. The remaining fields of the body are set as the mapping content. Similarily the response will contain the newly created target resource content in *response.$V.target* with the rest of the response containing the mapping.`, body: { type: "object", valospace: { filterable: true }, properties: { highlight: { type: "boolean" }, $V: { type: "object", properties: { target: { $ref: "#TestTag" } } }, }, }, response: { 200: { type: "object", valospace: { filterable: true }, properties: { highlight: { type: "boolean" }, $V: { type: "object", properties: { href: { type: "string" }, rel: { type: "string" }, target: { $ref: "#TestTag" }, } }, }, }, 403: { type: "string" }, 404: { type: "string" }, } }, config: { resource: { name: "TestIndividual", schema: { $ref: "#TestIndividual" }, gate: { name: "individuals", projection: ["@@", [["@-out", ["INDIVIDUAL"]], ["@.", [["@$V", "target"]]]]], filterCondition: [["@$valk.nullable"], ["@.:visible"]], }, }, relation: { name: "tags", schema: { type: "array", valospace: { mappingName: "tags", reflection: ["@@", [["@-out", ["TAG"]], ["@$valk", "nullable"]]], }, items: { type: "object", valospace: { filterable: true }, properties: { highlight: { type: "boolean" }, $V: { type: "object", properties: { href: { type: "string" }, rel: { type: "string" }, target: { type: "object", valospace: { resourceType: "TestTag" }, properties: { $V: { type: "object", properties: { id: { type: "string", pattern: "^[a-zA-Z0-9\\-_.~]+$", valospace: { reflection: ["@.", [["@$V", "rawId"]]], }, }, } }, } }, } }, }, }, }, }, target: { name: "TestTag", schema: { $ref: "#TestTag" } }, enabledWithRules: ["relationName"], requiredRules: ["routeRoot", "mappingName"], valueAssertedRules: ["resource"], runtimeRules: ["doCreateMappingAndTarget"], rules: { doCreateMappingAndTarget: ["@!new", [ ["@!", ["Relation"]], ["@*", [ ["@.", ["name", ["@!", ["relationName"]]]], ["@.", ["source", ["@!", ["resource"]]]], ["@.", ["target", ["@!new", [ ["@!", ["Entity"]], ["@*", [ ["@.", ["name", ["@!", ["request", "body", "$V", "target", "name"]]]], ["@.", ["owner", ["@!", ["routeRoot"]]]], ["@.", ["properties", ["@*", [ ["@.", ["name", ["@!", ["request", "body", "$V", "target", "name"]]]], ]]]], ]], ]]]], ]], ]], mappingName: "tags", relationName: "TAG", resource: ["@!ref", [["@!", ["request", "params", "resourceId"]]]], routeRoot: ["@$~u4", "aaaabbbb-cccc-dddd-eeee-ffffffffffff"], scriptRoot: ["@$~gh", "0123456789abcdef"], }, }, })
§ Data common to all projections examples
({ shared: "shared example data example" })
§ expanded schema of an extended resource type
we expectvianamedResourceType("TestNewsItem", exports.TestThingType, { [ObjectSchema]: { description: "Test News Item resource", valospace: { gate: { name: "news", projection: [["@-out:NEWSITEM"], ["@.$V.target"]], filterCondition: [["@$valk.nullable"], ["@.:visible"]], }, }, }, startTime: exports.TestDateTimeType, endTime: exports.TestDateTimeType, })
toEqualexportSchemaOf(type)
({ schemaName: "TestNewsItem", type: "object", description: "Test News Item resource", valospace: { gate: { name: "news", projection: ["@@", [["@-out", ["NEWSITEM"]], ["@.", [["@$V", "target"]]]]], filterCondition: [["@$valk.nullable"], ["@.:visible"]], }, }, properties: { $V: { type: "object", valospace: {}, properties: { id: { type: "string", pattern: "^[a-zA-Z0-9\\-_.~]+$", valospace: { reflection: ["@.", [["@$V", "rawId"]]], }, }, }, }, contact: { type: "object", properties: { email: { type: "string" }, phone: { type: "string" }, website: { type: "string" } }, }, description: { type: "string" }, icon: { type: "string" }, image: { type: "string", valospace: { reflection: ["@.", [["@$V", "name"]]] }, }, name: { type: "string" }, tags: { type: "array", valospace: { mappingName: "tags", reflection: ["@@", [["@-out", ["TAG"]], ["@$valk", "nullable"]]], }, items: { type: "object", valospace: { filterable: true }, properties: { highlight: { type: "boolean" }, $V: { type: "object", properties: { href: { type: "string" }, rel: { type: "string" }, target: { type: "object", valospace: { resourceType: "TestTag" }, properties: { $V: { type: "object", properties: { id: { type: "string", pattern: "^[a-zA-Z0-9\\-_.~]+$", valospace: { reflection: ["@.", [["@$V", "rawId"]]], }, }, } }, } }, } }, }, }, }, visible: { type: "boolean" }, startTime: { type: "object", valospace: {}, properties: { unixSeconds: { type: "number" }, zone: { type: "string" } }, }, endTime: { type: "object", valospace: {}, properties: { unixSeconds: { type: "number" }, zone: { type: "string" } }, }, }, })