Add django 1.11 support

Will close #83.
Issue is django removed the format_output method from forms.MultiWidget, see https://docs.djangoproject.com/en/1.11/releases/1.11/#changes-due-to-the-introduction-of-template-based-widget-rendering.
I've tried to keep support for both >1.11 and <=1.10 by adding a template_name and get_context to GeopositionWidget but leaving the existing format_output.
It's working on 1.11, have not checked on 1.10 or 1.8.

Thanks @wjdp for this!!
I'm merging this into a django-1.11 branch first in order to change the test settings and include 1.11 before merging into master.

[...] change the test settings and include 1.11 before merging into master.

Done in #86 :)


no full screen view on mac version?

Original ticket:
https://sourceforge.net/p/djv/bugs/22/

Hopefully this is now fixed with GLFW_COCOA_RETINA_FRAMEBUFFER.

This should be fixed now in the master branch and will be included with the next release.


Raspberry Pi version

Works great, if you replace the phantomjs64 with a compiled binary for the arm processor.  Dropping this into the phantom-bin directory named phantomjs64 let's it work just fine.  You may want to include it in your original download. There are a few precomplied binaries out there in github, as it takes about 2 days to compile on that platform: https://github.com/aeberhardo/phantomjs-linux-armv6l

Great, thanks. When i have time to do it i will add this to ingress-ice.
Thank you!

Hm, sorry... I think i won't add it to ingress-ice — PhantomJS 1.9.6 is AFAIR the least ice requires :(

Here is another project that has compiled the 2.x version of phantomjs for the Raspberry Pi.  https://github.com/spfaffly/phantomjs-linux-armv6l  Don't need it myself (I already have a running copy), but others may want.

Oh, thanks, this one should work :+1:

Done in 7f57fcbafc248f937a333dba0fbcb3baf4f777d7


Get Going instructions vague and possibly incorrect

I performed the following:
mkdir jspmtest && cd jspmtest
npm install -g gulp jspm
npm install
jspm install (follow prompts and accept defaults)
Running gulp serve returns No gulpfile found.
Questions

Do I run jspm install from a current app root that already has a gulpfile.js?
** If so, will PR.js highjack or override my existing gulp serve task?
How is setting up PR.js locally differ from the hosted version (https://radify.github.io/)?
** If I set up PR.js locally, will I be able to use my private repository?

I performed the following [...]

My experience has always been that installation instructions are assumed to be run from the project directory, after cloning. I'm open to suggestions on how to make it more clear that this is the intent.

Do I run jspm install from a current app root that already has a gulpfile.js? ** If so, will PR.js highjack or override my existing gulp serve task?

Nope, JSPM works just like NPM. You clone the project and install dependencies. It has its own independent Gulpfile.

How is setting up PR.js locally differ from the hosted version (https://radify.github.io/)?

Right now the only benefit to cloning it locally is to hack on the validation rules or contribute to tasks on the roadmap. :smile:

If I set up PR.js locally, will I be able to use my private repository?

Nope, we need to add GitHub auth for that (also on the roadmap). Should have time to implement it soon.

Cf. #12.


Ensure disable search bar on input blur

Sorry, why that? Check for example search in native iOS mail app, it shouldn't be disabled on blur as you won't be able to scroll through search results. As for the case when searchbar overlay is visible (no search) it will be disabled when you click on it. Or did i miss something?

Open the search bar page in the kitchen-sink-ios example. While the input search is focused (but empty), the overlay is visible (as expected) and if you press the menu button, it is revealed, but the overlay still visible. If the focus on the search input is lost, I can imagine that the user no longer has interest in search. Obviously the user can tap on the overlay to hide it, but why this additional task? It is only my opinion about the minimum user actions required to complete a task.

If the focus on the search input is lost

Or user just swipes over search results. So it still a question for me

If the user swipes over search results, the search bar bar is not disabled by the blur event handler: https://github.com/mgesmundo/Framework7/blob/fix-searchbar/src/js/searchbar.js#L208.

But this is still incomplete solution. What if there are links in your searchbar-found links, and if you open another page, and later go back to the page with search results, it will be disabled. Or if you tap close to list-block with results on empty are of the page, it will be disabled again. I guess, we should leave it to app developer decision when he wants to disable it

I agree with your consideration: I will add an option to enable/disable this behavior.

Should this be closed? Its 2 years later and it does seem to introduce some odd behaviour


GitHub request to get the latest version of Dependency

Check is we have any option to get the latest version from generic scope registry

Haven't found a way how to do that, so let's close so far.


final project report - DRAFT

due 4/12/2018
transition plan:

code can remain in github with MIT license
document both API and Alexa skill with README
transition alexa skill to GE while keeping it in developer mode (no submission to alexa store)

Done. submitted by Max on 04/12/2018


Add time bounds to Transaction Builder attributes

99% done here: https://github.com/stellar/laboratory/commit/c1345670a9ba589454dc886fa1f53e8310e8b0f5
Blocked by https://github.com/stellar/js-stellar-base/issues/67


deny.toml stricten unknown sources + bump tokio for rustsec issue

found a rustsec issue running cargo deny check manually. came out a few days ago. https://rustsec.org/advisories/RUSTSEC-2021-0124. it looks like it applies to us since we use oneshot in the controller. description from discord:

If a tokio::sync::oneshot channel is closed (via the oneshot::Sender::close or oneshot::Receiver::close methods), a data race may occur if the oneshot::Sender::send method is called while the corresponding oneshot::Receiver is awaited or calling try_recv.

we use it only once (excluding tests) in the graceful_ shutdown channel, and those channels only close when we close the whole app, but memory corruption - even at that point - could be bad.

was trying to figure out why it didn't trigger on CI, and it was because it only showed up locally because my local lockfile had set tokio to 0.12. so this isn't actually an issue that we need to rush a release out for, users can pin a newer version of tokio to fix this themselves.


Doc error for text_completion_dataset

The documentatoin at https://pytorch.org/torchtune/stable/tutorials/datasets.html indicates that when using the unmodified text_completion_dataset type, there is a parameter dataset.source which describes the dataset type (E.g. - text) and a dataset.data_files parameter, which points to the actual local dataset.
In the current version it seems as if dataset.source replaced dataset.data_files and points to the actual local dataset.  Also there doesn't seem to be a specific parameter to set dataset type, as it appears to be automatically determined.

Hi @troy256 thanks for creating this issue. Assigning to @RdoubleA to take a look here

Hey @troy256, you can still pass in source and data_files into text_completion_dataset exactly as you suggested, where source is the data file type and data_files is the actual path. I do see where the confusion is, the docstring for the source parameter only discusses path to a HF dataset. I can make this docstring more clear.


IHaskell can't find R packages for use by inline-r

I have
{ nixpkgs ? import <nixpkgs> {} }:

let

  haskellDeps = ps: with ps; [
    (nixpkgs.haskell.lib.dontCheck inline-r)
  ];

in

  nixpkgs.stdenv.mkDerivation {
  name = "env";
  buildInputs = [
    (nixpkgs.haskellPackages.ghcWithPackages haskellDeps)
    nixpkgs.R
    nixpkgs.rPackages.dplyr
  ];
}

and running nix-shell baz.nix -I nixpkgs=https://github.com/NixOS/nixpkgs-channels/archive/nixos-19.03.tar.gz I get
[nix-shell:~/nixtest]$ ghci -fno-ghci-sandbox
GHCi, version 8.6.4: http://www.haskell.org/ghc/  :? for help
Prelude> :set -XTemplateHaskell
Prelude> :set -XQuasiQuotes
Prelude> import Language.R.QQ
Prelude Language.R.QQ> import qualified Language.R as R
Prelude Language.R.QQ R> R.runRegion $ do x <- [r| loadedNamespaces() |]; [r| print(x_hs) |]; return ()
[1] "compiler"  "graphics"  "utils"     "grDevices" "stats"     "datasets"
[7] "methods"   "base"
Prelude Language.R.QQ R> R.runRegion $ do x <- [r| library(dplyr) |]; [r| print(x_hs) |]; return ()

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union

[1] "dplyr"     "stats"     "graphics"  "grDevices" "utils"     "datasets"
[7] "methods"   "base"

But trying this
let

  pkgs = {
    ihaskell = builtins.fetchTarball {
      url = "https://github.com/gibiansky/IHaskell/tarball/bb2500c448c35ca79bddaac30b799d42947e8774";
      sha256 = "1n4yqxaf2xcnjfq0r1v7mzjhrizx7z5b2n6gj1kdk2yi37z672py";
    };
    nixpkgs = builtins.fetchTarball {
      url = "https://github.com/NixOS/nixpkgs-channels/tarball/49dc8087a20e0d742d38be5f13333a03d171006a";
      sha256 = "1fdnqm4vyj50jb2ydcc0nldxwn6wm7qakxfhmpf72pz2y2ld55i6";
    };
  };

in import "${pkgs.ihaskell}/release.nix" {
  compiler = "ghc864";
  nixpkgs  = import pkgs.nixpkgs { overlays = [ ]; };
  packages = self: [ self.inline-r ];
  systemPackages = self: [ self.R self.rPackages.dplyr ];
}

gives

I've now tried this on an ubuntu box that I spun up.
I also tried
let

  pkgs = {
    ihaskell = builtins.fetchTarball {
      url = "https://github.com/gibiansky/IHaskell/tarball/bb2500c448c35ca79bddaac30b799d42947e8774";
      sha256 = "1n4yqxaf2xcnjfq0r1v7mzjhrizx7z5b2n6gj1kdk2yi37z672py";
    };
    nixpkgs = builtins.fetchTarball {
      url = "https://github.com/NixOS/nixpkgs-channels/tarball/49dc8087a20e0d742d38be5f13333a03d171006a";
      sha256 = "1fdnqm4vyj50jb2ydcc0nldxwn6wm7qakxfhmpf72pz2y2ld55i6";
    };
  };

  rOverlay = rself: rsuper: {
    myR = rsuper.rWrapper.override {
      packages = with rsuper.rPackages; [ ggplot2 dplyr xts purrr ];
    };
  };

in import "${pkgs.ihaskell}/release.nix" {
  compiler = "ghc864";
  nixpkgs  = import pkgs.nixpkgs { overlays = [ rOverlay ]; };
  # nixpkgs  = import pkgs.nixpkgs { overlays = [ ]; };
  packages = self: [ self.inline-r ];
  systemPackages = self: [ self.myR ];
  # systemPackages = self: [ self.R self.rPackages.dplyr ];
}

But

So somehow inline-r picks up an R which doesn't have dplyr but if I actually run R via inline-R then the inner R picks up the R which does have dplyr.

It seems like what's happening is that the R_LIBS_SITE environment variable is not being set correctly when using IHaskell. I don't know how to solve this in general, do you have any suggestions? I tried :!export R_LIBS_SITE=<...> but that doesn't work in either IHaskell or GHCi.

This works for me:
let
  pkgs = {
    ihaskell = builtins.fetchTarball {
      url = "https://github.com/gibiansky/IHaskell/tarball/bb2500c448c35ca79bddaac30b799d42947e8774";
      sha256 = "1n4yqxaf2xcnjfq0r1v7mzjhrizx7z5b2n6gj1kdk2yi37z672py";
    };
    nixpkgs = builtins.fetchTarball {
      url = "https://github.com/NixOS/nixpkgs-channels/tarball/49dc8087a20e0d742d38be5f13333a03d171006a";
      sha256 = "1fdnqm4vyj50jb2ydcc0nldxwn6wm7qakxfhmpf72pz2y2ld55i6";
    };
  };

  rOverlay = rself: rsuper: {
    myR = rsuper.rWrapper.override {
      packages = with rsuper.rPackages; [ ggplot2 dplyr xts purrr ];
    };
  };

  nixpkgs  = import pkgs.nixpkgs { overlays = [ rOverlay ]; };

  r-libs-site = nixpkgs.runCommand "r-libs-site" {
    buildInputs = with nixpkgs; [ R rPackages.ggplot2 rPackages.dplyr rPackages.xts rPackages.purrr ];
  } ''echo $R_LIBS_SITE > $out'';

  ihaskellEnv = (import "${pkgs.ihaskell}/release.nix" {
    compiler = "ghc864";
    nixpkgs  = nixpkgs;
    packages = self: [ self.inline-r ];
  }).passthru.ihaskellEnv;

  systemPackages = self: [ self.myR ];

  jupyterlab = nixpkgs.python3.withPackages (ps: [ ps.jupyterlab ]);

  rtsopts = "-M3g -N2";

  ihaskellJupyterCmdSh = cmd: extraArgs: nixpkgs.writeScriptBin "ihaskell-${cmd}" ''
    #! ${nixpkgs.stdenv.shell}
    export GHC_PACKAGE_PATH="$(echo ${ihaskellEnv}/lib/*/package.conf.d| tr ' ' ':'):$GHC_PACKAGE_PATH"
    export R_LIBS_SITE=$(${nixpkgs.coreutils}/bin/cat ${r-libs-site})
    export PATH="${nixpkgs.stdenv.lib.makeBinPath ([ ihaskellEnv jupyterlab ] ++ systemPackages nixpkgs)}''${PATH:+:}$PATH"
    ${ihaskellEnv}/bin/ihaskell install \
      -l $(${ihaskellEnv}/bin/ghc --print-libdir) \
      --use-rtsopts="${rtsopts}" \
      && ${jupyterlab}/bin/jupyter ${cmd} ${extraArgs} "$@"
  '';
in
nixpkgs.buildEnv {
  name = "ihaskell-with-packages";
  buildInputs = [ nixpkgs.makeWrapper ];
  paths = [ ihaskellEnv jupyterlab ];
  postBuild = ''
    ln -s ${ihaskellJupyterCmdSh "lab" ""}/bin/ihaskell-lab $out/bin/
    ln -s ${ihaskellJupyterCmdSh "notebook" ""}/bin/ihaskell-notebook $out/bin/
    ln -s ${ihaskellJupyterCmdSh "nbconvert" ""}/bin/ihaskell-nbconvert $out/bin/
    ln -s ${ihaskellJupyterCmdSh "console" "--kernel=haskell"}/bin/ihaskell-console $out/bin/
    for prg in $out/bin"/"*;do
      if [[ -f $prg && -x $prg ]]; then
        wrapProgram $prg --set PYTHONPATH "$(echo ${jupyterlab}/lib/*/site-packages)"
      fi
    done
  '';
}

That looks great - I will try it as soon as I am back at a real keyboard.

That works - thanks very much :) - would you like me to do anything? Otherwise we can close the ticket.

No further action required, closing the tickets sounds great to me :smile:.


Issue with k8s.io/id/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/

This is a Bug Report

Problem:
The page is empty in website, although it's in the master branch
Proposed Solution:
The page should show
Page to Update:
https://kubernetes.io/id/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes

/language id

this has been fixed by upstream issue sometime back, closing


How to install udt4py in Windows and Arm-based jetson nano? Thanks

How to install udt4py in Windows and Arm-based jetson nano?
Thanks

you need Cython and VC builder to install it.

https://cython.readthedocs.io/en/latest/src/quickstart/install.html


Add "random quote generator" API project

Features:

Fetches Quote from API
Dark mode
Shows appropriate images from unsplash API
Responsive Design
Tweet with single click

I can do this
pls assign me

Not needed. Directly add the code and send a pull request. Let moderators decide whether your project will be added or not....

Should'nt I wait till getting assigned? That's correct thing to do isn't it?
@projectsop

No

Seems like you don't know anything....
First fork the repo
Then add the code
Then create a pull request
No need to ask.
I do same thing
I am now the top contributor


doc: introduction: Improve style and grammar across the chapter

doc: introduction: More consistent doc style across the chapter and better English grammar
These changes are cosmetic and they do not change the meaning of the document.
Signed-off-by: Kirill Kobelev<EMAIL_ADDRESS>

Oops, sorry that this never was reviewed. Thanks for the PR!
Can you please fix your commit message and make sure the commit is signed off too?

Hi @kobelev-dev!
You're getting there :) Only one commit with all your changes would be sufficient, so could you please force push just one single commit to your branch?  but it needs to be less than 72 characters, so maybe "doc: introduction: Improve style and grammar across the chapter"?
Thanks!

Hi @kartben
I made one more attempt after manipulations. I had to reinsert the changes as I lost them in my first rebase attempt. So please look again. There is just one commit there now.
It is still not clear to me if the subject of a commit and the first line of description should be both present or not. when editing here on GitHub in a browser it asks to enter them both. In VS code there is just one edit box.
Is this a normal procedure to propose any change (including in code) as single commit? AFAIK commits can be squashed while merging the PR. Although I never did that on GitHub.

Hi @kartben I made one more attempt after manipulations. I had to reinsert the changes as I lost them in my first rebase attempt. So please look again. There is just one commit there now.

Thanks for your patience! In the future, if you "lose" commits I would recommend using git reflog. This would show you the SHA-1 of all recent commits in your repo, even the ones that may have ended up becoming "orphans". This way you can then cherry-pick the changes, or reset to the commit, etc.

It is still not clear to me if the subject of a commit and the first line of description should be both present or not. When editing here on GitHub in a browser it asks to enter them both. In VS code there is just one edit box.

It's all one "message" but typically the first line is the "title", followed by a blank line, and then the rest would be considered the commit message.

Is this a normal procedure to propose any change (including in code) as single commit? AFAIK commits can be squashed while merging the PR. Although I never did that on GitHub.

It depends on the project's practices. In Zephyr we don't squash commits and they end up being merged (well, rebased) as-is. In your case, all the changes are part of the same "fixing grammar" thingy so it makes sense to group them, but it may have been two commits if you had e..g first fixed some spelling and grammar error and then proposed reformatting of the file, or moved sections around. Your PR would have still been something along the lines of "Improve Intro section" but then two commits 1/ fix grammar 2/ re-order sections. If that makes sense :)
Anyhow, thanks very much again! If you wrap your commit message so that it doesn't exceed the 75 characters max length, you should now be good to go.

Hi @kartben
Thanks for your explanations and I am sorry for so long delay. I mastered a little bit my knowledge in git. I understand what I am doing better now.
So, I updated the commit message and pushed forward 220 commits on the main branch in the main repo. But now I see that I am a couple of commits back again. Will that be automatically fixed when the final merge will happen? Once this PR will be approved almost certain more commits will be done.
The commits tab shows 2 commits, but to my understanding the first one is not relevant. It is not part of the branch any more.

I hope that I finally did it right. Thanks for spending your time with me.

Looks like I need to abandon this and to start over clean.
I will do that tomorrow.


idea: rename the project to duroutine?

The idea came up in a couple of independent discussions, what do you think?

@Pryz mentioned this sounds like the name of a medicine, it seems he's not wrong 😅 https://www.google.com/search?q=durotine&oq=durotine&gs_lcrp=EgZjaHJvbWUyBggAEEUYOdIBCDI5MDRqMGo3qAIAsAIA&sourceid=chrome&ie=UTF-8
Closing


Avoid implicit casts and portable printf with size_t

Like the previous PR, this one is meant to avoid those possible loss of data errors. Plus, it uses the z format for size_t instead of l, because size_t can vary in size (32-bit or 64-bit).

Is there anything pending in this PR I need to do?

No, I just thought now that we have more people @ovivoda or @louwers would also have a quick glance and merge it, but I can do it now 😊

@ntadej Sorry I completely missed this. Thanks for merging it!

No problem, thank you!


Fixed _get_drag_data getting incorrect position on a scaled Control

Fixes #68841.

Have tested, that the PR solves the problem.
The solution and implementation makes sense, because mpos and gui.drag_accum are both viewport-coordinates.

Thanks!


Support muting

Muting users is already possible and reflected in the API but we could support muting particular emojis or keywords

Though this may end up in the API as well, so not sure it's worth handling client-side


Fix issue with wakes and MPI

In xfields/beam_elements/element_with_slicer.py line 231 if the messages are not ready to be received the function just returns, while it should actually wait until the message is ready. I make it wait with a simple while loop.
In generale this can lead to a deadlock so it's maybe not the best solution, but it works in our specific case.

@xbuffat we might need your review as well here


Add verbose flag to print cargo commands

I often find myself wanting to reproduce the same command that cargo-3ds was running, so I thought it would be handy to print these commands out when a flag is passed in.
The output looks like this, with the intention that it can be copy-pasted back into the shell easily to run the same command:
$ cargo 3ds -v test
No pre-build std found, using build-std
Running command:
   RUSTDOCFLAGS=" --no-run --persist-doctests target/doctests" \
   RUSTFLAGS=" -L/opt/devkitpro/libctru/lib -lctru" \
   /Users/ianchamberlain/.rustup/toolchains/nightly-x86_64-apple-darwin/bin/cargo test --target armv6k-nintendo-3ds --message-format json-render-diagnostics -Z build-std --no-run

    Finished test [unoptimized + debuginfo] target(s) in 0.26s
Getting metadata
Building smdh:/Users/ianchamberlain/Documents/Development/3ds/test-runner-3ds/target/armv6k-nintendo-3ds/debug/deps/integration-86fc0175e918598b.smdh
Running command:
   smdhtool --create integration "Homebrew Application" "Unspecified Author" /opt/devkitpro/libctru/default_icon.png /Users/ianchamberlain/Documents/Development/3ds/test-runner-3ds/target/armv6k-nintendo-3ds/debug/deps/integration-86fc0175e918598b.smdh

Building 3dsx: /Users/ianchamberlain/Documents/Development/3ds/test-runner-3ds/target/armv6k-nintendo-3ds/debug/deps/integration-86fc0175e918598b.3dsx
Running command:
   3dsxtool /Users/ianchamberlain/Documents/Development/3ds/test-runner-3ds/target/armv6k-nintendo-3ds/debug/deps/integration-86fc0175e918598b.elf /Users/ianchamberlain/Documents/Development/3ds/test-runner-3ds/target/armv6k-nintendo-3ds/debug/deps/integration-86fc0175e918598b.3dsx "--smdh=/Users/ianchamberlain/Documents/Development/3ds/test-runner-3ds/target/armv6k-nintendo-3ds/debug/deps/integration-86fc0175e918598b.smdh"

Running 3dslink
Running command:
   3dslink /Users/ianchamberlain/Documents/Development/3ds/test-runner-3ds/target/armv6k-nintendo-3ds/debug/deps/integration-86fc0175e918598b.3dsx

No response from 3DS!

Also fix minor issue with building test crate for doctests.

This is a very welcome addition, especially since cargo-3ds presents a film of obscurity between the user and the commands actually run (maybe we should do something about documenting how cargo-3ds interacts with the environment).
Just a thing: even though I think that it'd be almost impossible to move away from 3dslink (especially for how it interacts with the Homebrew Menu), I would still like to work on #2. What do you think about moving away from console commands and actually re-implement some features?

Just a thing: even though I think that it'd be almost impossible to move away from 3dslink (especially for how it interacts with the Homebrew Menu), I would still like to work on #2. What do you think about moving away from console commands and actually re-implement some features?

Sure, I don't think it's a bad idea, if you want to. I personally wouldn't consider it a priority, since users will always have to have the toolchain installed anyway, so we should always be able to rely on the existence of those tools. Having more stuff in Rust (and library-usable) is always nice though!

Going to go ahead and merge this, it fixes some issues with building doctests and doesn't seem too controversial.


Change withoutError to withoutUncert

To be consistent, use withoutUncert instead of withoutError in the results.tex.

Done.

Great 👍. You can create a PR from your branch to main. In that PR write "Resolves #38" or "Fixes #38", then it will automatically close this issue once the PR is merged.


Error k8s-infra-0.11.3 secret "signoz-infra-k8s-infra-apikey-secrets" not found

actual secret name created is "signoz-infra-k8s-infra-apikey-secret" - no "s" on the end

Fixed by https://github.com/SigNoz/charts/pull/400


allow passing log_level to LLInterpreter from Model classes

So that we see additional parser output - useful for debugging

Added it as an environment variable instead -- LLGUIDANCE_LOG_LEVEL (defaults to 1 if it's unset in your env)


removed layers appear to be present in layer selection

in the layer selection dialog, removed layers appear to still be on the map.
in this recording, notice that the two deleted Idalia layers still appear to be on the map (they have a "-" icon instead of "+") when they show as options in the layer selection dialog.

duplicate of #35

Close as a duplicate


GraphQL Emitter Design

GraphQL Emitter Design
Authors: Angel Vargas, Steve Rice (He Him), Swati Kumar
Last updated: Oct 31, 2024
Motivation
From the TypeSpec docs:

TypeSpec is a protocol agnostic language. It could be used with many different protocols independently or together

TypeSpec's standard library includes support for emitting OpenAPI 3.0, JSON Schema 2020-12 and Protobuf.
As GraphQL is a widely used protocol for querying data by client applications, providing GraphQL support in the TypeSpec standard library can help bring all valuable TypeSpec features to the GraphQL ecosystem.
This proposal describes the design for a GraphQL emitter that can be added to TypeSpec's standard library and can be used to emit a valid GraphQL schema from a valid TypeSpec definition.
General Emitter Design Guidelines
Refer to 4604
GraphQL spec and validation rules

GraphQL Validation Rule
Emitter Compliance Guidelines

All types within a GraphQL schema must have unique names. No two provided types may have the same name. No provided type may have a name which conflicts with any built in types (including Scalar and Introspection types).
All anonymous types in TSP will need a default name (something like namespace + parent_type + field_name). If a type in TSP results in multiple types in the output, each output type should be unique by having a prefix or suffix (something like type + “Interface”)

All types and directives defined within a schema must not have a name which begins with “__” (two underscores), as this is used exclusively by GraphQL’s introspection system. GraphQL Identifiers have this validation (names can only start with an _ or letter)
TSP has a wider set of valid names so we’ll throw an emitter validation error for invalid GraphQL names. The developer can use the upcoming invisibility decorator to define another field with a GraphQL valid name

The query root operation type must be provided and must be an Object type.
If the resulting GraphQL schema has no query type, create a dummy query type with no fields

Custom scalars should provide a @specifiedBy directive or the specifiedByURL introspection field that must link to a human readable specification of data format, serialization, and coercion rules for the scalar
Use existing open source specification for custom scalars that already provide these details and use the @specifiedBy directive in the schema to point to them

Object Types and Input Types are two completely different types in GraphQL
See object type and input types for more details

An object type must define one or more fields
Throw an error if we encounter an empty object

Basic emitter building blocks
The following building blocks are used by the emitter code:
emitter.ts (starting point)
Responsibilities:
- Resolving emitter options like noEmit, strictEmit, ...
- Create the actual gql-emitter with the output filePath and options

gql-emitter.ts (main file)

Creates a GraphQLEmitter class that initializes the registry, and typeSelector
 - Starts navigateProgram that collects all the types and builds the GraphQL AST
 - Creates the top-level query/mutation/subscriptions
 - Creates a new GraphQLSchema (js object)
 - Validates schema
 - Returns schema if no errors

If not error
 - printSchema(schema) (GraphQL method that handles all the formatting etc)
 - Write string to file

registry.ts (several maps to collect types)
Mostly has 2 types methods:
- addXXX (addGraphQLType)
- getXXX (getGraphQLType)

The add methods add the partial type to a collector and the get methods are called in the exit visitors to finish building the type as all the information is available to do so.

selector.ts (exposes the function to select the right GraphQL type based on TSP type)
 - typeSelector(type: Type): GraphQLOutputType | GraphQLInputType

The main design constraint is that we only want to traverse the TSP program once to collect and build the GraphQL types.
Detailed Emitter Design
Design Scenarios
We need to consider two main scenarios when designing the GraphQL emitter:

When the TypeSpec code is specifically designed for emitting GraphQL, we can equip developers with GraphQL-specific decorators, and objects. This will aid in crafting TypeSpec code that generates well-designed GraphQL schemas. Given that GraphQL does not employ HTTP or REST concepts, developers should be able to bypass those libraries. However, it should still be feasible to emit OpenAPI or any other schema by adding the appropriate decorators (like @route) to the existing TypeSpec code used to generate the GraphQL schema and the existing graphql emitter should continue to work as expected.
When a developer aims to create a GraphQL service from an existing TypeSpec schema originally used for emitters like OpenAPI, we focus on designing a usable GraphQL schema. This may involve using Any scalars for unsupported GraphQL objects and emitting all the operations in the TypeSpec code. Although the emitted GraphQL schema might lack optimal design, it remains functional. If a specific pattern can enhance the GraphQL schema and aligns with our design guidelines, it should be applied. We will also offer warnings and recommendations to assist developers in modifying the TypeSpec code to improve their emitted GraphQL schema incrementally.

Output Types
Context and design challenges
GraphQL distinguishes between Input and Output Types. While there is no way in TypeSpec to allow the developers to specify this, the compiler provides a mechanism that identifies each model as Input and/or Output using UsageFlags.
In GraphQL:

Scalar and Enum types can be used as both: Input and Output
Object, Interface and Union types can be used only as Output
Input Object types can't be used as Output

Design Proposal
Use the UsageFlags to identify the input and output types for GraphQL.
🔴 Design Decision: As TSP will allow a model to be both input and output type and indeed that would be useful for GraphQL as well, the GraphQL emitter will support this case. In order to differentiate between the input and output types we propose creating a new GraphQL type for inputs with the name of the type + Input suffix.
When creating an operation that returns models, all directly or indirectly referenced models, should be emitted as valid GraphQL output types.
Mapping

TypeSpec
GraphQL
Notes

Model.name
Object.name
See Naming conventions

Model.properties
Object.fields

Examples

TypeSpec
GraphQL

@doc("Simple output model")
model Image {
  id: int32,
  url: str,
}
@doc("Operation")
op getImage(
  id: int32,
  size: str,
): Image;

type Image {
  id: Int!
  url: String!
}
type Query {
  getImage(id: Int!, size:String!): Image!
}

@doc("empty output model")
model Image {}
@doc("Operation with empty model")
op getImage(id: int32, size: str): Image;

type Query {
  getImage(id: Int!, size: String!)
}

@doc("empty model as a field")
model Image {}
@doc("regular model")
model User {
  image: Image;
}
op getUser(id: int): User;

scalar Any
type User {
  image: Any
}
type Query {
  getUser(id: Int!): User!
}

@doc("? vs null output model")
model Image {
  id?: int32
  url: str | null;
}
@doc("operation")
op getImage(
  id: int32,
  size: str,
): Image;

type Image {
  id: Int
  url: String
}
type Query {
  getImage(id: Int!, size:String!): Image!
}
      Based on result coercion rules if `url` is non-null, then `null` or `undefined` will raise an error. So, we need to mark `url` as not required in GraphQL.

More complicated examples with unions, interfaces, and lists are described in their respective sections.
Input Types
Context and design challenges
Use the UsageFlags.INPUT to determine if a TSP model is an input type. The following validation rules apply to input types:

Unions and Interfaces are not part of the input type.
Input types may not be defined as an unbroken chain of Non-Null singular fields as shown below

# This is invalid

input Example {
	self: Example!
	name: String
}

# This is also invalid
input First {
	second: Second!
	name: String
}

input Second {
	first: First!
	value: String
}

For an optional input type, a null value can be provided, and that would be assigned to this type. Optional input types can also be “missing” from the input map. Null and missing are treated differently.

Design Proposal
To emit a valid GraphQL and still represent the schema defined in TypeSpec, the emitter will follow these rules:

If the Input model is Scalar or Enum, the type is generated normally.
If the input type is a Model and all the properties of the Model are of valid Input types, a new Input object will be created in GraphQL, with the typename as the original type + Input suffix.

🔴 Design decision: All models are created with the Input suffix regardless of whether or not it is used as both, because the model can be used as both input and output in the future and changing the type name will cause issues with schema evolution.
Cons: the Input suffix can be annoying or result in types like UserInputInput

If the model or its properties are invalid Input types, the type of the invalid model or property will be assigned to the Any scalar type and a warning will be emitted.

🔴 Design decision: In order to provide a different definition of the same field so that the GraphQL type can be represented more accurately, we will use the upcoming visibility redesign to provide an alternative definition, see the examples to see what that could look like.

If the model contains an unbroken chain of non-null singular fields, throw an error and fail the emitter process

Mapping

TypeSpec
GraphQL
Notes

Model.name
Object.name
See Naming conventions

Model.properties
Object.fields

Examples

TypeSpec
GraphQL

@doc("Valid Input Model")
model UserData {
  name: string;
  email?: string;
  age: int | null;
}
@doc("created user")
model User {
  ... UserData
  id: int32;
}
@mutation
op createUser(userData: UserData): User

input UserDataInput {
  name: String!
  email: String
  age: Int
}
type User {
  name: String!
  email: String
  age: Int
  id: Int!
}
type Mutation {
  createUser(userData: UserDataInput!): User!
}

@doc("invalid input model")
model UserData {
  pet?: Pet;
  name: string;
  email?: string;
  age: int | null;
}
@doc("created user")
model User {
  ... UserData
  id: int32;
}
union Pet {
  dog: Dog,
  cat: Cat
}
@mutation
op createUser(userData: UserData): User

Translate the invalid input to Any
scalar Any
input UserDataInput {
  pet: Any
  name: String!
  email: String
  age: Int
}
type User {
  pet: Pet
  name: String!
  email: String
  age: Int
  id: Int!
}
union Pet = Dog | Cat
type Mutation {
  createUser(userData: UserDataInput!): User!
}

@doc("common fields")
model UserFields {
  name: string;
  email?: string;
  age: int | null;
}
@doc("invalid input model")
model UserData {
  pet?: Pet;
  ... UserFields
}
model UserDataGql {
  dog?: Dog
  cat?: Cat
  ... UserFields
}
union UserInputPerProtocol {
  @invisbile(HttpVis)
  UserDataGql,
  @invisible(GraphQLVis)
  UserData,
}
@doc("created user")
model User {
  ... UserData
  id: int32;
}
union Pet {
  dog: Dog,
  cat: Cat
}
@mutation
op createUser(userData: UserInputPerProtocol): User

input UserDataGqlInput {
  dog: Dog
  cat: Cat
  name: String!
  email: String
  age: Int
}
type User {
  pet: Pet
  name: String!
  email: String
  age: Int
  id: Int!
}
union Pet = Dog | Cat
type Mutation {
  createUser(userData: UserDataGqlInput!): User!
}

model UserData {
  identity: Identity;
  numFollowers: int;
  profession: Profession
}
model Profession {
  isEmployed: boolean;
  employer: string;
}
model Identity {
  user: UserData;
  gender: string;
}
model User {
  id: string;
}
op createUser(userData: UserData): User

Throw an error in emitter validation

Design Alternatives
For specifying GraphQL/HTTP specific types:

Create a new decorator to allow the TSP entities to belong to different protocols. This would be part of the TSP library similar to invisible and visible
Use this new way to define protocol specific entities

Auto-resolve unwrapping of unions

Even with the @invisible decorator applied to union variants, the emitter creators will have to deal with the auto-unwrapping of unions with just one variant. As this would be common functionality to all emitters, perhaps this should be done in a common place like by the TSP compiler

Scalars
Context and design challenges
GraphQL only provides five built-in scalars: Int, String, Float, Boolean and ID.
Any other scalar should be added as a custom scalar, and the @specifiedBy directive should be added to provide a specification.
The ID scalar type represents an unique identifier, as defined here.
Design Proposal
The emitter will use the mappings provided below to map TypeSpec to GraphQL scalars, trying to emit as a built-in scalar when possible.
For the custom scalars, if the TypeSpec documentation mentions a specification, that will be used for the @specifiedBy directive.  If not provided, we will use a link to the TypeSpec documentation: https://typespec.io/docs/standard-library/built-in-data-types/
Encodings provided by the @encode decorator in TSP code would also be considered to build the proper custom scalar.
We are proposing a new TypeSpec native decorator @specifiedBy over scalars to allow developers to provide their own references.  If provided, the emitter will use the information to generate the GraphQL directive.
To handle the ID type, the emitters library will include a TypeSpec scalar:
@doc("GraphQL ID")
scalar ID extends string;

Type Mappings to GraphQL Built-In Scalars

TypeSpec
GraphQL
Notes

string
String

boolean
Boolean

int32 int16 int8 safeint uint32 uint16 uint8
Int
GraphQL Int is a 32-bit Integer Alternatively, we can define a Scalar for every specific TypeSpec type

float float32 float64
Float
GraphQL Float is double-precision Alternatively, we can define a Scalar for every specific TypeSpec type

Type Mappings to GraphQL custom Scalars

TypeSpec
encoding
GraphQL
Primitive
specifiedBy

integer int64

scalar BigInt
String

numeric

scalar Numeric
String

decimaldecimal128

scalar BigDecimal
String

bytes
base64
scalar Bytes
String
https://datatracker.ietf.org/doc/html/rfc4648

base64url
scalar BytesUrl
String
https://datatracker.ietf.org/doc/html/rfc4648#section-5

utcDateTime
rfc3339
scalar UTCDateTime
String
https://datatracker.ietf.org/doc/html/rfc3339

rfc7231
scalar UTCDateTimeHuman
String
https://datatracker.ietf.org/doc/html/rfc7231

unixTimestamp
scalar UTCDateTimeUnix
Int

offsetDateTime
rfc3339
scalar OffsetDateTime
String
https://datatracker.ietf.org/doc/html/rfc3339

rfc7231
scalar OffsetDateTimeHuman
String
https://datatracker.ietf.org/doc/html/rfc7231

unixTimestamp
scalar OffsetDateTimeUnix
Int

unixTimestamp32

scalar OffsetDateTimeUnix
Int

duration
ISO8601
scalar Duration
String
https://www.iso.org/obp/ui/#iso:std:iso:8601:-1:ed-1:v1:en

seconds
scalar DurationSeconds
Float

plainDate

scalar PlainDate
String

plainTime

scalar PlainTime
String

url

scalar URL
String
https://url.spec.whatwg.org/

unknown

scalar Any
String

Examples

TypeSpec
GraphQL

scalar password extends string;
scalar ternary;

scalar Password
scalar Ternary

Unions
Context and design challenges

In GraphQL, all Unions should be named, while in TypeSpec anonymous Unions can be used.
Scalars, Interfaces and Unions can't be member types of an Union. Therefore, in GraphQL nested Unions are not permitted.
Unions can't be part of a GraphQL Input Object.

Design Proposal
Generate 1:1 mapping for regular unions.
For nested unions, a single union will be recursively composed with all the variants implicitly defined in TypeSpec.
As the interface models are decorated with an @Interface decorator, throw a validation error when defining a union variant for a model type that is decorated with this.
Wrap the scalars in a wrapping object type and emit a union with those types.
Create explicit unions in GraphQL for anonymous TSP unions, naming them using the context where the Union is declared, for example using model and property names, or the operation and parameter names, or the operation name if used as a return type.  And all cases with the "Union" suffix. (See examples). Note that this approach may generate identical GraphQL unions with distinct names. We will throw an error if there are naming conflicts.
There are some special cases with distinct treatments, like:

Unions containing null type: see Nullability

Mapping

TypeSpec
GraphQL
Notes

Union.name
Union.name
Anonymous Unions can be represented as: ModelPropertyUnion OperationParameterUnion OperationUnion

Union.types
Union.types

Examples

TypeSpec
GraphQL

@doc("Named Union")
union Animal {
  bear: Bear,
  lion: Lion,
}

union Animal = Bear | Lion

Nested unions
@doc("Named Union")
union Animal {
  bear: Bear,
  lion: Lion,
}
@doc("Nested Union")
union Pet {
cat: Cat,
dog: Dog,
animal: Animal,
}

union Pet = Cat | Dog | Bear | Lion

Anonymous union in param
@doc("Anonymous Union in a parameter")
@query
op setUserAddress(
id: int32,
data: FullAddress | BasicAddress,
): User;

union SetUserAddresDataUnion = FullAddress | BasicAddress
type Query {
setUserAddress(id: Int!, data: SetUserAddressDataUnion!): User!
}

Named union of scalars
@doc("Named Union of Scalars")
union TwoScalars {
text: string,
numeric: float32,
}

union TwoScalars = TextUnionVariant | NumericUnionVariant
type TextUnionVariant {
value: String!
}
type NumericUnionVariant {
value: Float!
}

Named union of scalars and models
union CompositeAddress {
oneLineAddress: string,
fullAddress: FullAddress,
basicAddress: BasicAddress
}

type OneLineAddressUnionVariant {
value: String!
}
union CompositeAddress = OneLineAddressUnionVariant | FullAddress | BasicAddress

Anonymous union in return type
@doc("Anonymous Union in a return type")
op getUser(id: int32): User | Error;

union GetUserUnion = User | Error
type Query {
getUser(id: Int!): GetUserUnion!
}

Design Alternatives
Union of scalars design alternative:

Don’t wrap the scalars, and just emit Any type.

Pros : We are not opinionated about how to represent scalars
Cons: there might be a lot of Any types

Open Questions

Think in a better naming rules to reduce or avoid duplicates

Field Arguments
Context and design challenges

Fields (model properties) can receive arguments.
Field Arguments follow the same rules as operation parameters. (Actually,  operation parameters are field arguments)
The models directly or indirectly used in the field arguments should be declared as Input
Arguments are Unordered
TypeSpec does not support arguments on model properties.

Design Proposal

Create a new decorator called operationFields that references operations or interfaces to be added to a model
This will be used by the emitter to generate a field with arguments on the corresponding GraphQL type
Operations and namespaces that are used in the operationFields decorator are not emitted as part of the root GraphQL operations like query, mutation, or subscription

extern dec operationFields(target: Model, ...onOperations: Operation[] | Interface[])

Mapping

TypeSpec
GraphQL
Notes

@operationFields
Model
List of operations or interfaces are the arguments

Operation.name
Field.name
Model is the target of the decorator.

Operation.returnType
Field.type
Model is the target of the decorator.

Operation.parameters
Field.ArgumentsMap
Model is the target of the decorator.

Decorators

Decorator
Target
Parameters
Validations

@operationFields
Model
The operations or interfaces to be added as a field with arguments on the GraphQL object type

@useAsQuery
Model
None

Examples

TypeSpec
GraphQL

@operationFields(ImageService.urls, followers)
model User {
  id: integer;
  name: string;
}
namespace ImageService {
@operationFields(Images)
model Image {
id: integer;
name: string;
}
op analyze(category: string): string
op urls(size: string): url[] | null
}
// This decorator is used to create a custom query model
@useAsQuery
@operationFields(followers)
model MyOwnQuery {
me: User
}
op followers(sort: string): User[]

type User {
id: Int!
name: String!
followers(sort: String!): [User]!
imageServiceUrls(size: String!): [URL!]
}
""" When model and operations are within the same namespace, don't append the namespace """
type Image {
id: Int!
name: String!
analyze(category: String!): String!
urls(size: String!): [URL!]
}
schema {
query: MyOwnQuery
}
type MyOwnQuery {
me: User
followers(sort: String): [User]
}

Additional examples that show namespaces in GraphQL can be found here:

Example with namespaces and operationFields within namespaces
Example when namespaces are only used in the TSP context if the design doesn’t make use of them, but are disambiguated at the top level

Design Alternatives

[DISCARDED] @parameters({arg1: type1; arg2: type2;}) decorator targeting Model Properties.
We prototyped this, but found issues when validating/generating the Input types.
[DISCARDED] @mapArguments(modelProperty, arg1, agr2, …) decorator over Operations, where arg1, arg2, etc. are the name of the parameters of the target operation to map as arguments of the modelProperty.  Discarded because @modelRoute is a better abstraction and is less complex.

ModelRoute Decorator Design:
We propose to introduce a decorator over the Operations to map the operation as a new parameterized field of a model.

The @modelRoute decorator will receive a parameter with the Model where to add the field.
The new field of the model will be created using the name, parameters and type of the operation.
The operation will be excluded from the top-level Query and Mutation types.
Multiple decorators can be added to the same operation, each one with a different Model.
Since the operations designed to be targeted by the @modelRoute decorator would be probably useless for other schemas because of the lack of the Model context; we may want to force the Model to appear in the parameters and exclude it from the GraphQL field arguments, or even take the first parameter of the operation as the Model.

@modelRoute(User)
op avatar(user:User, size: str): String;

type User {
  id: Int!
  avatar(size: String): String!
}

Interfaces
Context and design challenges
There is no way to represent GraphQL Interfaces in TSP directly. We’ll use a combination of special decorators and the spread operator to achieve this for the GraphQL emitter.
Only Output Types can be decorated as an Interface. If an Input Type is decorated as an Interface, a decorator validation error must be thrown.
Design Proposal
GraphQL Interfaces will be defined using the two specific decorators outlined below:
extern dec Interface(target: Model);
extern dec compose(target: Model, ...implements: Interface.target[]);

The @Interface decorator will designate the TSP model to be used as an Interface in GraphQL. This model will be emitted as the GraphQLInterface type.
The @compose decorator designates which Interfaces should the current model be composed of. The @compose decorator can only refer to other models that are marked with the @Interface decorator and not vanilla model types.
Mapping

TypeSpec
GraphQL
Notes

@Interface
Interface

Model
Interface (Output Type)
Note only output models can be interfaces

@compose
extends Iface1, Iface2…
@compose can be used either with a combination of the @Interface decorator or on the model directly

Decorators

Decorator
Target
Parameters
Validations

@Interface
Model

Can be assigned only to an output model

@compose
Model
Targets of the Interface decorator
Can be assigned only to an output model All the fields of the models from compose must be present in the target model

Examples

TypeSpec
GraphQL

alias ID = string
@Interface
model Node {
id: ID;
}
@Interface
@compose(Node)
model Person {
id: ID;  // This is from Node
... Identity // This is just for TSP spread
}
model Identity {
birthDate: plainDate;
age?: integer;
}
@compose(Person)
model Actor {
... Person
rating: string;
}
Fields within the composed model can be defined using either ... operator or manually, both are valid

scalar PlainDate
interface Node {
id: ID!
}
interface Person implements Node {
id: ID!
birthDate: PlainDate!
age: Int
}
type Actor implements Node & Person {
id: ID!
birthDate: PlainDate!
age: Int
rating: String!
}
GraphQL requires both Person and Node to be explicitly implemented by Actor.

Design Alternatives

[Discarded] Spread the fields of models defined in compose automatically – this wouldn’t be great because then compose would change the shape of the model just for GraphQL
[Discarded] Don’t define the Interface and assume interfaces from models used in compose. Since GraphQL has an explicit concept of Interface we’re representing that using this decorator. If validation rules specific to Interfaces need to be applied in the future, it will be possible to do so

Enums
Context and design challenges
TSP enum member types have no meaning in GraphQL and the enum member values should follow the naming convention shown below (similar to all other literal names). From the GraphQL spec: “EnumValue
Name but not true false null”
where Name should start with [A-Za-z] or <underscore> and can be followed by letter, digit, or <underscore>
GraphQL Recommendation: “It is recommended that Enum values be “all caps”. Enum values are only used in contexts where the precise enumeration type is known. Therefore it’s not necessary to supply an enumeration type name in the literal.”
Design Proposal
Use TypeSpec enums in the value context as GraphQL doesn’t need the type information.
TypeSpec enums with no types that can only be identifiers or string literals will be translated to all caps GraphQL enums as long as the identifiers are valid GraphQL names. If they are invalid, the emitter will throw a validation error.
🔴 Design decision: TypeSpec enums with integer or floating point values will be converted to a string value using the following rules to create result:

Initialize result to _
If the integer is negative add the word NEGATIVE_ to the result string
Create a string representation of the integer or create a string representation of the floating point value where . is converted to an _
Append the string representation to result

Pros: The GraphQL enum is a string representation of the value and reflects the true intention of the developer
Cons: The server side implementation will have to figure out the translation between the GraphQL enum and the internal representation of the enum where the algorithm isn’t obvious (i.e. they will basically have to implement the steps above).
Inline enums that don’t have an enum name will be assigned a distinct name based on where the field appears in the TSP schema. The name derived from the field will be followed by an Enum suffix. To provide disambiguation, the full name should be namespace + modelName + fieldName. See the examples table for an example.
Inline enum:
size?: "small" | "medium" | "large"

Mapping

TypeSpec
GraphQL
Notes

Enum.name
Enum.name
See Naming conventions

Enum.members
Enum.members

Examples

TypeSpec
GraphQL

@doc("Simple Enum")
enum Direction {
  North,
  East,
  South,
  West,
}

enum Direction {
  NORTH
  EAST
  SOUTH
  WEST
}

@doc("Enum with Values")
enum Hour {
  Nothing: 0,
  HalfofHalf: 0.25,
  SweetSpot: 0.5,
  AlmostFull: 0.75,
}

Convert the hour values into GraphQL enum values
enum Hour {
  _0
  _0_25
  _0_5
  _0_75
}
Note that we don’t use the type as TSP types might only have meaning within the TSP code and not the emitted protocol

enum Boundary {
  zero: 0,
  negOne: -1,
  one: 1
}

Convert Boundary values into GraphQL enum values
enum Boundary {
  _0
  _NEGATIVE_1
  _1
}

namespace DemoService;
model Person {
  size?: "small" | "medium" | "large"
}

Derive a unique name based on the namespace, model, field name \+ “Enum”
enum DemoServicePersonSizeEnum {
  SMALL
  MEDIUM
  LARGE
}

Design Alternatives

Use the type name instead of values for integer and floating point values. But, we would need to be consistent and use TSP enums in the type context rather than the value context which feels wrong.
Emit Any for enums with values as integers or floating points and let the developer define an alternate type using the upcoming visibility redesign to provide an alternative definition.

If the @invisible decorator can be applied to EnumMembers, we can provide alternate enum members for GraphQL in the same enum definition which change the emitter to emit the GraphQL enum values as shown below:

enum Hour {
  @invisible(GraphQLVis)
  Nothing: 0,
  @invisible(GraphQLVis)
  HalfofHalf: 0.25,
  @invisible(GraphQLVis)
  SweetSpot: 0.5,
  @invisible(GraphQLVis)
  AlmostFull: 0.75,
  ... GraphQLHour
}

@invisible(HttpVis)
enum GraphQLHour {
  Nothing: "zero",
  HalfofHalf: "quarter",
  SweetSpot: "half",
  AlmostFull: "threeQuarters",
}

====================================  GRAPHQL  ====================================

enum Hour {
   ZERO
   QUARTER
   HALF
   THREEQUARTER
}

Operations
Context and design challenges
There are three kinds of GraphQL Operations: Query, Mutation and Subscription.  While in TypeSpec there is no difference between them.

At least one query operation should be included in the schema.
The models directly or indirectly used in the operation parameters should be declared as Input types
The models directly or indirectly used as the operation result type should be declared as Output types

Design Proposal
To distinguish between Queries, Mutations and Subscription, we are proposing to include a set of three decorators in TypeSpec: @query, @mutation and @subscription.  These will decorate the TSP Operations to indicate the GraphQL kind.
The decorators would also be added to an interface, understanding that all operations within the interface would be of the provided kind.
The GraphQL emitter will generate the proper GraphQL kind for each Operation, according to these rules:

Follow the explicit definition of any of the decorators: @query, @mutation, @subscription
If the decorator is not provided, then:

If the strictEmit option is on, the operation would be omitted from the GraphQL schema
If the strictEmit option is off, then:

If the Operation is marked with @http.get or @http.head the Operation will be generated as a Query
If the Operation is marked as @http.put, @http.post @http.patch or @http.delete, the Operation will be generated as a Mutation
if the Operation is not  marked with any http verb, we fallback to the OpenAPI emitter behavior as follows:

If any of the parameters of the Operation is marked with @http.path, the emitter defaults to query,
Else, the operation will be emitted as Mutations, because the OpenAPI emitter defaults to post.

The Operation parameters will be converted to GraphQL arguments following the rules for the GraphQL Input types.
The Operation return type should be a valid GraphQL Output Type.
In line with the Field Arguments design, the operations decorated directly or indirectly with the @operationFields decorator, would not be added as query, mutations or subscriptions.
When no operation is emitted, an empty schema will be generated.
When mutations are provided, but there are no query operations, a dummy Query will be added to the schema to make it valid.
Mapping

TypeSpec
GraphQL
Notes

@GraphQL.query @GraphQL.mutation @GraphQL.subscription
(operation) Type
If decorators are not present, some rules will apply to define the operation Type.

Operation.name
name
See Naming conventions

Operation.returnType
type
See Output Types

Operation.parameters
args
See Input Types

Decorators

Decorator
Target
Parameters
Validations (on VS Code and at TSP  compile time)

@query
Operation, Interface
NA
Just one of these decorators should be applied to the same Operation.

@mutation
Operation, Interface
NA

@subscription
Operation, Interface
NA

Examples

TypeSpec
GraphQL

@doc("Explicit Query")
@GraphQL.query
op getUser(id: int32): User;
@doc("Explicit Mutation")
@GraphQl.mutation
op setUserName(
id: int32,
name: string
): User;
@doc("Mutation bg @HTT.post")
@HTTP.post
op setUserPronouns(
id: int32,
prononuns: String,
): User;
@doc("Mutation bc body param")
op setUserAddress(
id: int32,
@HTTP.body
address: Address
): User;
@doc("Query bc HTTP.get")
@HTTP.get
op getUsersByAddress(
@HTTP.body
address: Address
): User[];
@doc("Query bc HTTP.path")
@HTTP.get
op getUserAddressById(
@HTTP.path
id: int32,
): Address;
@doc("Mutation by default")
op getCurrentUser(): User;

type Query {
getUser(id: Int): User!
getUsersByAddress(address: Address): [User!]
getUserAddressById(id: Int): Address!
}
type Mutation {
setUserName(id: Int, name: String): User!
setUserPronouns(id: Int, pronouns: String): User!
setUserAddress(id: Int, address: Address): User!
getCurrentUser(id: Int): User!
}

@doc("Schema with a single Mutation")
@GraphQl.mutation
op setUserName(
id: int32,
name: string
): User;

""" Dummy Query """
type Query {
_: Boolean
}
type Mutation {
setUserName(id:Int, name: String): User
}

@doc("ERROR: Duplicated GraphQL operation kind")
@GraphQl.query
@GraphQl.mutation
op setUser(
id: int32,
name: string
): User;

Decorator Validation Errors

Lists
Context and design challenges
TSP defines a list and Array builtin types and both of those need to be converted to GraphQL lists. GraphQL lists are wrappers over output and input types.
Design Proposal
For TSP lists ([]) and arrays (Array) used as types of properties, parameters and operations, we will emit the corresponding list of types in GraphQL.
Mapping

TypeSpec
GraphQL
Notes

List.type
List.type

Array.type
List.type

Examples

TypeSpec
GraphQL

@doc("Lists as property types")
model User {
  id: int32;
  pronouns: string[];
  groups: Group[];
}
@doc("Lists as op return types")
op getUserAddresses(
id: int32;
): User[];
model Pet {
id: int32;
names: Array;
}

type User {
id: Int!
pronouns: [String!]!
groups: [Group!]!
}
type Query {
getUserAddresses(id: Int!): [User!]!
}
type Pet {
id: Int!
names: [String!]!
}

model Foo {
a: string[];
b: Array<string | null>;
c?: string[];
d: string[] | null;
}

type Foo {
a: [String!]!
b: [String]!
c: [String!]
d: [String!]
}
Note the difference in the requiredness of the values vs the list itself for the various options

Nullable vs Optional
Context and design challenges
In GraphQL, all properties and parameters are nullable by default, and the ! operator is applied to indicate non-nullability.
And although all fields are optional; for parameters, Input fields are required if they are marked as non-nullable.
In TypeSpec non-nullable is the default, while nullability is expressed by an Union that includes the  null type.  Also in TypeSpec: all the fields are required, unless are marked optional with the ? operator.
Design Proposal
All output types and return types will be emitted in GraphQL as non-nullable (! operator), except when the field is marked as optional, or when the type of the field is an Union containing the TypeSpec null type.
We can also use the same rules for Input fields, but we will force the field as required if the property or the argument is not nullable.  Alternatively, we can throw an error.

TypeSpec
GraphQL Output
GraphQL Input

name: string;
name: String!
name: String!

name?: string;
name: String
name: String!

name: string
null;
name: String

name?: string
null;
name: String

Examples

TypeSpec
GraphQL

model User {
  id: int32;
  name: string;
  pronouns?: string;
  birthYear: int32 | null;
  followers: User[];
  pet: Pet | null;
}
op getCurrentUser: User;
op getPet(user: User): Pet | null;

type User {
  id: Int!
  name: String!
  pronouns: String
  birthYear: Int
  followers: [User]!
  pet: Pet
}
type Query {
  getCurrentUser: User!
  getPet(user: User!): Pet
}

model User {
  id: int32;
  name: string;
  pronouns?: string;
  birthYear?: int32 | null;
  pet: Pet | null;
}
op patchUser(
  user: User
): User;
op patchUserNullable(
  user: User | null
): User;
op patchUserOptional(
  user?: User
): User;
op patchUserNullableOptional(
  user?: User | null
): User;

type User {
  id: Int!
  name: String!
  pronouns: String
  birthYear: Int
  pet: Pet
}
input UserInput {
  id: Int!
  name: String!
  pronouns: String!
  birthYear: Int
  pet: Pet
}
type Query {
  patchUser(user: UserInput!): User!
  patchUserNullable(user: UserInput): User!
  patchUserOptional(user: UserInput!): User!
  patchUserNullableOptional(user: UserInput): User!
}

Design Alternatives

[DISCARDED] Ignore TSP Optional operator and use only nullability.
Throw an error for Input types when they are nullable and not optional.

Visibility & Never
Context and design challenges

TypeSpec have two ways to filter out properties from Models:

Visibility, using @visibilty and @witthVisibility decorators.
never type

The filtering based on explicit filtered models using @withVisibility is already considered in the compiler, so it will be also included in the emitter.
HTTP library has the automatic visibility concept that automatically filters the properties from the model based on the HTTP type of the operation, with no need of generating explicit filtered models.
According to the note in the TypeSpec documentation, it is the responsibility of the emitters to exclude the fields of type never.

Design Proposal
Add to the emitter the handling of the never type, and exclude any field from the Model before emitting the Model.
Note: This may result in empty models.  We need to define what to do with fields pointing to empty Models.
For Implicit filtered models (automatic visibility):

Filter all output models using the "read" visibility, generating new models like ModelRead, or maybe  ModelOutput.  The new model would be generated only if it is distinct from the original Model.
Since GraphQL does not distinguish between create, update and delete operations; we can generate our Input models just based on the GraphQL operations are used for: Query (visibility "query") or for Mutation (visibilities: "create", "update" and  "delete"); generating: ModelQueryInput and ModelMutationInput.
To emit a schema closer to those emitted by other emitters, if the operation is marked with a HTTP verb decorator, we will need to follow the HTTP library specification to filter the models before using them, and if needed, generate new models based on the visibility and the operation type.  For example: for the operations responding using a Model, we will emit a new model named ModelRead with the properties filtered using the "read" visibility.
Note that the naming should include the Input suffix and this approach will generate models like UserCreateInput, UserUpdateInput, UserDeleteInput, etc.

Examples

TypeSpec
GraphQL

Never and explicit filtering
model PostBase<TState> {
  @visibility("read")
  id: int32;
  title: string;
  isPopular: boolean;
  @visibility("update")
  poster?: Person;
  postState: TState;
  postCountry?: Country;
}
model Post is PostBase<int32>;
model PostGql is PostBase<never>;
@withVisibility("read")
model PostRead {
  ...Post;
}

""" postState is Int """
type Post {
  id: Int!
  title: String!
  isPopular: Boolean!
  poster: Person
  postState: Int!
  postCountry: Country
}
""" No postState is present due to never """
type PostGql {
id: Int!
title: String!
isPopular: Boolean!
poster: Person
postCountry: Country
}
""" No poster because the visibility is read """
type PostRead {
id: Int!
title: String!
isPopular: Boolean!
postState: Int!
postCountry: Country
}

Automatic visibility with HTTP
model User {
name: string;
@visibility("read", "update") id: string;
@visibility("create") password: string;
@visibility("read") lastPwdReset: plainDate;
}
@route("/users")
interface Users {
@post create(user: User): User;
@get get(@path id: string): User;
@patch set(user: User): User;
}

scalar plainDate
""" Create automatic types """
type User {
name: String!
id: String!
password: String!
lastPwdReset: plainDate!
}
type UserRead {
name: String!
id: String!
lastPwdReset: plainDate!
}
type UserCreateInput {
name: String!
password: String!
}
type UserUpdateInput {
name: String!
id: String!
}
type Query {
get(id: String!): User!
}
type Mutation {
create(user: UserCreateInput): User!
set(user: UserUpdateInput!): User!
}

Automatic visibility with GraphQL
model User {
name: string;
@visibility("read", "update") id: string;
@visibility("create") password: string;
@visibility("read") lastPwdReset: plainDate;
}
interface Users {
@mutation create(user: User): User;
@query get(id: string): User;
@mutation set(user: User): User;
}

scalar plainDate
type User {
name: String!
id: String!
password: String!
lastPwdReset: plainDate!
}
type UserRead {
name: String!
id: String!
lastPwdReset: plainDate!
}
type UserMutationInput {
name: String!
id: String!
password: String!
}
type Query {
get(id: String!): User!
}
type Mutation {
create(user: UserCreateInput): User!
set(user: UserUpdateInput!): User!
}

Open Questions

Define what to do with fields pointing to empty models
Should we keep the original Models in the schema, even if they are not used?

User feedback:
The emitter will generate feedback for the developers through errors and warnings.  But the warning list could be enormous and not easy to read, especially when trying to emit a GraphQL from a large TSP specification not specifically designed for GraphQL.
With this in mind we are proposing to emit a "How to improve your TypeSpec scheme for GraphQL" report based on the warnings and other signals.  The purpose is to help developers to generate a better GraphQL schema, introducing the GraphQL decorators and other tricks to their TypeSpec code.  The report should be more readable than the warnings.
Typespec extension suggestions
These will be opened as separate issues.

Thanks for sharing the design doc for the GraphQL emitter, it looks solid overall! I'll defer to @bterlson for specific feedback on the design, here are a couple of high-level suggestions from me as well:
1. Error Handling
Can you include more details on error handling throughout the process? For example, specify how errors during type resolution or schema validation are managed.
2. Example Workflow
A step-by-step example of processing a simple TypeSpec definition, from initialization to schema generation would be super helpful.
3. Testing
I'd love to see the strategy for testing folded into the design doc, with a focus on:

Unit Tests: Test individual components and methods.
Integration Tests: Verify the entire workflow from TypeSpec definition to GraphQL schema generation.
Performance Tests: Assess how the emitter handles large and complex TypeSpec definitions.
Edge Case Tests: Handle edge cases and error conditions, like invalid GraphQL names and empty models.

Great work so far, I'm looking forward to seeing the final product!

Sorry for the delay in getting to this, crazy times followed by vacation. Overall I like the proposed design and the architectural sketch, though for the latter feel free to change that as you build as it's less important.
Next steps I think we should make any changes you want to make based on the below feedback and schedule a design meeting in the next week or two to go over some of these details and have any needed discussion.
Thoughts:

use /** */ in examples over @doc decorator (they mean the same thing). No need to update proposal, just keep in mind for docs or what have you.

Unclear of the rationale for using Any for empty models? An empty model might be used as a marker object or something?

I think we're going to have syntax eventually for in/out/inout types. Everything I see here is compatible with that direction but it's good to keep in mind.

Since the input name is munged, you could consider a decorator like a @inputName or something to customize it if needed.

Even with the @invisible decorator applied to union variants, the emitter creators will have to deal with the auto-unwrapping of unions with just one variant. As this would be common functionality to all emitters, perhaps this should be done in a common place like by the TSP compiler

Totally doable 😁 TypeKits are likely the answer here.

@specifiedBy seems like a good addition. Will have to ensure it layers appropriately with @encoding (i.e. using a known encoding should also fill in the @specifiedBy metadata, or we have some compiler API that unifies these two concepts). I'm not entirely sure it needs to be limited to scalar types however? E.g. it may be useful to use on model types to allow linking to specs like geojson, cloud events, or what-have-you.

For duration, the spec can provide a backing scalar using the @encode decorator, so I think the actual graphql type should depend on the backing scalar following the previous rules. For example, @encode(DurationKnownEncoding.seconds, int32) is Int, @encode(DurationKnownEncoding.seconds, float64) is float, @encode(DurationKnownEncoding.seconds, int64) is String.

For nested unions, slightly concerned about completely omitting the TypeSpec declaration of the nested union. Seems somewhat likely it would be referenced in the spec.

For named unions, we could consider always wrapping in a type that includes the variant name. I was hoping we could do this for JSON at one point but that ship has sailed. It basically takes pressure off clients/servers doing complex logic to find discriminators between the variants.

A decorator to control the generated union name might be useful.

Confused about the difference between @modelRoute and @operationFields? Are these just two ways of doing the same thing?

For operations, I think I'm a fan of doing the strict emit route only. The rules seem fairly complex seeing them written out and I think it's fair that adding support for an additional protocol requires decorators sometimes (this is def. true for e.g. protobuf). The non-strict behavior is always something we can add later.

For visibility I think we should not support the string form in this emitter at all, since enum based visibility is coming very soon.

Thanks both! I'll quickly respond to @bterlson 's questions here:

Confused about the difference between @modelRoute and @operationFields? Are these just two ways of doing the same thing?

Yes, they are. We just wanted to present both, but we're leaning towards operationFields rather than modelRoute and modelRoute will be discarded as we couldn't find a reason to prefer it over operationFields. With operationFields, we get to define field near the model and that seems to make more sense. Example playground

Sounds good, I agree with that assessment I think.
How does the 18th at 10am America/Los_Angeles sound for a final review of this proposal with the TypeSpec design crew?


Postgres schema name does not show on ERD.

The schema name is not shown on the object in the ERD. It's only visible on the tooltip.
The ERD is created in a project. (The only way to see different schema tables in the same ERD)
In the attached image, schema1.table1  and schema2.child is depicted. But the schemas are not visible in the design.

We can add extra ERD config option (in addition to attributes visibility and layout) to show FQ table names.


Crash when showing size of replaced music that does not exist

beet git version updated now
Ubuntu 14.04 64 bits
Python 2.7.8
I have imported an album. I have deleted from disk. I have imported again and beets crash:
$ beet im /dunehd/Musica\ pendiente/Madonna\ –\ Rebel\ Heart\ \[Deluxe\ Edition\ 2015\]\(MP3\ 320\ Kbps\)/

/dunehd/Musica pendiente/Madonna – Rebel Heart [Deluxe Edition 2015](MP3 320 Kbps)/Track List (25 items)
Correcting tags from:
    Madonna - Rebel Heart Deluxe
To:
    Madonna - Rebel Heart (Super Deluxe Edition)
URL:
    http://musicbrainz.org/release/0911931a-3770-4cb7-ba67-3d2fda24d2e8
(Similarity: 97.5%) (album, tracks) (Digital Media, 2015)
 * Living For Love                               -> Living for Love
 * Bitch I'm Madonna (feat. Nicki Minaj)         -> Bitch I’m Madonna (title)
 * Iconic (feat. Chance the Rapper & Mike Tyson) -> Iconic (title)
 * Veni Vidi Vici (feat. Nas)                    -> Veni Vedi Vici (title)
This album is already in the library!
Traceback (most recent call last):
  File "/usr/local/bin/beet", line 9, in <module>
    load_entry_point('beets==1.3.11', 'console_scripts', 'beet')()
  File "/usr/local/lib/python2.7/dist-packages/beets-1.3.11-py2.7.egg/beets/ui/__init__.py", line 953, in main
    _raw_main(args)
  File "/usr/local/lib/python2.7/dist-packages/beets-1.3.11-py2.7.egg/beets/ui/__init__.py", line 943, in _raw_main
    subcommand.func(lib, suboptions, subargs)
  File "/usr/local/lib/python2.7/dist-packages/beets-1.3.11-py2.7.egg/beets/ui/commands.py", line 874, in import_func
    import_files(lib, paths, query)
  File "/usr/local/lib/python2.7/dist-packages/beets-1.3.11-py2.7.egg/beets/ui/commands.py", line 851, in import_files
    session.run()
  File "/usr/local/lib/python2.7/dist-packages/beets-1.3.11-py2.7.egg/beets/importer.py", line 316, in run
    pl.run_parallel(QUEUE_SIZE)
  File "/usr/local/lib/python2.7/dist-packages/beets-1.3.11-py2.7.egg/beets/util/pipeline.py", line 301, in run
    out = self.coro.send(msg)
  File "/usr/local/lib/python2.7/dist-packages/beets-1.3.11-py2.7.egg/beets/util/pipeline.py", line 160, in coro
    task = func(*(args + (task,)))
  File "/usr/local/lib/python2.7/dist-packages/beets-1.3.11-py2.7.egg/beets/importer.py", line 1287, in user_query
    resolve_duplicates(session, task)
  File "/usr/local/lib/python2.7/dist-packages/beets-1.3.11-py2.7.egg/beets/importer.py", line 1299, in resolve_duplicates
    session.resolve_duplicate(task, found_duplicates)
  File "/usr/local/lib/python2.7/dist-packages/beets-1.3.11-py2.7.egg/beets/ui/commands.py", line 789, in resolve_duplicate
    not task.is_album,
  File "/usr/local/lib/python2.7/dist-packages/beets-1.3.11-py2.7.egg/beets/ui/commands.py", line 446, in summarize_items
    total_filesize = sum([item.filesize for item in items])
  File "/usr/local/lib/python2.7/dist-packages/beets-1.3.11-py2.7.egg/beets/dbcore/db.py", line 316, in __getattr__
    return self[key]
  File "/usr/local/lib/python2.7/dist-packages/beets-1.3.11-py2.7.egg/beets/dbcore/db.py", line 224, in __getitem__
    return getters[key](self)
  File "/usr/local/lib/python2.7/dist-packages/beets-1.3.11-py2.7.egg/beets/library.py", line 424, in <lambda>
    getters['filesize'] = lambda i: os.path.getsize(syspath(i.path))
  File "/usr/lib/python2.7/genericpath.py", line 49, in getsize
    return os.stat(filename).st_size
OSError: [Errno 2] No such file or directory: '/home/simon/M\xc3\xbasica/Madonna/Rebel Heart (Super Deluxe Edition)/01 - Living for Love.mp3'

Thanks! This looks like it came from #1291. @tomjaspers, would you mind adding error-handling for the getsize call? This could just log a warning and return a dummy value like 0.

Okay I'll have it done tomorrow

Thank you, @tomjaspers! :sparkles:


test_channel.vim fails on macOS

Steps to reproduce

Clone source (commit 870219c58c0804bdc55419b2e455c06ac715a835)
make -C the-source/src/testdir test_channel

Expected behaviour
The test should pass
Version of Vim
9.0.1247
Environment

macOS 12.6.2
Alacritty
alacritty, but I set TERM=xterm during tests typically to prevent termcap warnings during certain tests
Zsh

Notably, I can reproduce this only on my work computer; my personal laptop (macOS 11.7) passes just fine.
Logs and stack traces
It looks like the connection times out even after resolving localhost to IPv6, but when I run the server with `python3 test_channel.py`, I can `telnet localhost port` or `telnet ::1 port` (though I cannot `telnet <IP_ADDRESS> port`).

`channellog`:

==== start log session Jeu jan 26 16:27:01 2023 ====
  0.003308 : ch_log(): Test_call()
  0.003426 : Starting job: python3  test_channel.py
  0.003454 on 0: Created channel
  0.004368 : closing logfile channellog
  0.004620 : ui_delay(10)
  0.014844 : looking for messages on channels
  0.015482 : ui_delay(10)
  0.025530 : looking for messages on channels
  0.026006 : ui_delay(10)
  0.036167 : looking for messages on channels
  0.036560 : ui_delay(10)
  0.048605 : looking for messages on channels
  0.049134 : ui_delay(10)
  0.059417 : looking for messages on channels
  0.059858 : ui_delay(10)
  0.070091 : looking for messages on channels
  0.070612 : ui_delay(10)
  0.081568 : looking for messages on channels
  0.082218 on 1: Created channel
  0.082863 on 1: Resolved localhost to ::1
  0.082879 on 1: Trying to connect to ::1 port 58761
  0.088327 on 1: Connecting...
  0.088491 on 1: Waiting for connection (waiting 1 msec)...
  0.089545 ERR on 1: Connection timed out
  0.089574 on 1: Resolved localhost to <IP_ADDRESS>
  0.089584 on 1: Trying to connect to <IP_ADDRESS> port 58761
  0.096763 on 1: Connecting...
  0.096852 on 1: Waiting for connection (waiting 1 msec)...
  0.096891 ERR on 1: Connection timed out
  0.096980 on 0: Stopping job with ''
  0.097234 on 0: detaching channel from job
  0.098525 on 0: channel_select_check(): Read EOF from ch_part[1], closing
  0.098550 on 0: channel_select_check(): Read EOF from ch_part[2], closing
  0.101687 : ui_delay(20)
  0.126334 : looking for messages on channels
  0.126417 on 1: Closing channel because all readable fds are closed
  0.126442 on 1: Closing channel
  0.126463 on 1: Closing channel
  0.126483 on 1: Clearing channel
  0.126503 on 1: Freeing channel
  0.126526 on 0: Closing channel because all readable fds are closed
  0.126546 on 0: Closing channel
  0.126575 on 0: Closing channel
  0.126595 on 0: Clearing channel
  0.126614 on 0: Freeing channel
  0.126667 : Job ended
  0.126698 : Freeing job
  0.126725 : looking for messages on channels
  0.126748 : ui_delay(1000)
  1.131146 : looking for messages on channels
  1.131221 : ui_delay(971)
  2.105593 : looking for messages on channels
[ repeats for Test_call and other failing tests ]

Hm, there were some IPv6 related changes in https://github.com/vim/vim/commit/765d82a657c5e42d5d7c88ae410e53f398c34c43
Perhaps @jamessan knows about it, since he made the latest change?

If I can get gdb working with Vim on both machines, I'll try to debug just the call to ch_open while running the Python server.

Personal computer resolving localhost to [::1] (start server, debug compiled vim, run :echo ch_open('localhost:PORT', {})):

channel.c:658 (ret = connect(…);) returns -1, but the python server prints "socket opened." Then the code jumps through some select stuff to finally confirm the socket is really truly open (channel.c:713 (ret = select(sd + 1, …)) returns 1 and channel.c:745 (ret = getsockopt(…) returns 0, so channel.c:770 (if (FD_ISSET(sd, …)) break;) breaks out). Return the socket descriptor sd and continue as normal.

Work machine (same steps):

same return val from connect; same return val from select; same return val from getsockopt; same break. Cannot reproduce failure (?).

Work machine (no debugger; just run ./src/vim and :echo ch_open(…)):

prints "channel fail"

This suggests it could be a timing issue on the work machine? Since debugging slows things down? How can I test this?

Repro'd on d6e4c75af2d6435794f1a9259141d6d7c1923b4c (latest master); adding mch_delay(1000, MCH_DELAY_IGNOREINPUT) as in the following patch did NOT eliminate the problem, so I don't think my experience in the debugger should be chalked up to timing. Thoughts on how to reproduce the problem in the debugger or where else to look?
diff --git i/src/channel.c w/src/channel.c
index db4568d..c5cc116 100644
--- i/src/channel.c
+++ w/src/channel.c
@@ -655,6 +655,7 @@ channel_connect(
 	// Try connecting to the server.
 	ch_log(channel, "Connecting...");

+	mch_delay(1000, MCH_DELAY_IGNOREINPUT);
 	ret = connect(sd, server_addr, server_addrlen);
 	if (ret == 0)
 	    // The connection could be established.

You could try changing "1" to "100" or so.

Anything over 15 was sufficiently non-flaky on the work machine. Feel free to adjust the comment, too:
diff --git i/src/channel.c w/src/channel.c
index db4568d..bd28eac 100644
--- i/src/channel.c
+++ w/src/channel.c
@@ -980,10 +980,10 @@ channel_open(
 	ch_log(channel, "Trying to connect to %s port %d", dst, port);

 	// On Mac and Solaris a zero timeout almost never works.  At least wait
-	// one millisecond.  Let's do it for all systems, because we don't know
+	// 15 milliseconds.  Let's do it for all systems, because we don't know
 	// why this is needed.
 	if (waittime == 0)
-	    waittime = 1;
+	    waittime = 15;

 	sd = channel_connect(channel, addr->ai_addr, (int)addr->ai_addrlen,
 								   &waittime);


SharePoint Online Client Extensibility Web Application Principal - where can I find the public signature?

I opened this issue in the sp-dev-docs github but they considered it an Azure issue.
I would like to verify the JWT generated by the aadTokenProviderFactory but cannot figure out where the signature keys are stored.
None of the signatures at https://login.microsoftonline.com/common/discovery/keys or  https://login.microsoftonline.com/common/discovery/v2.0/keys are valid.
The original issue and discussion: https://github.com/SharePoint/sp-dev-docs/issues/3860

@butchmarshall Thanks for your feedback! We will investigate and update as appropriate.

I'm using the code from this document: https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/guidance/connect-to-api-secured-with-aad
I wish to verify the JWT generated by the code here:

@butchmarshall Please open a Azure Support Ticket so that a dedicated Identity Support engineer can check further on this issue. In case you limitations in your support plan to open support ticket please let me know and I will create a one time free support ticket for you.

@butchmarshall We will now proceed to close this thread as we haven't heard back. If there are further questions regarding this matter, please reopen it and we will gladly continue the discussion.

Sorry I haven't had time to follow up yet.
I'll try to open a support ticket - but I don't believe this is an issue with just my system.
Every one of our SharePoint tenants I've attempted this with has the same issue: butchdevtembosocial, tembosocialo365-dev, northflight and rivernorthair

@butchmarshall Sure, please let me know in case you need any help.  Also, please provide me case number over here and I will also follow-up internally to help you on this issue.

Thanks - I've created the support ticket<PHONE_NUMBER>02580

@butchmarshall I'am running into the same issue, were you able to fix it?


Assertion in broker

I am still getting an assertion in the broker:
broker: /home/pi/mqtt_cpp/include/mqtt/endpoint.hpp:9103: void mqtt::endpoint<std::mutex, lock_guard, 2>::send_connack(bool, variant<mqtt::connect_return_code, v5::connect_reason_code>, v5::properties) [Mutex = std::mutex, LockGuard = lock_guard, PacketIdBytes = 2]: Assertion `false' failed.
Aborted
it is this assertion:
https://github.com/redboltz/mqtt_cpp/blob/abb4f525d9eec4e6c7cce2c770d3bffa66f95314/include/mqtt/endpoint.hpp#L9137

It is caused by the broker sends connack but the version_ is neither v3_1_1 nor v5.
version_ is set at the only two location.
One is
https://github.com/redboltz/mqtt_cpp/blob/abb4f525d9eec4e6c7cce2c770d3bffa66f95314/include/mqtt/endpoint.hpp#L4877-L4879
the other is
https://github.com/redboltz/mqtt_cpp/blob/abb4f525d9eec4e6c7cce2c770d3bffa66f95314/include/mqtt/endpoint.hpp#L6666-L6693
Broker uses the latter.
Before the version_ is set, the broker create endpoint using the following constructor.
https://github.com/redboltz/mqtt_cpp/blob/abb4f525d9eec4e6c7cce2c770d3bffa66f95314/include/mqtt/endpoint.hpp#L189-L195
The version is set by server.hpp
https://github.com/redboltz/mqtt_cpp/blob/abb4f525d9eec4e6c7cce2c770d3bffa66f95314/include/mqtt/server.hpp#L143-L145
The initial value is undetermined.
https://github.com/redboltz/mqtt_cpp/blob/abb4f525d9eec4e6c7cce2c770d3bffa66f95314/include/mqtt/server.hpp#L192
The example broker doesn't pass version parameter.
https://github.com/redboltz/mqtt_cpp/blob/abb4f525d9eec4e6c7cce2c770d3bffa66f95314/example/broker.cpp#L18
So the server creates endpoint using default version_ (aka undetermined)
https://github.com/redboltz/mqtt_cpp/blob/abb4f525d9eec4e6c7cce2c770d3bffa66f95314/include/mqtt/server.hpp#L176
The broker send connack in the connack handler.
https://github.com/redboltz/mqtt_cpp/blob/abb4f525d9eec4e6c7cce2c770d3bffa66f95314/include/mqtt/broker/broker.hpp#L767
https://github.com/redboltz/mqtt_cpp/blob/abb4f525d9eec4e6c7cce2c770d3bffa66f95314/include/mqtt/broker/broker.hpp#L773
https://github.com/redboltz/mqtt_cpp/blob/abb4f525d9eec4e6c7cce2c770d3bffa66f95314/include/mqtt/broker/broker.hpp#L787
https://github.com/redboltz/mqtt_cpp/blob/abb4f525d9eec4e6c7cce2c770d3bffa66f95314/include/mqtt/broker/broker.hpp#L787
But I found one exception case.
This is it.
https://github.com/redboltz/mqtt_cpp/blob/abb4f525d9eec4e6c7cce2c770d3bffa66f95314/include/mqtt/broker/broker.hpp#L323-L335
When the broker get protocol_error, and the underlying connection is still established, then call connack with protocol_error.
It seems that the reason of assertion failed.
Because at that time, MQTT is not connected. That means version_ of endpoint is not determined yet. The broker shouldn't send connack in this situation.
I will fix it soon.

But then I would have to see a protocol error before the connack is send right ? Because I have logging enabled

or maybe connection is closed before mqtt connection establishement is complete, and this caused the error_handler to be called ?

I guess that the client sends  CONNECT packet with something protocol error.

or maybe connection is closed before mqtt connection establishement is complete, and this caused the error_handler to be called ?

If broker detects underlying layer's disconnection, then
  else if (sp->underlying_connected()){

returns false. So the assertion failed doesn't happedn.
If you get the backtrace when the assertion fail happens, it is helpful for debugging.

yes, let me apply your fix and then try to get backtrace.

It seems stable now with fix


Add methods for calculating positions of mates

When player moves with mates, the mates follow him and stay close to him. Figure out how the client handles it and try to replicate that. Expose the methods somewhere. Maybe add them directly to pathfinding?

It seems to me that the positions are quite random, at one of: player + {(1, 1), (-1, -1), (1, -1), (-1, 1), (1, 0), (0, 1), (-1, 0), (0, -1)}


Update test.py

User description
Added test cases

PR Type
Tests

Description

Added multiple new test cases to the TestDiffMotionDetector class to ensure robustness and error handling:

Tests for successful binary image return after setting background and foreground images.
Tests for handling None as input for background and foreground images, ensuring appropriate None responses.
Comprehensive testing of both successful operations and error handling in motion detection scenarios.

Changes walkthrough 📝
Relevant filesTests

test.pyEnhance and Expand Test Coverage for Motion Detection

tests/test_diff_motion_detector/test.py
Added tests for binary image return success in motion detection.  Added tests for handling None inputs for background and foreground images.  Enhanced existing test suite with comprehensive scenarios for motion detection.

+38/-2

💡 PR-Agent usage:
Comment /help on the PR to get a list of all available PR-Agent tools and their descriptions

/describe
--pr_description.extra_instructions="
For the title, use the format [type]: [summary]
"
--pr_description.publish_labels=true
--pr_description.publish_description_as_comment=true
--pr_description.generate_ai_title=true

/review
--pr_reviewer.extra_instructions="
In the possible issues section, emphasize the following:

Is the code logic efficient?

"
--pr_reviewer.num_code_suggestions="2"
--pr_reviewer.inline_code_comments=true
--pr_reviewer.require_score_review=true

/improve
--pr_code_suggestions.extra_instructions="
Emphasize the following:

Does the code logic cover relevant edge cases?
Is the code logic clear and easy to understand?
Is the code logic efficient?

"
--pr_code_suggestions.num_code_suggestions_per_chunk="4"
--pr_code_suggestions.commitable_code_suggestions=true

/describe
--pr_description.extra_instructions="
For the title, use the format [type]: [summary]
"
--pr_description.publish_labels=true
--pr_description.publish_description_as_comment=true
--pr_description.generate_ai_title=true

/describe
--pr_description.extra_instructions="
For the title, use the format [type]: [summary]
"
--pr_description.publish_labels=true
--pr_description.publish_description_as_comment=true
--pr_description.generate_ai_title=true

/review
--pr_reviewer.extra_instructions="
In the possible issues section, emphasize the following:

Is the code logic efficient?

"
--pr_reviewer.num_code_suggestions="2"
--pr_reviewer.inline_code_comments=true
--pr_reviewer.require_score_review=true

/improve
--pr_code_suggestions.extra_instructions="
Emphasize the following:

Does the code logic cover relevant edge cases?
Is the code logic clear and easy to understand?
Is the code logic efficient?
Efficiency Concern: The tests test_return_binary_image_successfully and test_set_background_and_return_binary_image_successfully both read the same images from disk multiple times. This could be optimized by reading the images once and reusing them across tests.
--

--

"
--pr_code_suggestions.num_code_suggestions_per_chunk="4"
--pr_code_suggestions.commitable_code_suggestions=true


Use comment matcher in CXX frontend

Small improvement to comment matcher and use it in the CXX frontend.

@oxisto  The "old" setComments method is still used in various places. I'm not sure what to do with it. Should we remove it? It could lead to adding some comments twice now.

@oxisto The "old" setComments method is still used in various places. I'm not sure what to do with it. Should we remove it? It could lead to adding some comments twice now.

You can try to remove it and see if it (doesn't) break :)

@oxisto The "old" setComments method is still used in various places. I'm not sure what to do with it. Should we remove it? It could lead to adding some comments twice now.

You can try to remove it and see if it (doesn't) break :)

Seems to work


Authentication Provider

Add support for a custom Authentication Provider that allows for a user to be authenticated with a phone number and verification code AND allows for the user to have a valid session token/installation id.

Solved via Twilio Verify API


CloudSave

Hello im got error in console in whit new savecloud version
OPTIONS /cloudsave/savetocloud 403 0.392 ms - 48
and reload page have this error : Cloudsave Failed

If you're getting a 403 error it has to do with login credentials.  Did you disable the login plugin?

no its enable

So a 403 means forbidden from the server.  Either your api route is rejecting it because the token is invalid/not there.....or your webserver is rejecting the get/post request before it even hits my system.  Judging by your second issue I think this issue is more to do with your particular server than the plugins.

Ok i try to install HTTPS credential in my server i respost this work

I don't think https will work...

There seems to be something up with your webserver in general.  And I'm more concerned about the message where the preflight has an invalid http code....

Using
Server version: Apache/2.4.10 (Debian)
Server built:   Jul 18 2017 18:32:16
PHP 7.0.20-1~dotdeb+8.2 (cli) ( NTS )

have this error in console have update PHP to 7.1 and have install rewrite module in create .htacces
whit
<IfModule mod_rewrite.c>
	RewriteEngine On
</IfModule>

testing on local and work for client whit maker to server WTF

Found simply solution for allow domain
// allow url
app.use(function(req,res,next){
res.setHeader('Access-Control-Allow-Origin', '*');
next();
});

testing on another Server whit Cpanel juste Client Webserver its on this server and server socket.io on VPS
giving same error

no idea my errror here ?

have search few solution in internet and have so have testing on My VPS ! so nelderson have always time im testing same error
Not work have 403 Same error :(

    map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
    }

upstream websocket {
    server localhost:8000;
}

server {
    listen       80;
    server_name  localhost;
	    proxy_pass_header Set-Cookie;

     location ~ ^/(node|socket\.io) {
        proxy_pass http://websocket;
        proxy_http_version 1.1;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header Host $http_host;
         proxy_set_header X-NginX-Proxy true;
         proxy_set_header Upgrade $http_upgrade;
         proxy_set_header Connection "upgrade";
    	proxy_pass_header X-XSRF-TOKEN;
    }

    location /index.html {
        root   /var/www/html/;
    }

    location ~ \.css {
        root   /var/www/html;
        expires max;
    }

    location ~* \.(jpg|jpeg|png|gif|ico|js|woff|woff2|ttf|json)$ {
        root   /var/www/html;
        access_log off;
        expires max;
    }

    location ~* \.(js|css)$ {
        expires 1y;
        log_not_found off;

    }

    location /cloudsave/loadfromcloud {
	proxy_pass http://websocket;
        proxy_http_version 1.1;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header Host $http_host;
         proxy_set_header X-NginX-Proxy true;
         proxy_set_header Upgrade $http_upgrade;
         proxy_set_header Connection "upgrade";
    	proxy_pass_header X-XSRF-TOKEN;
         proxy_redirect off;
    }

    location /cloudsave/savetocloud {
	proxy_pass http://websocket;
        proxy_http_version 1.1;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header Host $http_host;
         proxy_set_header X-NginX-Proxy true;
         proxy_set_header Upgrade $http_upgrade;
         proxy_set_header Connection "upgrade";
    	proxy_pass_header X-XSRF-TOKEN;
         proxy_redirect off;
    }

    location /cloudsave {
	proxy_pass http://websocket;
        proxy_http_version 1.1;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header Host $http_host;
         proxy_set_header X-NginX-Proxy true;
         proxy_set_header Upgrade $http_upgrade;
         proxy_set_header Connection "upgrade";
    	proxy_pass_header X-XSRF-TOKEN;
	 proxy_redirect off;
    }

}

YEAHHHHH !!! Found Error ! Comment in few minute !


Add gelf output plugin to fluentbit

What this PR does / why we need it:
Which issue(s) this PR fixes:

Fixes #881
Does this PR introduced a user-facing change?

Add gelf output plugin to fluentbit

Additional documentation, usage docs, etc.:

Hi @wenchajun ! Thanks for the review.

Is the corresponding match field missing?

I don't think it's missing because it's handled by this part of the code: https://github.com/fluent/fluent-operator/blob/master/apis/fluentbit/v1alpha2/clusteroutput_types.go#L153
If I create the following manifest:
apiVersion: fluentbit.fluent.io/v1alpha2
kind: ClusterOutput
metadata:
  name: test
  labels:
    fluentbit.fluent.io/enabled: "true"
    fluentbit.fluent.io/mode: "fluentbit-only"
spec:
  matchRegex: "*"
  gelf:
    host: <IP_ADDRESS>
    port: 12202
    mode: tls
    tls:
      verify: true

The generated configuration looks like:
[Output]
    Name    gelf
    Match_Regex    *
    Host    gra1.logs.ovh.com
    Port    12202
    Mode    tls
    tls    On
    tls.verify    true

Here it uses matchRegex but it's the same as for match.
But maybe I'm wrong ?

@patrick-stephens what do you think?

@patrick-stephens @wanjunlei what do you think?

Not sure what you're querying here - all filter+output plugins support match and match_regex.
I think the docs have just included the field explicitly.

@patrick-stephens @wanjunlei what do you think?

Not sure what you're querying here - all filter+output plugins support match and match_regex. I think the docs have just included the field explicitly.

Agree, Match & MatchRegex are common attributes of output plugins:
https://docs.fluentbit.io/manual/administration/configuring-fluent-bit/classic-mode/configuration-file#config_output
https://github.com/fluent/fluent-operator/blob/master/apis/fluentbit/v1alpha2/clusteroutput_types.go#L39


made the ui cleaner

PR Fixes:

Cleaner UI

Resolves #313

@alexbennycodes
@nimit9 solved this in #307

@Pratham271 can you remove the appbar changes from this PR, otherwise it'll cause major merge conflicts with the one I've raised

closing because of conflicts