Skip to content

Commit

Permalink
[org.openapis.v3] Implement full OpenAPI 3.0.3 spec (#39)
Browse files Browse the repository at this point in the history
This adds the whole specification for OpenAPI 3.0.3
  • Loading branch information
nickswift authored Mar 19, 2024
1 parent 23fa825 commit a0b58cb
Show file tree
Hide file tree
Showing 36 changed files with 2,390 additions and 7 deletions.
2 changes: 1 addition & 1 deletion packages/org.openapis.v3.contrib/PklProject
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
amends "../basePklProject.pkl"

package {
version = "1.0.0"
version = "1.0.1"
}

dependencies {
Expand Down
2 changes: 1 addition & 1 deletion packages/org.openapis.v3.contrib/PklProject.deps.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"resolvedDependencies": {
"package://pkg.pkl-lang.org/pkl-pantry/org.openapis.v3@2": {
"type": "local",
"uri": "projectpackage://pkg.pkl-lang.org/pkl-pantry/org.openapis.v3@2.0.0",
"uri": "projectpackage://pkg.pkl-lang.org/pkl-pantry/org.openapis.v3@2.1.0",
"path": "../org.openapis.v3"
}
}
Expand Down
99 changes: 99 additions & 0 deletions packages/org.openapis.v3.contrib/examples/SampleAPI.pkl
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
//===----------------------------------------------------------------------===//
// Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//===----------------------------------------------------------------------===//
module org.openapis.v3_0.examples.SampleAPI

amends "@openapi/Document.pkl"

import "@openapi/Components.pkl"
import "@openapi/HTTPResponse.pkl"
import "../SchemaGenerator.pkl"

// User schema
local class User {
firstName: String
middleName: String?
lastName: String
}

info {
title = "Sample API"
description = "Example API to demonstrate the form of an OpenAPI PKL document"
version = "0.1.0"
}

servers {
// staging
new {
url = "https://staging-api.example.com"
description = "Staging server"
}

// production
new {
url = "https://api.example.com/{basePath}"
description = "Production server"
variables {
["basePath"] {
default = "v1"
}
}
}
}

paths {
["/users"] {
get {
summary = "Returns a list of users"
description = """
This is an endpoint that returns a list of users from the configured storage backend.
Blah blah blah.
"""
responses {
[HTTPResponse.OK] {
description = "A JSON array of usernames"
content {
["application/json"] {
schema = Components.componentRef("schemas", "UserList")
}
}
}
["4XX"] {
description = "Any client-side error"
}
}
}
}
}

// define components
components {
schemas {
["User"] = SchemaGenerator.generate(User)
["UserList"] {
type = "array"
items = Components.componentRef("schemas", "User")
}
}
links {
["someLink"] {
requestBody = "$url#/foo/bar"
}
}
}

output {
renderer = new JsonRenderer {}
}
57 changes: 57 additions & 0 deletions packages/org.openapis.v3/BaseParameter.pkl
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//===----------------------------------------------------------------------===//
// Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//===----------------------------------------------------------------------===//
abstract module org.openapis.v3.BaseParameter

/// A brief description of the parameter.
///
/// This could contain examples of use. CommonMark syntax MAY be used for rich text representation.
@SourceCode { language = "Markdown" }
description: String?

/// Specifies that a parameter is deprecated and SHOULD be transitioned out of usage.
///
/// Default value is false.
deprecated: Boolean?

/// Sets the ability to pass empty-valued parameters.
///
/// This is valid only for query parameters and allows sending a parameter with an empty value. Default value is
/// false. If style is used, and if behavior is n/a (cannot be serialized), the value of allowEmptyValue SHALL be
/// ignored. Use of this property is NOT RECOMMENDED, as it is likely to be removed in a later revision.
allowEmptyValue: Boolean?

/// When this is true, parameter values of type array or object generate separate parameters for each value of the
/// array or key-value pair of the map.
///
/// For other types of parameters this property has no effect. When style is form, the default value is true. For all
/// other styles, the default value is false.
explode: Boolean?

/// Example of the parameter's potential value. The example SHOULD match the specified schema and encoding properties
/// if present.
///
/// The example field is mutually exclusive of the examples field. Furthermore, if referencing a schema that contains
/// an example, the example value SHALL override the example provided by the schema. To represent examples of media
/// types that cannot naturally be represented in JSON or YAML, a string value can contain the example with escaping
/// where necessary.
example: Any?(!(this != null && examples != null))

/// Examples of the parameter's potential value.
///
/// Each example SHOULD contain a value in the correct format as specified in the parameter encoding. The examples
/// field is mutually exclusive of the example field. Furthermore, if referencing a schema that contains an example,
/// the examples value SHALL override the example provided by the schema.
examples: Mapping<String, Any>?
74 changes: 74 additions & 0 deletions packages/org.openapis.v3/Components.pkl
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//===----------------------------------------------------------------------===//
// Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//===----------------------------------------------------------------------===//
/// Holds a set of reusable objects for different aspects of the OAS.
///
/// All objects defined within the components object will have no effect on the API unless they are explicitly
/// referenced from properties outside the components object.
module org.openapis.v3.Components

import "expressions.pkl"
import "Example.pkl"
import "Header.pkl"
import "Link.pkl"
import "Parameter.pkl"
import "Reference.pkl"
import "RequestBody.pkl"
import "Response.pkl"
import "Schema.pkl"
import "SecurityScheme.pkl"
import "PathItem.pkl"

/// Component mapping key type used to reference all component values.
typealias ComponentKey = String(matches(Regex(#"[a-zA-Z0-9.\-_]+"#)))

/// Component type name for use with component reference helpers.
typealias ComponentType = "schemas"|"responses"|"parameters"|"examples"|"requestBodies"|"headers"|"links"

/// An object to hold reusable Schema Objects.
schemas: Mapping<ComponentKey, *Schema|Reference>?

/// An object to hold reusable Response Objects.
responses: Mapping<ComponentKey, *Response|Reference>?

/// An object to hold reusable Parameter Objects.
parameters: Mapping<ComponentKey, *Parameter|Reference>?

/// An object to hold reusable Example Objects.
examples: Mapping<ComponentKey, *Example|Reference>?

/// An object to hold reusable RequestBody Objects.
requestBodies: Mapping<ComponentKey, *RequestBody|Reference>?

/// An object to hold reusable Header Objects.
headers: Mapping<ComponentKey, *Header|Reference>?

/// An object to hold reusable Security Scheme Objects.
securitySchemes: Mapping<ComponentKey, *SecurityScheme|Reference>?

/// An object to hold reusable Link Objects.
links: Mapping<ComponentKey, *Link|Reference>?

/// An object to hold reusable Callback Objects.
callbacks: Mapping<ComponentKey, *Mapping<expressions.Expression, PathItem>|Reference>?

/// Component reference helper function. This reference will point to the named component in the local document's
/// "components" fields.
function componentRef(type: ComponentType, name: String): Reference =
// TODO: can we throw an error if the referenced component does not exist? This would be extremely useful.
// We may need to check for reference consistencey in the render step.
new Reference {
`$ref` = "#/components/\(type)/\(name)"
}
28 changes: 28 additions & 0 deletions packages/org.openapis.v3/Contact.pkl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//===----------------------------------------------------------------------===//
// Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//===----------------------------------------------------------------------===//
/// Contact information for the exposed API.
module org.openapis.v3.Contact

/// The identifying name of the contact person/organization.
name: String?

/// The URL pointing to the contact information. MUST be in the format of a URL.
url: Uri?

/// The email address of the contact person/organization.
///
/// MUST be in the format of an email address.
email: String?
98 changes: 98 additions & 0 deletions packages/org.openapis.v3/Document.pkl
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
//===----------------------------------------------------------------------===//
// Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//===----------------------------------------------------------------------===//
open module org.openapis.v3.Document

import "Info.pkl"
import "Server.pkl"
import "PathItem.pkl"
import "Components.pkl"
import "Security.pkl"
import "Tag.pkl"
import "ExternalDocs.pkl"
import "Reference.pkl" as _Reference
import "HTTPResponse.pkl" as _HttpResponse

/// This string MUST be the semantic version number of the OpenAPI Specification version that the OpenAPI document
/// uses.
///
/// The openapi field SHOULD be used by tooling specifications and clients to interpret the OpenAPI document. This is
/// not related to the API info.version string. The default value corresponds to the version of the spec we've
/// implemented in this package.
///
/// Since this library specifically follows version 3.0.3 of the OpenAPI spec, this value cannot change unless this
/// library is updated to implement a later version.
fixed openapi = "3.0.3"

/// Provides metadata about the API.
///
/// The metadata MAY be used by tooling as required.
info: Info

/// An array of Server Objects, which provide connectivity information to a target server.
///
/// If the servers property is not provided, or is an empty array, the default value would be a Server Object with a
/// url value of /.
servers: Listing<Server>?

/// The available paths and operations for the API.
///
/// Contains relative paths to an individual endpoint. The field name MUST begin with a forward slash (/). The path is
/// appended (no relative URL resolution) to the expanded URL from the Server Object's url field in order to construct
/// the full URL. Path templating is allowed.
///
/// When matching URLs, concrete (non-templated) paths would be matched before their templated counterparts.
/// Templated paths with the same hierarchy but different templated names MUST NOT exist as they are identical.
///
/// In case of ambiguous matching, it's up to the tooling to decide which one to use.
paths: Mapping<String(startsWith("/")), PathItem>

/// An element to hold various schemas for the specification.
components: Components?

/// A declaration of which security mechanisms can be used across the API.
///
/// The list of values includes alternative security requirement objects that can be used. Only one of the security
/// requirement objects need to be satisfied to authorize a request. Individual operations can override this
/// definition. To make security optional, an empty security requirement ({}) can be included in the array.
security: Listing<Security.Requirement>?

/// A list of tags used by the specification with additional metadata.
///
/// The order of the tags can be used to reflect on their order by the parsing tools. Not all tags that are used by
/// the Operation Object must be declared. The tags that are not declared MAY be organized randomly or based on the
/// tools' logic. Each tag name in the list MUST be unique.
tags: Listing<Tag>(isDistinct)?

/// Additional external documentation.
externalDocs: ExternalDocs?

// re-export types so they are available without import
typealias Reference = _Reference

// noinspection TypeMismatch
/// The output format to render.
///
/// OpenAPI documents can be defined in either JSON or YAML.
/// This is a Pkl-only property that is excluded from OpenAPI output.
hidden __format__: "json"|"yaml" = read?("prop:pkl.outputFormat") ?? "json"

output {
renderer =
if (__format__ == "json")
new JsonRenderer {}
else
new YamlRenderer {}
}
Loading

0 comments on commit a0b58cb

Please sign in to comment.