diff options
-rw-r--r-- | _exts/typescriptdomain.py | 342 | ||||
-rw-r--r-- | taler-wallet.rst | 63 |
2 files changed, 247 insertions, 158 deletions
diff --git a/_exts/typescriptdomain.py b/_exts/typescriptdomain.py index ce21b3b0..68777645 100644 --- a/_exts/typescriptdomain.py +++ b/_exts/typescriptdomain.py @@ -17,7 +17,7 @@ from pygments.filter import Filter from pygments.token import Literal, Text, Operator, Keyword, Name, Number from pygments.token import Comment, Token, _TokenType from pygments.token import * -from pygments.lexer import RegexLexer, bygroups, include +from pygments.lexer import RegexLexer, bygroups, include from pygments.formatters import HtmlFormatter from docutils import nodes @@ -47,30 +47,30 @@ class TypeScriptDefinition(SphinxDirective): optional_arguments = 0 final_argument_whitespace = False option_spec = { - 'force': directives.flag, - 'linenos': directives.flag, - 'dedent': int, - 'lineno-start': int, - 'emphasize-lines': directives.unchanged_required, - 'caption': directives.unchanged_required, - 'class': directives.class_option, + "force": directives.flag, + "linenos": directives.flag, + "dedent": int, + "lineno-start": int, + "emphasize-lines": directives.unchanged_required, + "caption": directives.unchanged_required, + "class": directives.class_option, } def run(self) -> List[Node]: document = self.state.document - code = '\n'.join(self.content) + code = "\n".join(self.content) location = self.state_machine.get_source_and_line(self.lineno) - linespec = self.options.get('emphasize-lines') + linespec = self.options.get("emphasize-lines") if linespec: try: nlines = len(self.content) hl_lines = parselinenos(linespec, nlines) if any(i >= nlines for i in hl_lines): logger.warning( - __('line number spec is out of range(1-%d): %r') % - (nlines, self.options['emphasize-lines']), - location=location + __("line number spec is out of range(1-%d): %r") + % (nlines, self.options["emphasize-lines"]), + location=location, ) hl_lines = [x + 1 for x in hl_lines if x < nlines] @@ -79,28 +79,26 @@ class TypeScriptDefinition(SphinxDirective): else: hl_lines = None - if 'dedent' in self.options: + if "dedent" in self.options: location = self.state_machine.get_source_and_line(self.lineno) - lines = code.split('\n') - lines = dedent_lines( - lines, self.options['dedent'], location=location - ) - code = '\n'.join(lines) + lines = code.split("\n") + lines = dedent_lines(lines, self.options["dedent"], location=location) + code = "\n".join(lines) literal = nodes.literal_block(code, code) # type: Element - if 'linenos' in self.options or 'lineno-start' in self.options: - literal['linenos'] = True - literal['classes'] += self.options.get('class', []) - literal['force'] = 'force' in self.options - literal['language'] = "tsref" - extra_args = literal['highlight_args'] = {} + if "linenos" in self.options or "lineno-start" in self.options: + literal["linenos"] = True + literal["classes"] += self.options.get("class", []) + literal["force"] = "force" in self.options + literal["language"] = "tsref" + extra_args = literal["highlight_args"] = {} if hl_lines is not None: - extra_args['hl_lines'] = hl_lines - if 'lineno-start' in self.options: - extra_args['linenostart'] = self.options['lineno-start'] + extra_args["hl_lines"] = hl_lines + if "lineno-start" in self.options: + extra_args["linenostart"] = self.options["lineno-start"] self.set_source_info(literal) - caption = self.options.get('caption') + caption = self.options.get("caption") if caption: try: literal = container_wrapper(self, literal, caption) @@ -108,11 +106,11 @@ class TypeScriptDefinition(SphinxDirective): return [document.reporter.warning(exc, line=self.lineno)] tsid = "tsref-type-" + self.arguments[0] - literal['ids'].append(tsid) + literal["ids"].append(tsid) tsname = self.arguments[0] - ts = self.env.get_domain('ts') - ts.add_object('type', tsname, self.env.docname, tsid) + ts = self.env.get_domain("ts") + ts.add_object("type", tsname, self.env.docname, tsid) return [literal] @@ -120,27 +118,24 @@ class TypeScriptDefinition(SphinxDirective): class TypeScriptDomain(Domain): """TypeScript domain.""" - name = 'ts' - label = 'TypeScript' + name = "ts" + label = "TypeScript" directives = { - 'def': TypeScriptDefinition, + "def": TypeScriptDefinition, } roles = { - 'type': - XRefRole( + "type": XRefRole( lowercase=False, warn_dangling=True, innernodeclass=nodes.inline ), } dangling_warnings = { - 'type': 'undefined TypeScript type: %(target)s', + "type": "undefined TypeScript type: %(target)s", } - def resolve_xref( - self, env, fromdocname, builder, typ, target, node, contnode - ): + def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): try: info = self.objects[(str(typ), str(target))] except KeyError: @@ -148,14 +143,10 @@ class TypeScriptDomain(Domain): return None else: anchor = "tsref-type-{}".format(str(target)) - title = typ.upper() + ' ' + target - return make_refnode( - builder, fromdocname, info[0], anchor, contnode, title - ) + title = typ.upper() + " " + target + return make_refnode(builder, fromdocname, info[0], anchor, contnode, title) - def resolve_any_xref( - self, env, fromdocname, builder, target, node, contnode - ): + def resolve_any_xref(self, env, fromdocname, builder, target, node, contnode): """Resolve the pending_xref *node* with the given *target*. The reference comes from an "any" or similar role, which means that Sphinx @@ -174,22 +165,18 @@ class TypeScriptDomain(Domain): pass else: anchor = "tsref-type-{}".format(str(target)) - title = "TYPE" + ' ' + target - node = make_refnode( - builder, fromdocname, info[0], anchor, contnode, title - ) + title = "TYPE" + " " + target + node = make_refnode(builder, fromdocname, info[0], anchor, contnode, title) ret.append(("ts:type", node)) return ret @property def objects(self) -> Dict[Tuple[str, str], Tuple[str, str]]: return self.data.setdefault( - 'objects', {} + "objects", {} ) # (objtype, name) -> docname, labelid - def add_object( - self, objtype: str, name: str, docname: str, labelid: str - ) -> None: + def add_object(self, objtype: str, name: str, docname: str, labelid: str) -> None: self.objects[objtype, name] = (docname, labelid) @@ -198,101 +185,114 @@ class BetterTypeScriptLexer(RegexLexer): For `TypeScript <https://www.typescriptlang.org/>`_ source code. """ - name = 'TypeScript' - aliases = ['ts'] - filenames = ['*.ts'] - mimetypes = ['text/x-typescript'] + name = "TypeScript" + aliases = ["ts"] + filenames = ["*.ts"] + mimetypes = ["text/x-typescript"] flags = re.DOTALL tokens = { - 'commentsandwhitespace': [(r'\s+', Text), (r'<!--', Comment), - (r'//.*?\n', Comment.Single), - (r'/\*.*?\*/', Comment.Multiline)], - 'slashstartsregex': [ - include('commentsandwhitespace'), + "commentsandwhitespace": [ + (r"\s+", Text), + (r"<!--", Comment), + (r"//.*?\n", Comment.Single), + (r"/\*.*?\*/", Comment.Multiline), + ], + "slashstartsregex": [ + include("commentsandwhitespace"), ( - r'/(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/' - r'([gim]+\b|\B)', String.Regex, '#pop' - ), (r'(?=/)', Text, ('#pop', 'badregex')), (r'', Text, '#pop') + r"/(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/" r"([gim]+\b|\B)", + String.Regex, + "#pop", + ), + (r"(?=/)", Text, ("#pop", "badregex")), + (r"", Text, "#pop"), ], - 'badregex': [(r'\n', Text, '#pop')], - 'typeexp': [ - (r'[a-zA-Z0-9_?.$]+', Keyword.Type), - (r'\s+', Text), - (r'[|]', Text), - (r'\n', Text, "#pop"), - (r';', Text, "#pop"), - (r'', Text, "#pop"), + "badregex": [(r"\n", Text, "#pop")], + "typeexp": [ + (r"[a-zA-Z0-9_?.$]+", Keyword.Type), + (r"\s+", Text), + (r"[|]", Text), + (r"\n", Text, "#pop"), + (r";", Text, "#pop"), + (r"", Text, "#pop"), ], - 'root': [ - (r'^(?=\s|/|<!--)', Text, 'slashstartsregex'), - include('commentsandwhitespace'), + "root": [ + (r"^(?=\s|/|<!--)", Text, "slashstartsregex"), + include("commentsandwhitespace"), ( - r'\+\+|--|~|&&|\?|:|\|\||\\(?=\n)|' - r'(<<|>>>?|==?|!=?|[-<>+*%&\|\^/])=?', Operator, - 'slashstartsregex' + r"\+\+|--|~|&&|\?|:|\|\||\\(?=\n)|" + r"(<<|>>>?|==?|!=?|[-<>+*%&\|\^/])=?", + Operator, + "slashstartsregex", ), - (r'[{(\[;,]', Punctuation, 'slashstartsregex'), - (r'[})\].]', Punctuation), + (r"[{(\[;,]", Punctuation, "slashstartsregex"), + (r"[})\].]", Punctuation), ( - r'(for|in|while|do|break|return|continue|switch|case|default|if|else|' - r'throw|try|catch|finally|new|delete|typeof|instanceof|void|' - r'this)\b', Keyword, 'slashstartsregex' + r"(for|in|while|do|break|return|continue|switch|case|default|if|else|" + r"throw|try|catch|finally|new|delete|typeof|instanceof|void|" + r"this)\b", + Keyword, + "slashstartsregex", ), ( - r'(var|let|const|with|function)\b', Keyword.Declaration, - 'slashstartsregex' + r"(var|let|const|with|function)\b", + Keyword.Declaration, + "slashstartsregex", ), ( - r'(abstract|boolean|byte|char|class|const|debugger|double|enum|export|' - r'extends|final|float|goto|implements|import|int|interface|long|native|' - r'package|private|protected|public|short|static|super|synchronized|throws|' - r'transient|volatile)\b', Keyword.Reserved + r"(abstract|boolean|byte|char|class|const|debugger|double|enum|export|" + r"extends|final|float|goto|implements|import|int|interface|long|native|" + r"package|private|protected|public|short|static|super|synchronized|throws|" + r"transient|volatile)\b", + Keyword.Reserved, ), - (r'(true|false|null|NaN|Infinity|undefined)\b', Keyword.Constant), + (r"(true|false|null|NaN|Infinity|undefined)\b", Keyword.Constant), ( - r'(Array|Boolean|Date|Error|Function|Math|netscape|' - r'Number|Object|Packages|RegExp|String|sun|decodeURI|' - r'decodeURIComponent|encodeURI|encodeURIComponent|' - r'Error|eval|isFinite|isNaN|parseFloat|parseInt|document|this|' - r'window)\b', Name.Builtin + r"(Array|Boolean|Date|Error|Function|Math|netscape|" + r"Number|Object|Packages|RegExp|String|sun|decodeURI|" + r"decodeURIComponent|encodeURI|encodeURIComponent|" + r"Error|eval|isFinite|isNaN|parseFloat|parseInt|document|this|" + r"window)\b", + Name.Builtin, ), # Match stuff like: module name {...} ( - r'\b(module)(\s*)(\s*[a-zA-Z0-9_?.$][\w?.$]*)(\s*)', - bygroups(Keyword.Reserved, Text, Name.Other, - Text), 'slashstartsregex' + r"\b(module)(\s*)(\s*[a-zA-Z0-9_?.$][\w?.$]*)(\s*)", + bygroups(Keyword.Reserved, Text, Name.Other, Text), + "slashstartsregex", ), # Match variable type keywords - (r'\b(string|bool|number)\b', Keyword.Type), + (r"\b(string|bool|number)\b", Keyword.Type), # Match stuff like: constructor - (r'\b(constructor|declare|interface|as|AS)\b', Keyword.Reserved), + (r"\b(constructor|declare|interface|as|AS)\b", Keyword.Reserved), # Match stuff like: super(argument, list) ( - r'(super)(\s*)\(([a-zA-Z0-9,_?.$\s]+\s*)\)', - bygroups(Keyword.Reserved, Text), 'slashstartsregex' + r"(super)(\s*)\(([a-zA-Z0-9,_?.$\s]+\s*)\)", + bygroups(Keyword.Reserved, Text), + "slashstartsregex", ), # Match stuff like: function() {...} - (r'([a-zA-Z_?.$][\w?.$]*)\(\) \{', Name.Other, 'slashstartsregex'), + (r"([a-zA-Z_?.$][\w?.$]*)\(\) \{", Name.Other, "slashstartsregex"), # Match stuff like: (function: return type) ( - r'([a-zA-Z0-9_?.$][\w?.$]*)(\s*:\s*)', - bygroups(Name.Other, Text), 'typeexp' + r"([a-zA-Z0-9_?.$][\w?.$]*)(\s*:\s*)", + bygroups(Name.Other, Text), + "typeexp", ), # Match stuff like: type Foo = Bar | Baz ( - r'\b(type)(\s*)([a-zA-Z0-9_?.$]+)(\s*)(=)(\s*)', - bygroups( - Keyword.Reserved, Text, Name.Other, Text, Operator, Text - ), 'typeexp' + r"\b(type)(\s*)([a-zA-Z0-9_?.$]+)(\s*)(=)(\s*)", + bygroups(Keyword.Reserved, Text, Name.Other, Text, Operator, Text), + "typeexp", ), - (r'[$a-zA-Z_][a-zA-Z0-9_]*', Name.Other), - (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float), - (r'0x[0-9a-fA-F]+', Number.Hex), - (r'[0-9]+', Number.Integer), + (r"[$a-zA-Z_][a-zA-Z0-9_]*", Name.Other), + (r"[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?", Number.Float), + (r"0x[0-9a-fA-F]+", Number.Hex), + (r"[0-9]+", Number.Integer), (r'"(\\\\|\\"|[^"])*"', String.Double), (r"'(\\\\|\\'|[^'])*'", String.Single), - ] + ], } @@ -310,7 +310,7 @@ class LinkFilter(Filter): def _filter_one_literal(self, ttype, value): last = 0 for m in re.finditer(literal_reg, value): - pre = value[last:m.start()] + pre = value[last : m.start()] if pre: yield ttype, pre t = copy_token(ttype) @@ -321,7 +321,6 @@ class LinkFilter(Filter): if post: yield ttype, post - def filter(self, lexer, stream): for ttype, value in stream: if ttype in Token.Keyword.Type: @@ -332,7 +331,7 @@ class LinkFilter(Filter): elif ttype in Token.Comment: last = 0 for m in re.finditer(link_reg, value): - pre = value[last:m.start()] + pre = value[last : m.start()] if pre: yield from self._filter_one_literal(ttype, pre) t = copy_token(ttype) @@ -358,19 +357,19 @@ class LinkFilter(Filter): _escape_html_table = { - ord('&'): u'&', - ord('<'): u'<', - ord('>'): u'>', - ord('"'): u'"', - ord("'"): u''', + ord("&"): u"&", + ord("<"): u"<", + ord(">"): u">", + ord('"'): u""", + ord("'"): u"'", } class LinkingHtmlFormatter(HtmlFormatter): def __init__(self, **kwargs): super(LinkingHtmlFormatter, self).__init__(**kwargs) - self._builder = kwargs['_builder'] - self._bridge = kwargs['_bridge'] + self._builder = kwargs["_builder"] + self._bridge = kwargs["_bridge"] def _get_value(self, value, tok): xref = tok_getprop(tok, "xref") @@ -381,8 +380,9 @@ class LinkingHtmlFormatter(HtmlFormatter): if tok_getprop(tok, "trailing_underscore"): logger.warn( - "{}:{}: code block contains xref to '{}' with unsupported trailing underscore" - .format(self._bridge.path, self._bridge.line, xref) + "{}:{}: code block contains xref to '{}' with unsupported trailing underscore".format( + self._bridge.path, self._bridge.line, xref + ) ) if tok_getprop(tok, "is_identifier"): @@ -390,39 +390,69 @@ class LinkingHtmlFormatter(HtmlFormatter): return value if re.match("^[0-9]+$", xref) is not None: return value - if xref in ("number", "object", "string", "boolean", "any", "true", "false", "null", "undefined", "Array"): + if xref in ( + "number", + "object", + "string", + "boolean", + "any", + "true", + "false", + "null", + "undefined", + "Array", + "unknown", + ): return value if xref is None: return value content = caption if caption is not None else value - ts = self._builder.env.get_domain('ts') + ts = self._builder.env.get_domain("ts") r1 = ts.objects.get(("type", xref), None) if r1 is not None: - rel_uri = self._builder.get_relative_uri(self._bridge.docname, r1[0]) + "#" + r1[1] - return '<a style="color:inherit;text-decoration:underline" href="%s">%s</a>' % ( - rel_uri, content + rel_uri = ( + self._builder.get_relative_uri(self._bridge.docname, r1[0]) + + "#" + + r1[1] + ) + return ( + '<a style="color:inherit;text-decoration:underline" href="%s">%s</a>' + % (rel_uri, content) ) - std = self._builder.env.get_domain('std') + std = self._builder.env.get_domain("std") r2 = std.labels.get(xref.lower(), None) if r2 is not None: - rel_uri = self._builder.get_relative_uri(self._bridge.docname, r2[0]) + "#" + r2[1] - return '<a style="color:inherit;text-decoration:underline" href="%s">%s</a>' % ( - rel_uri, content + rel_uri = ( + self._builder.get_relative_uri(self._bridge.docname, r2[0]) + + "#" + + r2[1] + ) + return ( + '<a style="color:inherit;text-decoration:underline" href="%s">%s</a>' + % (rel_uri, content) ) r3 = std.anonlabels.get(xref.lower(), None) if r3 is not None: - rel_uri = self._builder.get_relative_uri(self._bridge.docname, r3[0]) + "#" + r3[1] - return '<a style="color:inherit;text-decoration:underline" href="%s">%s</a>' % ( - rel_uri, content + rel_uri = ( + self._builder.get_relative_uri(self._bridge.docname, r3[0]) + + "#" + + r3[1] + ) + return ( + '<a style="color:inherit;text-decoration:underline" href="%s">%s</a>' + % (rel_uri, content) ) - logger.warn("{}:{}: code block contains unresolved xref '{}'".format(self._bridge.path, self._bridge.line, xref)) + logger.warn( + "{}:{}: code block contains unresolved xref '{}'".format( + self._bridge.path, self._bridge.line, xref + ) + ) return value - def _fmt(self, value, tok): cls = self._get_css_class(tok) value = self._get_value(value, tok) @@ -438,11 +468,11 @@ class LinkingHtmlFormatter(HtmlFormatter): lsep = self.lineseparator escape_table = _escape_html_table - line = '' + line = "" for ttype, value in tokensource: link = get_annotation(ttype, "link") - parts = value.translate(escape_table).split('\n') + parts = value.translate(escape_table).split("\n") if len(parts) == 0: # empty token, usually should not happen @@ -466,9 +496,9 @@ class MyPygmentsBridge(PygmentsBridge): self.dest = "html" self.trim_doctest_flags = trim_doctest_flags self.formatter_args = { - 'style': SphinxStyle, - '_builder': builder, - '_bridge': self + "style": SphinxStyle, + "_builder": builder, + "_bridge": self, } self.formatter = LinkingHtmlFormatter self.builder = builder @@ -483,9 +513,7 @@ class MyPygmentsBridge(PygmentsBridge): self.line = line self.path = self.builder.env.doc2path(docname) self.docname = docname - return super().highlight_block( - source, lang, opts, force, location, **kwargs - ) + return super().highlight_block(source, lang, opts, force, location, **kwargs) class MyHtmlBuilder(StandaloneHTMLBuilder): @@ -495,12 +523,10 @@ class MyHtmlBuilder(StandaloneHTMLBuilder): if self.config.pygments_style is not None: style = self.config.pygments_style elif self.theme: - style = self.theme.get_confstr('theme', 'pygments_style', 'none') + style = self.theme.get_confstr("theme", "pygments_style", "none") else: - style = 'sphinx' - self.highlighter = MyPygmentsBridge( - self, self.config.trim_doctest_flags - ) + style = "sphinx" + self.highlighter = MyPygmentsBridge(self, self.config.trim_doctest_flags) self.dark_highlighter = None @@ -543,6 +569,6 @@ literal_reg = re.compile(r"``([^`]+)``") def setup(app): lexer = BetterTypeScriptLexer() lexer.add_filter(LinkFilter(app)) - app.add_lexer('tsref', lexer) + app.add_lexer("tsref", lexer) app.add_domain(TypeScriptDomain) app.add_builder(MyHtmlBuilder) diff --git a/taler-wallet.rst b/taler-wallet.rst index 78daad1a..2ac95df6 100644 --- a/taler-wallet.rst +++ b/taler-wallet.rst @@ -86,6 +86,69 @@ APIs and Data Formats These APIs are still a work in progress and *not* final. +Envelope Format +--------------- + +All API responses and notifications are returned in the +following envelope: + +.. ts:def:: WalletCoreResponseEnvelope + + type WalletCoreResponseEnvelope = + | WalletCoreSuccess + | WalletCoreError + | WalletCoreNotification + +.. ts:def:: WalletCoreSuccess + + export interface WalletCoreSuccess { + type: "response"; + operation: string, + // ID to correlate success response to request + id: string; + // Result type depends on operation + result: unknown; + } + +.. ts:def:: WalletCoreError + + export interface WalletCoreError { + type: "error"; + operation: string, + // ID to correlate success response to request + id: string; + error: WalletCoreErrorInfo; + } + +.. ts:def:: WalletCoreNotification + + export interface WalletCoreSuccess { + type: "notification"; + + // actual type is WalletNotification, + // to be documented here + payload: any; + } + +.. ts:def:: WalletCoreErrorInfo + + export interface WalletCoreErrorInfo { + // Numeric error code defined defined in the + // GANA gnu-taler-error-codes registry. + talerErrorCode: number; + + // English description of the error code. + talerErrorHint: string; + + // English diagnostic message that can give details + // for the instance of the error. + message: string; + + // Error details, type depends + // on talerErrorCode + details: unknown; + } + Balances -------- |