jld3103
2 years ago
15 changed files with 0 additions and 9607 deletions
@ -1,10 +0,0 @@
|
||||
# Files and directories created by pub. |
||||
.dart_tool/ |
||||
.packages |
||||
|
||||
# Conventional directory for build outputs. |
||||
build/ |
||||
|
||||
# Omit committing pubspec.lock for library packages; see |
||||
# https://dart.dev/guides/libraries/private-files#pubspeclock. |
||||
pubspec.lock |
@ -1 +0,0 @@
|
||||
include: package:nit_picking/dart.yaml |
@ -1,500 +0,0 @@
|
||||
import 'dart:convert'; |
||||
import 'dart:io'; |
||||
|
||||
import 'package:path/path.dart' as p; |
||||
import 'package:spec_templates/method_parameter.dart'; |
||||
import 'package:spec_templates/openapi_spec.dart'; |
||||
import 'package:xml/xml.dart'; |
||||
|
||||
Future main(final List<String> args) async { |
||||
final tmpDirectory = Directory(p.join(Directory.systemTemp.path, 'nextcloud-neon')); |
||||
if (!tmpDirectory.existsSync()) { |
||||
tmpDirectory.createSync(); |
||||
} |
||||
|
||||
final path = args[0]; |
||||
final isCore = args[1] == 'true'; |
||||
|
||||
final appDirectory = Directory(p.absolute(p.normalize(path))); |
||||
if (!appDirectory.existsSync()) { |
||||
throw Exception('App directory $appDirectory not found'); |
||||
} |
||||
late String infoXmlPath; |
||||
if (isCore) { |
||||
infoXmlPath = p.join( |
||||
'specs', |
||||
'templates', |
||||
'appinfo_core.xml', |
||||
); |
||||
} else { |
||||
infoXmlPath = p.join( |
||||
appDirectory.path, |
||||
'appinfo', |
||||
'info.xml', |
||||
); |
||||
} |
||||
|
||||
final document = XmlDocument.parse(File(infoXmlPath).readAsStringSync()); |
||||
final info = document.findElements('info').toList().single; |
||||
final id = info.findElements('id').toList().single.innerText; |
||||
final name = info.findElements('name').toList().single.innerText; |
||||
final summary = info.findElements('summary').toList().single.innerText; |
||||
final version = info.findElements('version').toList().single.innerText; |
||||
final license = info.findElements('licence').toList().single.innerText; |
||||
|
||||
late String routesPhpPath; |
||||
if (isCore) { |
||||
routesPhpPath = p.join( |
||||
appDirectory.path, |
||||
'routes.php', |
||||
); |
||||
} else { |
||||
routesPhpPath = p.join( |
||||
appDirectory.path, |
||||
'appinfo', |
||||
'routes.php', |
||||
); |
||||
} |
||||
|
||||
final routes = await _parseRoutesFile(tmpDirectory, routesPhpPath); |
||||
|
||||
final paths = <String, Path>{}; |
||||
|
||||
final hasRoutes = routes.keys.contains('routes'); |
||||
final hasOCS = routes.keys.contains('ocs'); |
||||
if (!hasRoutes && !hasOCS) { |
||||
throw Exception('One of ocs and routes is required, but only found: "${routes.keys.join('", "')}"'); |
||||
} |
||||
|
||||
final routesBasePath = '${isCore ? '' : '/apps'}/$id'; |
||||
final ocsBasePath = '/ocs/v2.php$routesBasePath'; |
||||
|
||||
for (final k in routes.keys) { |
||||
for (final route in routes[k]!) { |
||||
final name = route['name'] as String; |
||||
var url = route['url'] as String; |
||||
// ignore: avoid_dynamic_calls |
||||
final requirements = route['requirements']?.cast<String, String>() as Map<String, String>?; |
||||
if (!url.startsWith('/')) { |
||||
url = '/$url'; |
||||
} |
||||
if (url.endsWith('/')) { |
||||
url = url.substring(0, url.length - 1); |
||||
} |
||||
if (k == 'routes') { |
||||
url = '$routesBasePath$url'; |
||||
} else if (k == 'ocs') { |
||||
url = '$ocsBasePath$url'; |
||||
} |
||||
final verb = route['verb'] as String? ?? 'GET'; |
||||
|
||||
if (name.startsWith('page#') || name.startsWith('admin#')) { |
||||
continue; |
||||
} |
||||
|
||||
if (verb == 'GET' && url == '/') { |
||||
continue; |
||||
} |
||||
|
||||
final methodName = _getMethodName(name.split('#')[1]); |
||||
final controllerName = _getControllerName(name.split('#')[0]); |
||||
late String controllerFilePath; |
||||
if (isCore) { |
||||
controllerFilePath = p.join( |
||||
appDirectory.path, |
||||
'Controller', |
||||
'$controllerName.php', |
||||
); |
||||
} else { |
||||
controllerFilePath = p.join( |
||||
appDirectory.path, |
||||
'lib', |
||||
'Controller', |
||||
'$controllerName.php', |
||||
); |
||||
} |
||||
final controllerContent = File(controllerFilePath).readAsStringSync().replaceAll('\n', ''); |
||||
|
||||
if (methodName == 'preflightedCors') { |
||||
continue; |
||||
} |
||||
|
||||
final reg = |
||||
RegExp('\\/\\*\\*((?:(?!\\/\\*\\*).)*?)\\*\\/(?:(?!\\*\\/).)*?public function $methodName\\(([^\\)]*)\\)'); |
||||
final match = reg.allMatches(controllerContent).single; |
||||
|
||||
final docParameters = <String>[]; |
||||
var current = ''; |
||||
for (final docLine in match |
||||
.group(1)! |
||||
.split('*') |
||||
.map((final s) { |
||||
var r = s.trim(); |
||||
while (r.contains(' ')) { |
||||
r = r.replaceAll(' ', ' '); |
||||
} |
||||
return r; |
||||
}) |
||||
.where((final s) => s.isNotEmpty) |
||||
.toList()) { |
||||
if (docLine.startsWith('@')) { |
||||
if (current != '') { |
||||
docParameters.add(current); |
||||
} |
||||
} |
||||
|
||||
if (docLine.startsWith('@return')) { |
||||
current = ''; |
||||
break; |
||||
} |
||||
|
||||
if (docLine.startsWith('@param')) { |
||||
current = docLine; |
||||
} else if (current != '') { |
||||
current += ' $docLine'; |
||||
} |
||||
} |
||||
if (current != '') { |
||||
docParameters.add(current); |
||||
} |
||||
|
||||
final methodParameters = _getMethodParameters( |
||||
controllerName, |
||||
methodName, |
||||
match.group(2)!.split(',').map((final s) => s.trim()).where((final s) => s.isNotEmpty).toList(), |
||||
docParameters, |
||||
); |
||||
|
||||
final parameterNames = RegExp('{[^}]*}').allMatches(url).map((final m) { |
||||
final t = m.group(0)!; |
||||
return t.substring(1, t.length - 1); |
||||
}).toList(); |
||||
|
||||
final parameters = <Parameter>[]; |
||||
for (final parameterName in parameterNames) { |
||||
MethodParameter? parameter; |
||||
for (final methodParameter in methodParameters) { |
||||
if (methodParameter.name == parameterName) { |
||||
parameter = methodParameter; |
||||
break; |
||||
} |
||||
} |
||||
if (parameter == null && (requirements == null || requirements[parameterName] == null)) { |
||||
throw Exception('Could not find parameter for $parameterName in $name'); |
||||
} |
||||
parameters.add( |
||||
Parameter( |
||||
name: parameterName, |
||||
in_: 'path', |
||||
required: true, |
||||
description: parameter?.description, |
||||
schema: { |
||||
'type': parameter?.openAPIType ?? 'TODO', |
||||
if (parameter?.defaultValue != null) ...{ |
||||
'default': parameter?.defaultValue, |
||||
}, |
||||
}, |
||||
), |
||||
); |
||||
} |
||||
final queryParameters = <MethodParameter>[]; |
||||
for (final methodParameter in methodParameters) { |
||||
var found = false; |
||||
for (final parameter in parameters) { |
||||
if (parameter.name == methodParameter.name) { |
||||
found = true; |
||||
break; |
||||
} |
||||
} |
||||
if (!found) { |
||||
queryParameters.add(methodParameter); |
||||
} |
||||
} |
||||
|
||||
if (paths[url] == null) { |
||||
paths[url] = Path( |
||||
parameters: parameters, |
||||
); |
||||
} |
||||
|
||||
final operation = Operation( |
||||
operationID: '${name.replaceAll('#', '-').toLowerCase()}-TODO', |
||||
tags: [id], |
||||
parameters: queryParameters.isNotEmpty |
||||
? queryParameters |
||||
.map<Parameter>( |
||||
(final queryParameter) => Parameter( |
||||
name: queryParameter.name, |
||||
in_: 'query', |
||||
description: queryParameter.description, |
||||
required: !queryParameter.nullable && queryParameter.defaultValue == null, |
||||
schema: queryParameter.openAPIType == 'boolean' |
||||
? { |
||||
// This is a quirk in Nextcloud where sending literal booleans in query parameters doesn't work and only integers work. |
||||
// See https://github.com/nextcloud/server/issues/34226 |
||||
'type': 'integer', |
||||
if (queryParameter.defaultValue != null) ...{ |
||||
'default': queryParameter.defaultValue == 'true' ? 1 : 0, |
||||
}, |
||||
} |
||||
: { |
||||
'type': queryParameter.openAPIType ?? 'TODO', |
||||
if (queryParameter.defaultValue != null) ...{ |
||||
'default': queryParameter.defaultValue, |
||||
}, |
||||
}, |
||||
), |
||||
) |
||||
.toList() |
||||
: null, |
||||
responses: { |
||||
200: Response( |
||||
description: '', |
||||
content: { |
||||
'application/json': MediaType( |
||||
schema: { |
||||
'type': 'string', |
||||
}, |
||||
), |
||||
}, |
||||
), |
||||
}, |
||||
); |
||||
|
||||
switch (verb) { |
||||
case 'DELETE': |
||||
paths[url]!.delete = operation; |
||||
break; |
||||
case 'GET': |
||||
paths[url]!.get = operation; |
||||
break; |
||||
case 'POST': |
||||
paths[url]!.post = operation; |
||||
break; |
||||
case 'PUT': |
||||
paths[url]!.put = operation; |
||||
break; |
||||
case 'PATCH': |
||||
paths[url]!.patch = operation; |
||||
break; |
||||
case 'OPTIONS': |
||||
paths[url]!.options = operation; |
||||
break; |
||||
default: |
||||
throw Exception('Unsupported verb: $verb'); |
||||
} |
||||
} |
||||
} |
||||
|
||||
late String spdxIdentifier; |
||||
switch (license) { |
||||
case 'agpl': |
||||
spdxIdentifier = 'AGPL-3.0'; |
||||
break; |
||||
default: |
||||
throw Exception('Can not convert license name "$license" to a SPDX identifier'); |
||||
} |
||||
|
||||
File( |
||||
p.join( |
||||
'specs', |
||||
'templates', |
||||
'$id.json', |
||||
), |
||||
).writeAsStringSync( |
||||
const JsonEncoder.withIndent(' ').convert( |
||||
Spec( |
||||
version: '3.1.0', |
||||
info: Info( |
||||
title: name, |
||||
version: version, |
||||
description: summary, |
||||
license: License( |
||||
name: license, |
||||
identifier: spdxIdentifier, |
||||
), |
||||
), |
||||
paths: paths, |
||||
).toMap(), |
||||
), |
||||
); |
||||
} |
||||
|
||||
String _getControllerName(final String name) { |
||||
final result = StringBuffer(); |
||||
|
||||
final parts = name.split(''); |
||||
for (var i = 0; i < parts.length; i++) { |
||||
var char = parts[i]; |
||||
final prevChar = i > 0 ? parts[i - 1] : null; |
||||
|
||||
if (char == '_') { |
||||
continue; |
||||
} |
||||
if (i == 0 || prevChar == '_') { |
||||
char = char.toUpperCase(); |
||||
} |
||||
result.write(char); |
||||
} |
||||
|
||||
result.write('Controller'); |
||||
|
||||
return result.toString(); |
||||
} |
||||
|
||||
String _getMethodName(final String name) { |
||||
final result = StringBuffer(); |
||||
|
||||
final parts = name.split(''); |
||||
for (var i = 0; i < parts.length; i++) { |
||||
var char = parts[i]; |
||||
final prevChar = i > 0 ? parts[i - 1] : null; |
||||
|
||||
if (char == '_') { |
||||
continue; |
||||
} |
||||
if (prevChar == '_') { |
||||
char = char.toUpperCase(); |
||||
} |
||||
result.write(char); |
||||
} |
||||
|
||||
return result.toString(); |
||||
} |
||||
|
||||
List<MethodParameter> _getMethodParameters( |
||||
final String controllerName, |
||||
final String methodName, |
||||
final List<String> parameters, |
||||
final List<String> docs, |
||||
) { |
||||
var reg = RegExp(r'@param ((?:[a-z|\[\]]+ )?)(\$?)([a-zA-Z_]+)((?: .*)?)'); |
||||
final docMatches = <RegExpMatch>[]; |
||||
for (final doc in docs) { |
||||
reg.allMatches(doc).forEach(docMatches.add); |
||||
} |
||||
|
||||
final result = <MethodParameter>[]; |
||||
|
||||
reg = RegExp(r'(\??)((?:[a-z-A-Z]+ )?)\$([a-zA-Z_]+)((?: = .*)?)'); |
||||
for (final parameter in parameters) { |
||||
final match = reg.allMatches(parameter).single; |
||||
var nullable = match.group(1)!.isNotEmpty; |
||||
String? type = match.group(2)!.trim(); |
||||
if (type.isEmpty) { |
||||
type = null; |
||||
} |
||||
final name = match.group(3)!; |
||||
final defaultValue = match.group(4)!.replaceAll('=', '').trim(); |
||||
String? description; |
||||
|
||||
for (final doc in docMatches) { |
||||
final docName = doc.group(3)!.trim(); |
||||
if (docName == name) { |
||||
final docType = doc.group(1)!.trim(); |
||||
final docDescription = doc.group(4)!.trim(); |
||||
if (docDescription.isNotEmpty) { |
||||
description = docDescription; |
||||
} |
||||
if (type == null && docType.isNotEmpty) { |
||||
final parts = docType.split('|').where((final p) => p.isNotEmpty); |
||||
if (parts.contains('null')) { |
||||
nullable = true; |
||||
} |
||||
final nonNullableParts = parts.where((final p) => p != 'null'); |
||||
if (nonNullableParts.length > 1) { |
||||
if (nonNullableParts.contains('string')) { |
||||
// Catch all |
||||
type = 'string'; |
||||
continue; |
||||
} |
||||
throw Exception( |
||||
'Can not determine reliable type for "$docType" for parameter "$name" of method "$methodName" in controller "$controllerName"', |
||||
); |
||||
} else { |
||||
type = nonNullableParts.single; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
result.add( |
||||
MethodParameter( |
||||
type: type, |
||||
nullable: nullable, |
||||
name: name, |
||||
defaultValue: defaultValue.isNotEmpty ? defaultValue : null, |
||||
description: description, |
||||
controllerName: controllerName, |
||||
methodName: methodName, |
||||
), |
||||
); |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
Future<Map<String, List<Map<String, dynamic>>>> _parseRoutesFile( |
||||
final Directory tmpDirectory, |
||||
final String path, |
||||
) async { |
||||
final content = File(path).readAsStringSync(); |
||||
|
||||
late String routes; |
||||
if (content.contains('registerRoutes')) { |
||||
routes = RegExp(r'registerRoutes\(\$this, (\[[^;]*)\);').firstMatch(content)!.group(1)!; |
||||
} else if (content.contains('return [')) { |
||||
routes = RegExp(r'return (\[[^;]*);').firstMatch(content)!.group(1)!; |
||||
} else if (content.contains('return array_merge_recursive(')) { |
||||
final includes = RegExp(r"include\(__DIR__ . '/([^']*)'\),") |
||||
.allMatches(RegExp(r'return array_merge_recursive\(\n(.*)\n\);', dotAll: true).firstMatch(content)!.group(1)!) |
||||
.map((final match) => match.group(1)!) |
||||
.toList(); |
||||
|
||||
final out = <String, List<Map<String, dynamic>>>{}; |
||||
for (final include in includes) { |
||||
final routes = await _parseRoutesFile(tmpDirectory, p.join(File(path).parent.path, include)); |
||||
for (final key in routes.keys) { |
||||
if (!out.containsKey(key)) { |
||||
out[key] = []; |
||||
} |
||||
out[key]!.addAll(routes[key]!); |
||||
} |
||||
} |
||||
|
||||
return out; |
||||
} else { |
||||
throw Exception('Unsupported routes format'); |
||||
} |
||||
|
||||
final variables = RegExp(r'^(\$(requirements[a-zA-Z]*) =[^;]*;)$', multiLine: true) |
||||
.allMatches(content) |
||||
.map((final match) => match.group(1)!) |
||||
.toList(); |
||||
|
||||
final phpFile = File(p.join(tmpDirectory.path, p.basename(path))); |
||||
final jsonFile = File(p.join(tmpDirectory.path, p.basename(path).replaceAll('.php', '.json'))); |
||||
|
||||
phpFile.writeAsStringSync( |
||||
''' |
||||
<?php |
||||
${variables.join('\n')} |
||||
|
||||
\$fp = fopen('${jsonFile.path}', 'w'); |
||||
fwrite(\$fp, str_replace("\\/","/",json_encode($routes))); |
||||
fclose(\$fp); |
||||
?> |
||||
''', |
||||
); |
||||
final result = await Process.run('php', [phpFile.path]); |
||||
if (result.exitCode != 0) { |
||||
throw Exception('Failed to run php: ${result.stderr}'); |
||||
} |
||||
|
||||
return (json.decode(jsonFile.readAsStringSync()) as Map<String, dynamic>).map( |
||||
(final key, final value) => MapEntry<String, List<Map<String, dynamic>>>( |
||||
key, |
||||
(value as List).map((final a) => a as Map<String, dynamic>).toList(), |
||||
), |
||||
); |
||||
} |
@ -1,93 +0,0 @@
|
||||
// ignore_for_file: public_member_api_docs |
||||
|
||||
class MethodParameter { |
||||
MethodParameter({ |
||||
required this.type, |
||||
required this.nullable, |
||||
required this.name, |
||||
required final String? defaultValue, |
||||
required this.description, |
||||
required this.controllerName, |
||||
required this.methodName, |
||||
}) { |
||||
if (defaultValue == 'null') { |
||||
nullable = true; |
||||
} |
||||
if (type == null && defaultValue != null && defaultValue != 'null') { |
||||
nullable = false; |
||||
if (int.tryParse(defaultValue) != null) { |
||||
type = 'int'; |
||||
} |
||||
if (defaultValue == 'true' || defaultValue == 'false') { |
||||
type = 'bool'; |
||||
} |
||||
if (defaultValue == "''" || defaultValue == '""') { |
||||
type = 'string'; |
||||
} |
||||
if (defaultValue == '[]') { |
||||
type = 'array'; |
||||
} |
||||
} |
||||
if (type == null) { |
||||
throw Exception( |
||||
'Unknown type for parameter "$name" with default value "$defaultValue" of method "$methodName" in controller "$controllerName"', |
||||
); |
||||
} |
||||
if (defaultValue != null && defaultValue != 'null') { |
||||
switch (type) { |
||||
case 'int': |
||||
this.defaultValue = int.tryParse(defaultValue); |
||||
break; |
||||
case 'bool': |
||||
this.defaultValue = defaultValue == 'true'; |
||||
break; |
||||
case 'string': |
||||
this.defaultValue = defaultValue.substring(1, defaultValue.length - 1); |
||||
break; |
||||
case 'array': |
||||
break; |
||||
default: |
||||
throw Exception('Unknown way to parse default value for type "$type"'); |
||||
} |
||||
} |
||||
} |
||||
|
||||
String? type; |
||||
bool nullable; |
||||
final String name; |
||||
dynamic defaultValue; |
||||
final String? description; |
||||
|
||||
final String controllerName; |
||||
final String methodName; |
||||
|
||||
String? get openAPIType { |
||||
if (type != null) { |
||||
if (type == 'string') { |
||||
return 'string'; |
||||
} |
||||
if (type == 'int' || type == 'integer') { |
||||
return 'integer'; |
||||
} |
||||
if (type == 'bool' || type == 'boolean') { |
||||
return 'boolean'; |
||||
} |
||||
if (type == 'array') { |
||||
return 'array'; |
||||
} |
||||
if (type == 'Chain') { |
||||
// Unsupported |
||||
return null; |
||||
} |
||||
|
||||
throw Exception( |
||||
'Could not infer OpenAPI type from type "$type" for parameter "$name" of method "$methodName" in controller "$controllerName"', |
||||
); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
@override |
||||
String toString() => |
||||
'MethodParameter(type: $type, nullable: $nullable, name: $name, defaultValue: $defaultValue, description: $description, controllerName: $controllerName, methodName: $methodName)'; |
||||
} |
@ -1,253 +0,0 @@
|
||||
// ignore_for_file: public_member_api_docs |
||||
|
||||
class Spec { |
||||
Spec({ |
||||
required this.version, |
||||
required this.info, |
||||
this.tags, |
||||
this.paths, |
||||
}); |
||||
|
||||
Map<String, dynamic> toMap() => { |
||||
'openapi': version, |
||||
'info': info.toMap(), |
||||
if (tags != null) ...{ |
||||
'tags': tags!.map((final tag) => <String, String>{'name': tag}).toList(), |
||||
}, |
||||
if (paths != null) ...{ |
||||
'paths': paths!.map((final key, final value) => MapEntry(key, value.toMap())), |
||||
}, |
||||
}; |
||||
|
||||
final String version; |
||||
final Info info; |
||||
final List<String>? tags; |
||||
final Map<String, Path>? paths; |
||||
} |
||||
|
||||
class Info { |
||||
Info({ |
||||
required this.title, |
||||
required this.version, |
||||
this.description, |
||||
this.license, |
||||
}); |
||||
|
||||
Map<String, dynamic> toMap() => { |
||||
'title': title, |
||||
'version': version, |
||||
if (description != null) 'description': description, |
||||
if (license != null) 'license': license!.toMap(), |
||||
}; |
||||
|
||||
final String title; |
||||
final String version; |
||||
final String? description; |
||||
final License? license; |
||||
} |
||||
|
||||
class License { |
||||
License({ |
||||
required this.name, |
||||
this.identifier, |
||||
this.url, |
||||
}) : assert( |
||||
(identifier == null) != (url == null), |
||||
'Specify either identifier or url', |
||||
); |
||||
|
||||
Map<String, dynamic> toMap() => { |
||||
'name': name, |
||||
if (identifier != null) 'identifier': identifier, |
||||
if (url != null) 'url': url, |
||||
}; |
||||
|
||||
final String name; |
||||
final String? identifier; |
||||
final String? url; |
||||
} |
||||
|
||||
class Server { |
||||
Server({ |
||||
required this.url, |
||||
this.description, |
||||
this.variables, |
||||
}); |
||||
|
||||
final String url; |
||||
final String? description; |
||||
final Map<String, ServerVariable>? variables; |
||||
|
||||
Map<String, dynamic> toMap() => { |
||||
'url': url, |
||||
if (description != null) 'description': description, |
||||
if (variables != null) |
||||
'variables': variables!.map( |
||||
(final key, final value) => MapEntry( |
||||
key, |
||||
value.toMap(), |
||||
), |
||||
), |
||||
}; |
||||
} |
||||
|
||||
class ServerVariable { |
||||
ServerVariable({ |
||||
required this.default_, |
||||
this.enum_, |
||||
this.description, |
||||
}); |
||||
|
||||
final String default_; |
||||
final List<String>? enum_; |
||||
final String? description; |
||||
|
||||
Map<String, dynamic> toMap() => { |
||||
if (enum_ != null) 'enum': enum_, |
||||
'default': default_, |
||||
if (description != null) 'description': description, |
||||
}; |
||||
} |
||||
|
||||
class Path { |
||||
Path({ |
||||
this.summary, |
||||
this.description, |
||||
this.servers, |
||||
this.parameters, |
||||
this.get, |
||||
this.put, |
||||
this.post, |
||||
this.delete, |
||||
this.options, |
||||
this.head, |
||||
this.patch, |
||||
this.trace, |
||||
}); |
||||
|
||||
Map<String, dynamic> toMap() => { |
||||
if (summary != null) 'summary': summary, |
||||
if (description != null) 'description': description, |
||||
if (servers != null) 'servers': servers!.map((final s) => s.toMap()).toList(), |
||||
if (parameters != null && parameters!.isNotEmpty) |
||||
'parameters': parameters!.map((final p) => p.toMap()).toList(), |
||||
if (get != null) 'get': get!.toMap(), |
||||
if (put != null) 'put': put!.toMap(), |
||||
if (post != null) 'post': post!.toMap(), |
||||
if (delete != null) 'delete': delete!.toMap(), |
||||
if (options != null) 'options': options!.toMap(), |
||||
if (head != null) 'head': head!.toMap(), |
||||
if (patch != null) 'patch': patch!.toMap(), |
||||
if (trace != null) 'trace': trace!.toMap(), |
||||
}; |
||||
|
||||
final String? summary; |
||||
final String? description; |
||||
final List<Server>? servers; |
||||
final List<Parameter>? parameters; |
||||
Operation? get; |
||||
Operation? put; |
||||
Operation? post; |
||||
Operation? delete; |
||||
Operation? options; |
||||
Operation? head; |
||||
Operation? patch; |
||||
Operation? trace; |
||||
} |
||||
|
||||
class Parameter { |
||||
Parameter({ |
||||
required this.name, |
||||
required this.in_, |
||||
this.description, |
||||
this.required, |
||||
this.deprecated, |
||||
this.allowEmptyValue, |
||||
this.schema, |
||||
}); |
||||
|
||||
Map<String, dynamic> toMap() => { |
||||
'name': name, |
||||
'in': in_, |
||||
if (description != null) 'description': description, |
||||
if (required != null) 'required': required, |
||||
if (deprecated != null) 'deprecated': deprecated, |
||||
if (allowEmptyValue != null) 'allowEmptyValue': allowEmptyValue, |
||||
if (schema != null) 'schema': schema, |
||||
}; |
||||
|
||||
final String name; |
||||
final String in_; |
||||
final String? description; |
||||
final bool? required; |
||||
final bool? deprecated; |
||||
final bool? allowEmptyValue; |
||||
final Map<String, dynamic>? schema; |
||||
} |
||||
|
||||
class Operation { |
||||
Operation({ |
||||
this.operationID, |
||||
this.tags, |
||||
this.parameters, |
||||
this.responses, |
||||
}); |
||||
|
||||
Map<String, dynamic> toMap() => { |
||||
if (operationID != null) ...{ |
||||
'operationId': operationID, |
||||
}, |
||||
if (tags != null) ...{ |
||||
'tags': tags, |
||||
}, |
||||
if (parameters != null) ...{ |
||||
'parameters': parameters!.map((final p) => p.toMap()).toList(), |
||||
}, |
||||
if (responses != null) ...{ |
||||
'responses': responses!.map( |
||||
(final key, final value) => MapEntry( |
||||
key.toString(), |
||||
value.toMap(), |
||||
), |
||||
), |
||||
}, |
||||
}; |
||||
|
||||
final String? operationID; |
||||
final List<String>? tags; |
||||
final List<Parameter>? parameters; |
||||
final Map<dynamic, Response>? responses; |
||||
} |
||||
|
||||
class Response { |
||||
Response({ |
||||
required this.description, |
||||
this.content, |
||||
}); |
||||
|
||||
Map<String, dynamic> toMap() => { |
||||
'description': description, |
||||
if (content != null) |
||||
'content': content!.map( |
||||
(final key, final value) => MapEntry( |
||||
key, |
||||
value.toMap(), |
||||
), |
||||
), |
||||
}; |
||||
|
||||
final String description; |
||||
final Map<String, MediaType>? content; |
||||
} |
||||
|
||||
class MediaType { |
||||
MediaType({ |
||||
this.schema, |
||||
}); |
||||
|
||||
Map<String, dynamic> toMap() => { |
||||
'schema': schema, |
||||
}; |
||||
|
||||
final Map<String, dynamic>? schema; |
||||
} |
@ -1,16 +0,0 @@
|
||||
name: spec_templates |
||||
version: 1.0.0 |
||||
publish_to: 'none' |
||||
|
||||
environment: |
||||
sdk: '>=3.0.0 <4.0.0' |
||||
|
||||
dependencies: |
||||
path: ^1.8.3 |
||||
xml: ^6.3.0 |
||||
|
||||
dev_dependencies: |
||||
nit_picking: |
||||
git: |
||||
url: https://github.com/stack11/dart_nit_picking |
||||
ref: 0b2ee0d |
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0"?> |
||||
<info xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd"> |
||||
<id>core</id> |
||||
<name>Core</name> |
||||
<summary>Core functionality of Nextcloud</summary> |
||||
<description><![CDATA[Core functionality of Nextcloud]]></description> |
||||
<version>27.0.0</version> |
||||
<licence>agpl</licence> |
||||
</info> |
@ -1,821 +0,0 @@
|
||||
{ |
||||
"openapi": "3.1.0", |
||||
"info": { |
||||
"title": "Notes", |
||||
"version": "4.8.0", |
||||
"description": "Distraction-free notes and writing", |
||||
"license": { |
||||
"name": "agpl", |
||||
"identifier": "AGPL-3.0" |
||||
} |
||||
}, |
||||
"paths": { |
||||
"/apps/notes/notes": { |
||||
"get": { |
||||
"operationId": "notes-index-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"parameters": [ |
||||
{ |
||||
"name": "pruneBefore", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "integer", |
||||
"default": 0 |
||||
} |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"post": { |
||||
"operationId": "notes-create-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"parameters": [ |
||||
{ |
||||
"name": "category", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "string", |
||||
"default": "" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "content", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "string", |
||||
"default": "" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "title", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "string", |
||||
"default": "" |
||||
} |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/apps/notes/notes/dashboard": { |
||||
"get": { |
||||
"operationId": "notes-dashboard-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/apps/notes/notes/{id}": { |
||||
"parameters": [ |
||||
{ |
||||
"name": "id", |
||||
"in": "path", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "integer" |
||||
} |
||||
} |
||||
], |
||||
"get": { |
||||
"operationId": "notes-get-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"put": { |
||||
"operationId": "notes-update-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"parameters": [ |
||||
{ |
||||
"name": "content", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"delete": { |
||||
"operationId": "notes-destroy-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/apps/notes/notes/undo": { |
||||
"post": { |
||||
"operationId": "notes-undo-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"parameters": [ |
||||
{ |
||||
"name": "id", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "integer" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "title", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "content", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "category", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "modified", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "integer" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "favorite", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "integer" |
||||
} |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/apps/notes/notes/{id}/autotitle": { |
||||
"parameters": [ |
||||
{ |
||||
"name": "id", |
||||
"in": "path", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "integer" |
||||
} |
||||
} |
||||
], |
||||
"put": { |
||||
"operationId": "notes-autotitle-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/apps/notes/notes/{id}/{property}": { |
||||
"parameters": [ |
||||
{ |
||||
"name": "id", |
||||
"in": "path", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "integer" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "property", |
||||
"in": "path", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
], |
||||
"put": { |
||||
"operationId": "notes-updateproperty-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"parameters": [ |
||||
{ |
||||
"name": "modified", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "integer" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "title", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "category", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "favorite", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "integer" |
||||
} |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/apps/notes/notes/{noteid}/attachment": { |
||||
"parameters": [ |
||||
{ |
||||
"name": "noteid", |
||||
"in": "path", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "integer" |
||||
} |
||||
} |
||||
], |
||||
"get": { |
||||
"operationId": "notes-getattachment-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"parameters": [ |
||||
{ |
||||
"name": "path", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"post": { |
||||
"operationId": "notes-uploadfile-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/apps/notes/settings": { |
||||
"get": { |
||||
"operationId": "settings-get-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"put": { |
||||
"operationId": "settings-set-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/apps/notes/settings/migrate": { |
||||
"post": { |
||||
"operationId": "settings-migrate-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/apps/notes/api/{apiVersion}/notes": { |
||||
"parameters": [ |
||||
{ |
||||
"name": "apiVersion", |
||||
"in": "path", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "TODO" |
||||
} |
||||
} |
||||
], |
||||
"get": { |
||||
"operationId": "notes_api-index-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"parameters": [ |
||||
{ |
||||
"name": "category", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "exclude", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "string", |
||||
"default": "" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "pruneBefore", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "integer", |
||||
"default": 0 |
||||
} |
||||
}, |
||||
{ |
||||
"name": "chunkSize", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "integer", |
||||
"default": 0 |
||||
} |
||||
}, |
||||
{ |
||||
"name": "chunkCursor", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"post": { |
||||
"operationId": "notes_api-create-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"parameters": [ |
||||
{ |
||||
"name": "category", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "string", |
||||
"default": "" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "title", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "string", |
||||
"default": "" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "content", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "string", |
||||
"default": "" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "modified", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "integer", |
||||
"default": 0 |
||||
} |
||||
}, |
||||
{ |
||||
"name": "favorite", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "integer", |
||||
"default": 0 |
||||
} |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/apps/notes/api/{apiVersion}/notes/{id}": { |
||||
"parameters": [ |
||||
{ |
||||
"name": "apiVersion", |
||||
"in": "path", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "TODO" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "id", |
||||
"in": "path", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "integer" |
||||
} |
||||
} |
||||
], |
||||
"get": { |
||||
"operationId": "notes_api-get-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"parameters": [ |
||||
{ |
||||
"name": "exclude", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "string", |
||||
"default": "" |
||||
} |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"put": { |
||||
"operationId": "notes_api-update-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"parameters": [ |
||||
{ |
||||
"name": "content", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "modified", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "integer" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "title", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "category", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "favorite", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "integer" |
||||
} |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"delete": { |
||||
"operationId": "notes_api-destroy-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/apps/notes/api/{apiVersion}/settings": { |
||||
"parameters": [ |
||||
{ |
||||
"name": "apiVersion", |
||||
"in": "path", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "TODO" |
||||
} |
||||
} |
||||
], |
||||
"get": { |
||||
"operationId": "notes_api-getsettings-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"put": { |
||||
"operationId": "notes_api-setsettings-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/apps/notes/api/{catchAll}": { |
||||
"parameters": [ |
||||
{ |
||||
"name": "catchAll", |
||||
"in": "path", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "TODO" |
||||
} |
||||
} |
||||
], |
||||
"get": { |
||||
"operationId": "notes_api-fail-TODO", |
||||
"tags": [ |
||||
"notes" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,401 +0,0 @@
|
||||
{ |
||||
"openapi": "3.1.0", |
||||
"info": { |
||||
"title": "Notifications", |
||||
"version": "2.15.0", |
||||
"description": "This app provides a backend and frontend for the notification API available in Nextcloud.", |
||||
"license": { |
||||
"name": "agpl", |
||||
"identifier": "AGPL-3.0" |
||||
} |
||||
}, |
||||
"paths": { |
||||
"/ocs/v2.php/apps/notifications/api/{apiVersion}/notifications": { |
||||
"parameters": [ |
||||
{ |
||||
"name": "apiVersion", |
||||
"in": "path", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
], |
||||
"get": { |
||||
"operationId": "endpoint-listnotifications-TODO", |
||||
"tags": [ |
||||
"notifications" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"delete": { |
||||
"operationId": "endpoint-deleteallnotifications-TODO", |
||||
"tags": [ |
||||
"notifications" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/ocs/v2.php/apps/notifications/api/{apiVersion}/notifications/{id}": { |
||||
"parameters": [ |
||||
{ |
||||
"name": "apiVersion", |
||||
"in": "path", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "id", |
||||
"in": "path", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "integer" |
||||
} |
||||
} |
||||
], |
||||
"get": { |
||||
"operationId": "endpoint-getnotification-TODO", |
||||
"tags": [ |
||||
"notifications" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"delete": { |
||||
"operationId": "endpoint-deletenotification-TODO", |
||||
"tags": [ |
||||
"notifications" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/ocs/v2.php/apps/notifications/api/{apiVersion}/notifications/exists": { |
||||
"parameters": [ |
||||
{ |
||||
"name": "apiVersion", |
||||
"in": "path", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
], |
||||
"post": { |
||||
"operationId": "endpoint-confirmidsforuser-TODO", |
||||
"tags": [ |
||||
"notifications" |
||||
], |
||||
"parameters": [ |
||||
{ |
||||
"name": "ids", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "array" |
||||
} |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/ocs/v2.php/apps/notifications/api/{apiVersion}/push": { |
||||
"parameters": [ |
||||
{ |
||||
"name": "apiVersion", |
||||
"in": "path", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "TODO" |
||||
} |
||||
} |
||||
], |
||||
"post": { |
||||
"operationId": "push-registerdevice-TODO", |
||||
"tags": [ |
||||
"notifications" |
||||
], |
||||
"parameters": [ |
||||
{ |
||||
"name": "pushTokenHash", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "devicePublicKey", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "proxyServer", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"delete": { |
||||
"operationId": "push-removedevice-TODO", |
||||
"tags": [ |
||||
"notifications" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/ocs/v2.php/apps/notifications/api/{apiVersion}/admin_notifications/{userId}": { |
||||
"parameters": [ |
||||
{ |
||||
"name": "apiVersion", |
||||
"in": "path", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "TODO" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "userId", |
||||
"in": "path", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
], |
||||
"post": { |
||||
"operationId": "api-generatenotification-TODO", |
||||
"tags": [ |
||||
"notifications" |
||||
], |
||||
"parameters": [ |
||||
{ |
||||
"name": "shortMessage", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "longMessage", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "string", |
||||
"default": "" |
||||
} |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/ocs/v2.php/apps/notifications/api/{apiVersion}/settings": { |
||||
"parameters": [ |
||||
{ |
||||
"name": "apiVersion", |
||||
"in": "path", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "TODO" |
||||
} |
||||
} |
||||
], |
||||
"post": { |
||||
"operationId": "settings-personal-TODO", |
||||
"tags": [ |
||||
"notifications" |
||||
], |
||||
"parameters": [ |
||||
{ |
||||
"name": "batchSetting", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "integer" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "soundNotification", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "soundTalk", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/ocs/v2.php/apps/notifications/api/{apiVersion}/settings/admin": { |
||||
"parameters": [ |
||||
{ |
||||
"name": "apiVersion", |
||||
"in": "path", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "TODO" |
||||
} |
||||
} |
||||
], |
||||
"post": { |
||||
"operationId": "settings-admin-TODO", |
||||
"tags": [ |
||||
"notifications" |
||||
], |
||||
"parameters": [ |
||||
{ |
||||
"name": "batchSetting", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "integer" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "soundNotification", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "soundTalk", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -1,316 +0,0 @@
|
||||
{ |
||||
"openapi": "3.1.0", |
||||
"info": { |
||||
"title": "User status", |
||||
"version": "1.7.0", |
||||
"description": "User status", |
||||
"license": { |
||||
"name": "agpl", |
||||
"identifier": "AGPL-3.0" |
||||
} |
||||
}, |
||||
"paths": { |
||||
"/ocs/v2.php/apps/user_status/api/v1/statuses": { |
||||
"get": { |
||||
"operationId": "statuses-findall-TODO", |
||||
"tags": [ |
||||
"user_status" |
||||
], |
||||
"parameters": [ |
||||
{ |
||||
"name": "limit", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "integer" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "offset", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "integer" |
||||
} |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/ocs/v2.php/apps/user_status/api/v1/statuses/{userId}": { |
||||
"parameters": [ |
||||
{ |
||||
"name": "userId", |
||||
"in": "path", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
], |
||||
"get": { |
||||
"operationId": "statuses-find-TODO", |
||||
"tags": [ |
||||
"user_status" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/ocs/v2.php/apps/user_status/api/v1/user_status": { |
||||
"get": { |
||||
"operationId": "userstatus-getstatus-TODO", |
||||
"tags": [ |
||||
"user_status" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/ocs/v2.php/apps/user_status/api/v1/user_status/status": { |
||||
"put": { |
||||
"operationId": "userstatus-setstatus-TODO", |
||||
"tags": [ |
||||
"user_status" |
||||
], |
||||
"parameters": [ |
||||
{ |
||||
"name": "statusType", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/ocs/v2.php/apps/user_status/api/v1/user_status/message/predefined": { |
||||
"put": { |
||||
"operationId": "userstatus-setpredefinedmessage-TODO", |
||||
"tags": [ |
||||
"user_status" |
||||
], |
||||
"parameters": [ |
||||
{ |
||||
"name": "messageId", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "clearAt", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "integer" |
||||
} |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/ocs/v2.php/apps/user_status/api/v1/user_status/message/custom": { |
||||
"put": { |
||||
"operationId": "userstatus-setcustommessage-TODO", |
||||
"tags": [ |
||||
"user_status" |
||||
], |
||||
"parameters": [ |
||||
{ |
||||
"name": "statusIcon", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "message", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
}, |
||||
{ |
||||
"name": "clearAt", |
||||
"in": "query", |
||||
"required": false, |
||||
"schema": { |
||||
"type": "integer" |
||||
} |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/ocs/v2.php/apps/user_status/api/v1/user_status/message": { |
||||
"delete": { |
||||
"operationId": "userstatus-clearmessage-TODO", |
||||
"tags": [ |
||||
"user_status" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/ocs/v2.php/apps/user_status/api/v1/user_status/revert/{messageId}": { |
||||
"parameters": [ |
||||
{ |
||||
"name": "messageId", |
||||
"in": "path", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
], |
||||
"delete": { |
||||
"operationId": "userstatus-revertstatus-TODO", |
||||
"tags": [ |
||||
"user_status" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/ocs/v2.php/apps/user_status/api/v1/predefined_statuses": { |
||||
"get": { |
||||
"operationId": "predefinedstatus-findall-TODO", |
||||
"tags": [ |
||||
"user_status" |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"/ocs/v2.php/apps/user_status/api/v1/heartbeat": { |
||||
"put": { |
||||
"operationId": "heartbeat-heartbeat-TODO", |
||||
"tags": [ |
||||
"user_status" |
||||
], |
||||
"parameters": [ |
||||
{ |
||||
"name": "status", |
||||
"in": "query", |
||||
"required": true, |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
], |
||||
"responses": { |
||||
"200": { |
||||
"description": "", |
||||
"content": { |
||||
"application/json": { |
||||
"schema": { |
||||
"type": "string" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,125 +0,0 @@
|
||||
#!/bin/bash |
||||
set -euxo pipefail |
||||
cd "$(dirname "$0")/.." |
||||
|
||||
rm -rf /tmp/nextcloud-neon |
||||
mkdir -p /tmp/nextcloud-neon |
||||
|
||||
xmlstarlet \ |
||||
edit \ |
||||
--update "/info/version" \ |
||||
--value "$(cd external/nextcloud-server && git describe --tags | sed "s/^v//")" \ |
||||
specs/templates/appinfo_core.xml \ |
||||
> /tmp/nextcloud-neon/appinfo_core1.xml |
||||
xmlstarlet \ |
||||
format \ |
||||
--indent-spaces 4 \ |
||||
/tmp/nextcloud-neon/appinfo_core1.xml \ |
||||
> /tmp/nextcloud-neon/appinfo_core2.xml |
||||
cp /tmp/nextcloud-neon/appinfo_core2.xml specs/templates/appinfo_core.xml |
||||
|
||||
function generate_spec_templates() { |
||||
fvm dart packages/spec_templates/bin/generate.dart "$1" "$2" |
||||
} |
||||
|
||||
generate_spec_templates external/nextcloud-news false |
||||
generate_spec_templates external/nextcloud-notes false |
||||
generate_spec_templates external/nextcloud-notifications false |
||||
generate_spec_templates external/nextcloud-server/apps/provisioning_api false |
||||
generate_spec_templates external/nextcloud-server/apps/user_status false |
||||
generate_spec_templates external/nextcloud-server/core true |
||||
|
||||
codenames=(core news notes notifications provisioning_api user_status) |
||||
|
||||
for codename in ${codenames[*]}; do |
||||
jq \ |
||||
--arg codename "$codename" \ |
||||
-s \ |
||||
'{ |
||||
openapi: .[0].openapi, |
||||
info: .[0].info, |
||||
servers: [ |
||||
{ |
||||
url: "https://{hostname}:{port}", |
||||
variables: { |
||||
hostname: { |
||||
default: "localhost" |
||||
}, |
||||
port: { |
||||
default: "8080" |
||||
} |
||||
} |
||||
} |
||||
], |
||||
security: [ |
||||
{ |
||||
basic_auth: [] |
||||
} |
||||
], |
||||
tags: .[1].tags, |
||||
components: { |
||||
schemas: .[1].components.schemas |
||||
}, |
||||
paths: .[1].paths |
||||
} | |
||||
.components.securitySchemes = { |
||||
basic_auth: { |
||||
type: "http", |
||||
scheme: "basic", |
||||
}, |
||||
} | |
||||
.components.schemas.OCSMeta = |
||||
{ |
||||
type: "object", |
||||
required: [ |
||||
"status", |
||||
"statuscode" |
||||
], |
||||
properties: { |
||||
status: { |
||||
type: "string" |
||||
}, |
||||
statuscode: { |
||||
type: "integer" |
||||
}, |
||||
message: { |
||||
type: "string" |
||||
}, |
||||
totalitems: { |
||||
type: "string" |
||||
}, |
||||
itemsperpage: { |
||||
type: "string" |
||||
} |
||||
} |
||||
} | |
||||
.components.schemas.EmptyOCS = |
||||
{ |
||||
type: "object", |
||||
required: [ |
||||
"ocs" |
||||
], |
||||
properties: { |
||||
ocs: { |
||||
type: "object", |
||||
required: [ |
||||
"meta", |
||||
"data" |
||||
], |
||||
properties: { |
||||
meta: { |
||||
"$ref": "#/components/schemas/OCSMeta" |
||||
}, |
||||
data: { |
||||
type: "array" |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
' \ |
||||
specs/templates/"$codename".json \ |
||||
specs/"$codename".json \ |
||||
> /tmp/nextcloud-neon/"$codename".json |
||||
cp /tmp/nextcloud-neon/"$codename".json specs/"$codename".json |
||||
done |
Loading…
Reference in new issue