Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion SPECIFICATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ MUST NOT use the `orsp` namespace unless it is defined by a future ORSP
specification. Unknown extension tokens do not make a source incompatible.

Optional discovery members are `description`, `iconUrl`, `websiteUrl`,
`languages`, `supportedVersions`, and `maxCatalogPageSize`. Language tags MUST
`languages`, `supportedVersions`, `maxCatalogPageSize`, `operatorName`,
`contactUrl`, `contentLicense`, and `rightsStatement`. Language tags MUST
follow BCP 47, such as `en`, `zh-CN`, or `sr-Latn`.

`supportedVersions`, when present, is a non-empty array of ORSP
Expand All @@ -121,6 +122,18 @@ clients MAY use it for diagnostics and MUST NOT require it.
declaring the largest `pageSize` the source accepts on the chapter-catalog
endpoint (Section 11). When absent, the limit is 100.

`operatorName`, `contactUrl`, `contentLicense`, and `rightsStatement` are
rights-transparency members. `operatorName` identifies the entity that
actually operates the source and can act on rights requests. `contactUrl`,
when present, MUST be an absolute HTTP(S) URL for a contact or rights-report
page controlled by that operator. `contentLicense` is a short license name or
authorization basis, for example `CC BY 4.0` or `Public Domain`.
`rightsStatement` is a concise, source-supplied description of content
provenance or authorization scope. A client MAY display these members for
transparency but MUST NOT treat their presence, absence, or content as a
legality, authorization, or identity certification by any reader, registry,
or the protocol itself.

`apiBaseUrl` MUST NOT contain user information, a query, or a fragment and MUST
end in `/`. Endpoint paths in this document are resolved relative to that URL.
For example, an API base URL of `https://books.example/api/` and endpoint
Expand Down
10 changes: 9 additions & 1 deletion SPECIFICATION.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ ORSP 1.1 定义三项可选的标准能力:
客户端遇到未知扩展能力时,不得因此判定书源不兼容。

发现文档的可选字段包括 `description`、`iconUrl`、`websiteUrl`、`languages`、
`supportedVersions` 和 `maxCatalogPageSize`。语言必须使用 BCP 47 标签,例如 `en`、
`supportedVersions`、`maxCatalogPageSize`、`operatorName`、`contactUrl`、
`contentLicense` 和 `rightsStatement`。语言必须使用 BCP 47 标签,例如 `en`、
`zh-CN` 或 `sr-Latn`。

`supportedVersions` 是非空的 ORSP `主版本.次版本` 字符串数组,出现时必须包含
Expand All @@ -103,6 +104,13 @@ ORSP 1.1 定义三项可选的标准能力:
`maxCatalogPageSize` 是 100 至 1000 之间的整数,声明章节目录接口(第 11 节)接受的
最大 `pageSize`。省略时上限为 100。

`operatorName`、`contactUrl`、`contentLicense` 和 `rightsStatement` 是权利透明度
字段。`operatorName` 标识实际运营该书源、能够处理权利请求的主体。`contactUrl` 如果
出现,必须是该运营者控制的绝对 HTTP(S) 联系或权利投诉页面。`contentLicense` 是简短
的许可名称或授权依据,例如 `CC BY 4.0` 或 `Public Domain`。`rightsStatement` 是书源
自行提供的内容来源或授权范围简述。客户端可以为了透明度展示这些字段,但不得把它们的
存在、缺失或内容当作任何阅读器、注册表或协议本身对合法性、授权或身份的认证。

`apiBaseUrl` 不得包含用户名、密码、查询参数或片段,并且必须以 `/` 结尾。本文接口路径
相对于该 URL 解析。例如,API 基础地址为 `https://books.example/api/`,接口关系为
`v1/search`,最终地址就是 `https://books.example/api/v1/search`。
Expand Down
8 changes: 8 additions & 0 deletions examples/dart_server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ class ReferenceSourceServer {
'apiBaseUrl': baseUri.resolve('api/').toString(),
'languages': ['zh-CN', 'en'],
'maxCatalogPageSize': maxCatalogPageSize,
'operatorName': 'ORSP Reference Project',
'contactUrl':
'https://github.com/miloquinn/open-reading-source-protocol/issues',
'contentLicense':
'Original example content under the repository license',
'rightsStatement':
'This reference source contains only original protocol test '
'content created for ORSP development.',
'capabilities': [
'search',
'discover',
Expand Down
19 changes: 19 additions & 0 deletions schemas/discovery.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,25 @@
"minimum": 100,
"maximum": 1000
},
"operatorName": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"contactUrl": {
"type": "string",
"format": "uri",
"pattern": "^https?://"
},
"contentLicense": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"rightsStatement": {
"type": "string",
"maxLength": 2000
},
"capabilities": {
"type": "array",
"minItems": 4,
Expand Down
18 changes: 18 additions & 0 deletions tool/conformance_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,24 @@ Future<void> main() async {
maxCatalogPageSize >= 100 && maxCatalogPageSize <= 1000,
'maxCatalogPageSize is within the allowed range',
);
check(
(discoveryJson['operatorName'] as String).isNotEmpty,
'operatorName is present and non-empty',
);
check(
Uri.parse(
discoveryJson['contactUrl'] as String,
).scheme.startsWith('http'),
'contactUrl is an absolute HTTP(S) URL',
);
check(
(discoveryJson['contentLicense'] as String).isNotEmpty,
'contentLicense is present and non-empty',
);
check(
(discoveryJson['rightsStatement'] as String).isNotEmpty,
'rightsStatement is present and non-empty',
);

final discover = await request(client, apiBase.resolve('v1/discover'));
check(discover.status == 200, 'discover returns 200');
Expand Down
Loading