text:
feat(v2): @docusaurus/init package

Motivation
Close #1601

Not a good idea for user to install whole core package just to init, so lets separate it into separate package like CRA
No longer silently install for ez debugging
Less dependencies on core

The right way to test this out as npm package is to actually release alpha.20 and try it out.
Others

Fix other bug on theme/Layout regarding metaimage
Some TS deps typing

Have you read the Contributing Guidelines on pull requests?
yes
Test Plan
At root, after installing, compile typescript and mimic running the init command
https://asciinema.org/a/vcInXTcBCChXyIexXPmIAx4HI

Deploy preview for docusaurus-preview failed.
Built with commit 3c0a507476f6d980b33c3b996f5a91aea4fd6839
https://app.netlify.com/sites/docusaurus-preview/deploys/5d2a038a52998800079eb4db

Deploy preview for docusaurus-preview failed.
Built with commit 2411afa04abbfdd18e4cf80fda82248e29ab803d
https://app.netlify.com/sites/docusaurus-preview/deploys/5d2a044e4c65460008e04224

Can we do a @docusaurus/cli package instead and move the commands there? Idk if our architecture permits that at the moment but it'll be good if we can do that.

I actually thought of that too but after some thought i realize that this approach has a very superior advantage: super fast and separated concern. This is also an approach used by CRA.
The thing with having CLI (which i believe can be installed globally like gatsby-cli) and being separated from core is that it can sometimes lead to subtle bugs in behavior and functionality if the version of the globally installed executable does not match the version of core.
Another thing is that if we move the init to docusaurus/cli, it means that the init templates wlll live inside that package. More installation time for all user that doesnt want to init
.
Here's what i suggest:
lets try this out first, since at least this is better than having to install whole core just to init new project.
then, lets create an issue and try to see if docusaurus/cli is worth it. im hoping to get people more experienced with cli stuff to contribute for this part

just the src/pages and src/themes docs stuff and we should be good to go for alpha 20
oh and pls help to add to our tasklist on the CLI in case i forget. gotta sleep


text:
feat: adds blog archive route

Motivation
Fixes #4431

Special thanks to @johnnyreilly (https://blog.johnnyreilly.com/2021/05/01/blog-archive-for-docusaurus) for the inspiration and starting an issue to have this added.
Have you read the Contributing Guidelines on pull requests?
Yes
Test Plan
Navigating to http://localhost:3000/blog/archive when serving the website via (cd website;yarn start;) will yield the new blog archive page. Please see the attached screenshot the expected output.
Related PRs
Docs have been updated in this PR to reflect the new option.

cc @slorber

Thanks @gabrielcsapo
I cleaned up a bit your PR and added missing i18n support.
Going to merge/release it now in beta.6
We can still improve this page in the future but at least an initial version is here.
We could link to it in the sidebar once it's ready to become more "visible" and we consider the design stable enough.

I think it's better to use reverse chronological order, and maybe just content as lists, including date of posts?

Oh sorry just saw your comment after merging 😅 wanted to merge it fast because I'm releasing beta.6 asap and it seemed good enough for a first version.
Yes I actually found the years ordering a bit weird, and the design can be improved, please feel free to do so in another PR for the next release

Don't worry, I'll try to find more examples of blog archives, and then probably improve current design.

I think it's better to use reverse chronological order, and maybe just content as lists, including date of posts?

Agree with this.  I'm so pleased this landed; I think it needs a little polish though.  This is what it looks like on my own blog:

The "Archive... Archive" could be tweaked to make more lovely I think

I just tried to use the archive.description / archive.title functionality and was presented with this:
A validation error occurred.
The validation system was added recently to Docusaurus as an attempt to avoid user configuration errors.
We may have made some mistakes.
If you think your configuration is valid and should keep working, please open a bug report.

This is my section of docusaurus.config.js:
  presets: [
    [
      '@docusaurus/preset-classic',
      ({
        docs: false,
        blog: {
          archive: {
            title: 'Blog Archive',
            description: 'Historic posts'
          },
          blogTitle: 'I CAN MAKE THIS WORK',
          blogDescription: 'The blog of johnnyreilly',
          /**
           * Number of blog post elements to show in the blog sidebar
           * 'ALL' to show all blog posts
           * 0 to disable
           */
          blogSidebarCount: 5,
          postsPerPage: 1,
          path: "./blog",
          routeBasePath: "/", // Set this value to '/'.
          showReadingTime: true,
          editUrl:
            "https://github.com/johnnyreilly/blog.johnnyreilly.com/edit/main/blog-website/blog/",
        },
        theme: {
          customCss: require.resolve('./src/css/custom.css'),
        },
      }),
    ],

It's possible I'm doing it wrong; but I am unable to work out how to do it right.... Moving the archive section up a level doesn't seem to work either.
As well as the console error it doesn't seem to affect the content of the generated page either?

Can it be configured though? The theme.blog.archive.description is only an ID for translation and doesn't have any implications of configuration structure. The only config option right now is archiveRoute

Maybe it can't be configured. If it can't it's probably something that would be desirable

Definitely worth improving on. Also, if we add this in options, we will transfer the translation to plugin-blog instead, and we can start to populate the options.json file😉

You can use the i18n support tu customize all English labels, I don't think
it's worth it to add an option for each individual label
Le sam. 4 sept. 2021 à 15:18, Joshua Chen @.***> a
écrit :

Definitely worth improving on. Also, if we add this in options, we will
transfer the translation to plugin-blog instead, and we can start to
populate the options.json file😉
—
You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub
https://github.com/facebook/docusaurus/pull/5428#issuecomment-912982007,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAFW6PWY2XLZFF2LUWDWKGTUAITCXANCNFSM5C3YWNXQ
.

You can use the i18n support tu customize all English labels, I don't think it's worth it to add an option for each individual label

In the same way we allow customizing the sidebar title and the blog title, we should allow customizing the archive title. For example, my site has a default en locale and a translated zh-Hans locale under i18n, and I never write any en translation because that's supposed to be the "default". Using i18n to customize labels means I essentially have to start a new locale under the i18n folder. If that's the encouraged practice in the future, we can actually get rid of a lot of text label options in the config file, but is that desirable on the user side? At least not for the people not using i18n IMO

We have a lot of text, aria labels etc in multiple places the theme and plugins.
Adding all those to options would be quite overwhelming and create a large option api surface that would have breaking changes when we refactor UI.
I feel it's more convenient and future proof to document better that the way to customize default english labels is by using docusaurus write-translations and customizing the labels in i18n/en/code.json
At the same time the other files would feel "duplicate" (user does not want to translate the sidebar because it's already localized correctly). We should probably provide a way to override theme labels without using the i18n/en folder, probably thanks to an extra Docusaurus config.

source: gharchive/pull-request

authors: Josh-Cena gabrielcsapo johnnyreilly lex111 slorber

repo: facebook/docusaurus

license: MIT

license_type: permissive

license_source: github-api


text:
Adds customStyleMap for more control over inline style ranges #342

cc @hellendag
Note, I also considered making customStyleMap and customStyleFn mutually exclusive, where if the latter were specified, then the former would materialize a function with the current behavior and only pass down customStyleMap to the leaf component -- but, then you'd lose the default behavior, which seems a little aggressive.
I think as long as it's clear that customStyleFn will execute after any customStyleMap additions then this is fine.
The downside here, is that just specifying a customStyleFn means that the default draft styles will always apply and you'd have to overwrite them to stop it (which is the current situation anyway).

I like this, and I think that in the long term, this approach will make sense as a replacement for the style map given the superior flexibility.

@hellendag comments addressed. Thanks

@hellendag anything needed further on this PR for merge?

LGTM. Let's do it.

repo: facebook/draft-js

license: mit

license_source: bigquery


text:
proposal: Generated Data Loaders

It would be nice if ent would generate some sort of dataloaders / context-specific caching and batching layer like https://github.com/vektah/dataloaden. That would simplify using ent in GraphQL APIs a lot by removing the need to build an extra abstraction layer over "simple" database operations.

Hey @BitPhinix, that's a great idea.
As I commented here, we already have some gqlgen integration that we want to OSS and it's ongoing (We actually tackled this problem with field-collections and eager-loading).
I'll move this issue to the new repository once it's out.

That would be awesome - and is exactly what I've been looking for. When are you planning to release it? I would love to use it asap. Thanks for this awesome project!

Any update on OSS-ing gqlgen integration?

Still waiting for the gqlgen integration release

QQ on this – is the proposal to adopt Relay node/connection approach?

Hey guys, the GraphQL integration was open-sourced along with a (WIP) doc - entgo.io/docs/graphql.
Closing, but please go over it and open an issue if there's a specific feature that's miss there. Thanks

I took a look at the integration but I am still unsure if the original question was answered. I tried to run the todo example to see if it was using some kind of batching to avoid the N+1 issue and I don't think it does? I think it either misses some documentation on the topic or it is not done yet, can you comment on that @a8m.
It was actually one of the first things I check for new server implementations.
I think the best would be to create a complete/complex example of GraphQL + ent that has multi-tenant and deeply nested loading and permission checks with the privacy feature. Currently I have a hard time judging if ent + entgql is production ready.

Hey @Sytten,

I took a look at the integration but I am still unsure if the original question was answered. I tried to run the todo example to see if it was using some kind of batching to avoid the N+1 issue and I don't think it does? I think it either misses some documentation on the topic or it is not done yet, can you comment on that @a8m.

The GraphQL documentation needs some improvement (I'll add more details to it), but as mentioned above, entgql uses GraphQL field collection and eager loading for solving this problem. That means, if you query nodes and their edges, entgql automatically adds With<E> steps to your root query, and as a result, you'll only have constant number of queries to the database (and it works recursively).
For example, given this query:
query {
  users(first: 100) {
    edges {
      node {
        photos {
          link
        }
        posts {
          content
          comments {
            content
          }
        }
      }
    }
  }
}

You should see 1 query for getting the users, 1 for getting the photos, and another 2 for getting the posts and their comments (4 in total).
The logic I mentioned here works both for root queries/resolvers and for the node(s) API.
Regarding the todo-app example (in entgql), you can find the root resolvers in this file, the generated edge resolvers in this files, and the eager-loading binding here (the actual implementation for the eager-loading binding).
I OSS-ed entgql after we were running with it almost a year in production, so it's definitely in a production ready state. If you have specific troubles with it, or there's something concrete that doesn't work for you, let me know and I'll try to help.

@a8m Thanks a lot for the answer, looks good to me! It is an interesting take on the N+1 problem for sure.
It leaves me wondering how privacy filter that requires two levels deep would work. Say if I have Tenant -> Group -> User and I want to make sure a user can only see other users in the tenant.
If I had a dataloader I would be confident that it would be a constant amount of requests, but here I think it would most likely need another DB request right?

It leaves me wondering how privacy filter that requires two levels deep would work. Say if I have Tenant -> Group -> User and I want to make sure a user can only see other users in the tenant.

Can you elaborate how does your multi-tenancy model look like? I'm familiar with 3 different approaches and I implemented all the 3 with ent (and ent-privacy) - 1) A tenant column on each table 2) A Tenant node connected to all other nodes 3) Named-database per tenant.
The first 2 approached can be implemented with ent-privacy (i.e. FilterRule) which mutates the actually query (and doesn't execute additional query to the database) and the third one doesn't really need privacy layer for the tenant-filtering logic.

If I had a dataloader I would be confident that it would be a constant amount of requests, but here I think it would most likely need another DB request right?

I don't really understand what do you mean tbh. How does dataloader queries different from any other queries? You still need to  filter by tenant, right? Do I miss anything?

Is it also possible to mix that with some custom resolvers for specific fields? I have some statistics that require custom SQL. I remember seeing someone mention thia need in another issue.

What is "that"? If you mean the edge-resolver, the answer is yes. You can override the default resolvers using gqlgen config (see, entgo docs).
If you want to share more about your use-case, I can try to help - I should be available on the Slack channel after the weekend. Feel free to ping me there.

Dataloaders
So here is a more real world example of what I am talking about:

So if I was doing it with dataloaders:

If I query orders and then ask for products, it is also fine because the dataloader already knows about the orders so it won't load them again to verify the permissions of products.
If I query products I load the orders and then check the tenant_id on those and compare that to the viewer context. That does another SQL query to get the orders, it's fine since it will be grouped in a single query loading all orders at once.
If I query comments, the dataloaders first query the products then query the orders. More work, but it is also fine because queries are grouped together so it only does 3 queries.

What would be the equivalent when using privacy filters?
Custom SQL
So I am building an observability SaaS for GraphQL, I am using TimescaleDB with some custom SQL functions that I need to call. I want to use ent for the rest of the system (Tenants, users, settings, api keys, etc.) but some fields will require SQL:
{
  type(id: "dsadsa", filter: {start: "2020-12-01", end: "2020-12-31"}) {
    fields {
      latency { # This requires custom SQL
        timestamp
        value
      }
    }
  }
}

I am guessing that those fields will have a custom gqlgen resolvers anyway since they don't appear in the ent models.
Thanks a lot for the answers BTW, I feel the questions would help others too so feel free to put them in the doc.

Sorry for the delay - weekend mode 🏖

Dataloaders
So here is a more real world example of what I am talking about:

So if I was doing it with dataloaders:

If I query orders and then ask for products, it is also fine because the dataloader already knows about the orders so it won't load them again to verify the permissions of products.
If I query products I load the orders and then check the tenant_id on those and compare that to the viewer context. That does another SQL query to get the orders, it's fine since it will be grouped in a single query loading all orders at once.
If I query comments, the dataloaders first query the products then query the orders. More work, but it is also fine because queries are grouped together so it only does 3 queries.

What would be the equivalent when using privacy filters?

When you mention "query", do you mean GraphQL query? Does it mean that users can query comments and products directly in your example (i.e. root fields and resolvers)?
If you don't have an edge (or a field) from the Tenant type, you can add a privacy rule for filtering by an edge and there's no need for loading the associations for this. For example:
// On product privacy filter rule.
q.Where(
    product.HasOrderWith(
        order.HasTenantWith(tenant.ID(tenant))
    ),
)

If you have an edge to the Tenant type, you can create an ent.Mixin for holding the edge for the Tenant schema and the basic privacy policy for filtering by the tenant_id, and share it with all different schemas.
Of course, filtering by tenant_id is a super simple example for privacy policy. Our case is far more complicated than this, and it's working great for us - I hope to come up with some extensive example in the near future (it requires a lot of effort).
Another last comment regarding this subject - we decided to tackle the "N+1 problem" for GraphQL in a different way than dataloader, because we found it much cleaner and simpler to use and understand. In the examples you mentioned, it looks like you use (or want to use) the dataloader also as a cache - to get objects that were already requested (right?) - if that's the case, I plan to provide support for multi-level cache in ent (request/session-level cache and a secondary-level cache like memcache/redis). I just prefer to separate the 2 problems.

So I am building an observability SaaS for GraphQL, I am using TimescaleDB with some custom SQL functions that I need to call. I want to use ent for the rest of the system (Tenants, users, settings, api keys, etc.) but some fields will require SQL:

Can you elaborate what type of custom SQL do you plan to use? You can extend ent using custom-templates

Sorry for the delay - weekend mode 🏖

Not worries, this is helping me so much @a8m!

Dataloaders
So here is a more real world example of what I am talking about:

So if I was doing it with dataloaders:

If I query orders and then ask for products, it is also fine because the dataloader already knows about the orders so it won't load them again to verify the permissions of products.
If I query products I load the orders and then check the tenant_id on those and compare that to the viewer context. That does another SQL query to get the orders, it's fine since it will be grouped in a single query loading all orders at once.
If I query comments, the dataloaders first query the products then query the orders. More work, but it is also fine because queries are grouped together so it only does 3 queries.

What would be the equivalent when using privacy filters?

When you mention "query", do you mean GraphQL query? Does it mean that users can query comments and products directly in your example (i.e. root fields and resolvers)?

Exactly

If you don't have an edge (or a field) from the Tenant type, you can add a privacy rule for filtering by an edge and there's no need for loading the associations for this. For example:
// On product privacy filter rule.
q.Where(
    product.HasOrderWith(
        order.HasTenantWith(tenant.ID(tenant))
    ),
)

That makes sense, I didn't know you could nest thewhere like that.

If you have an edge to the Tenant type, you can create an ent.Mixin for holding the edge for the Tenant schema and the basic privacy policy for filtering by the tenant_id, and share it with all different schemas.

My point was more that if we have a privacy policy on the mixin, it will do unnecessary joins on the DB at each level if I am not mistaken (please correct me if I am wrong). This is fine but I guess you have to be aware of it. Say you start from products and you then load comments. The privacy filter on product will join with order to get the tenant ID. Then the privacy filter for comments will join on products and orders to get the tenant id. Where dataloaders you don't need to do that because it acts as a cache too for children graphql resolvers (and thus privacy filters).

Of course, filtering by tenant_id is a super simple example for privacy policy. Our case is far more complicated than this, and it's working great for us - I hope to come up with some extensive example in the near future (it requires a lot of effort).

That would be awesome, I think we already have a somewhat complex use case to start from here.

Another last comment regarding this subject - we decided to tackle the "N+1 problem" for GraphQL in a different way than dataloader, because we found it much cleaner and simpler to use and understand. In the examples you mentioned, it looks like you use (or want to use) the dataloader also as a cache - to get objects that were already requested (right?) - if that's the case, I plan to provide support for multi-level cache in ent (request/session-level cache and a secondary-level cache like memcache/redis). I just prefer to separate the 2 problems.

Yes the dataloader caching is pretty important as I mentioned above because it prevents queries from children resolvers from having to do joins for privacy filtering. But an alternate solution is bad either, let's just make it easy to replace joins in privacy rules for better performances.

So I am building an observability SaaS for GraphQL, I am using TimescaleDB with some custom SQL functions that I need to call. I want to use ent for the rest of the system (Tenants, users, settings, api keys, etc.) but some fields will require SQL:

Can you elaborate what type of custom SQL do you plan to use? You can extend ent using custom-templates

Mostly custom pl/pgsql functions that are defined by the extension. Mostly aggregations, counts and time filtering. I might write some custom template, but I feel it might call for raw SQL and a dataloader.

source: gharchive/issue

authors: BitPhinix ImKcat Sytten a8m jufemaiz pbrazdil

repo: facebook/ent


text:
installation error

I tried the following command as suggested in the readme
luarocks make rockspec/fbpython-0.1-1.rockspec

And I got the folloing errors. The thpp was installed using the install_all.sh provided.
cmake -E make_directory build &&
cd build &&
cmake -DROCKS_PREFIX=/home/sizhangyu/torch/install/lib/luarocks/rocks/fbpython/0.1-1
-DROCKS_LUADIR=/home/sizhangyu/torch/install/lib/luarocks/rocks/fbpython/0.1-1/lua
-DROCKS_LIBDIR=/home/sizhangyu/torch/install/lib/luarocks/rocks/fbpython/0.1-1/lib
.. &&
make
-- Found Torch7 in /home/sizhangyu/torch/install
-- Boost version: 1.54.0
-- Found the following Boost libraries:
--   thread
-- Found PythonInterp: /usr/bin/python2.7 (found suitable version "2.7.6", minimum required is "2.7")
-- Found PythonInterp: /usr/bin/python2.7 (found version "2.7.6")
-- Configuring done
-- Generating done
-- Build files have been written to: /media/home2/other_tools/fblualib/fblualib/python/build
Scanning dependencies of target lua_module
[ 12%] Building CXX object CMakeFiles/lua_module.dir/Lib.cpp.o
[ 25%] Building CXX object CMakeFiles/lua_module.dir/LuaToPython.cpp.o
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp: In member function ‘fblualib::python::PyObjectHandle fblualib::python::LuaToPythonConverter::convert(lua_State*, int, unsigned int)’:
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:135:56: error: no matching function for call to ‘luaGetTensor(lua_State*&, int&)’
auto tensor = detail::luaGetTensor(L, index);
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:141:5: note: in expansion of macro ‘TENSOR_TO_NDARRAY’
TENSOR_TO_NDARRAY(double, NPY_DOUBLE);
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:135:56: note: candidate is:
auto tensor = detail::luaGetTensor(L, index);
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:141:5: note: in expansion of macro ‘TENSOR_TO_NDARRAY’
TENSOR_TO_NDARRAY(double, NPY_DOUBLE);
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:20:31: note: template typename thpp::Tensor::Ptr fblualib::python::detail::luaGetTensor(lua_State*, int)
typename thpp::Tensor::Ptr luaGetTensor(lua_State* L, int ud) {
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:20:31: note:   template argument deduction/substitution failed:
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp: In substitution of ‘template typename thpp::Tensor::Ptr fblualib::python::detail::luaGetTensor(lua_State*, int) [with T = double]’:
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:141:5:   required from here
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:20:31: error: no type named ‘Ptr’ in ‘class thpp::Tensor’
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:135:56: error: no matching function for call to ‘luaGetTensor(lua_State*&, int&)’
auto tensor = detail::luaGetTensor(L, index);
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:142:5: note: in expansion of macro ‘TENSOR_TO_NDARRAY’
TENSOR_TO_NDARRAY(float, NPY_FLOAT);
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:135:56: note: candidate is:
auto tensor = detail::luaGetTensor(L, index);
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:142:5: note: in expansion of macro ‘TENSOR_TO_NDARRAY’
TENSOR_TO_NDARRAY(float, NPY_FLOAT);
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:20:31: note: template typename thpp::Tensor::Ptr fblualib::python::detail::luaGetTensor(lua_State*, int)
typename thpp::Tensor::Ptr luaGetTensor(lua_State* L, int ud) {
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:20:31: note:   template argument deduction/substitution failed:
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp: In substitution of ‘template typename thpp::Tensor::Ptr fblualib::python::detail::luaGetTensor(lua_State*, int) [with T = float]’:
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:142:5:   required from here
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:20:31: error: no type named ‘Ptr’ in ‘class thpp::Tensor’
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:135:56: error: no matching function for call to ‘luaGetTensor(lua_State*&, int&)’
auto tensor = detail::luaGetTensor(L, index);
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:143:5: note: in expansion of macro ‘TENSOR_TO_NDARRAY’
TENSOR_TO_NDARRAY(int, NPY_INT32);
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:135:56: note: candidate is:
auto tensor = detail::luaGetTensor(L, index);
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:143:5: note: in expansion of macro ‘TENSOR_TO_NDARRAY’
TENSOR_TO_NDARRAY(int, NPY_INT32);
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:20:31: note: template typename thpp::Tensor::Ptr fblualib::python::detail::luaGetTensor(lua_State*, int)
typename thpp::Tensor::Ptr luaGetTensor(lua_State* L, int ud) {
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:20:31: note:   template argument deduction/substitution failed:
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp: In substitution of ‘template typename thpp::Tensor::Ptr fblualib::python::detail::luaGetTensor(lua_State*, int) [with T = int]’:
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:143:5:   required from here
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:20:31: error: no type named ‘Ptr’ in ‘class thpp::Tensor’
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:135:56: error: no matching function for call to ‘luaGetTensor(lua_State*&, int&)’
auto tensor = detail::luaGetTensor(L, index);
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:144:5: note: in expansion of macro ‘TENSOR_TO_NDARRAY’
TENSOR_TO_NDARRAY(long, NPY_INT64);
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:135:56: note: candidate is:
auto tensor = detail::luaGetTensor(L, index);
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:144:5: note: in expansion of macro ‘TENSOR_TO_NDARRAY’
TENSOR_TO_NDARRAY(long, NPY_INT64);
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:20:31: note: template typename thpp::Tensor::Ptr fblualib::python::detail::luaGetTensor(lua_State*, int)
typename thpp::Tensor::Ptr luaGetTensor(lua_State* L, int ud) {
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:20:31: note:   template argument deduction/substitution failed:
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp: In substitution of ‘template typename thpp::Tensor::Ptr fblualib::python::detail::luaGetTensor(lua_State*, int) [with T = long int]’:
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:144:5:   required from here
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:20:31: error: no type named ‘Ptr’ in ‘class thpp::Tensor’
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:135:56: error: no matching function for call to ‘luaGetTensor(lua_State*&, int&)’
auto tensor = detail::luaGetTensor(L, index);
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:145:5: note: in expansion of macro ‘TENSOR_TO_NDARRAY’
TENSOR_TO_NDARRAY(unsigned char, NPY_UINT8);
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:135:56: note: candidate is:
auto tensor = detail::luaGetTensor(L, index);
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:145:5: note: in expansion of macro ‘TENSOR_TO_NDARRAY’
TENSOR_TO_NDARRAY(unsigned char, NPY_UINT8);
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:20:31: note: template typename thpp::Tensor::Ptr fblualib::python::detail::luaGetTensor(lua_State*, int)
typename thpp::Tensor::Ptr luaGetTensor(lua_State* L, int ud) {
^
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:20:31: note:   template argument deduction/substitution failed:
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp: In substitution of ‘template typename thpp::Tensor::Ptr fblualib::python::detail::luaGetTensor(lua_State*, int) [with T = unsigned char]’:
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:145:5:   required from here
/media/home2/other_tools/fblualib/fblualib/python/LuaToPython.cpp:20:31: error: no type named ‘Ptr’ in ‘class thpp::Tensor’
make[2]: *** [CMakeFiles/lua_module.dir/LuaToPython.cpp.o] Error 1
make[1]: *** [CMakeFiles/lua_module.dir/all] Error 2
make: *** [all] Error 2
Error: Build error: Failed building.

hi @sizhangyu i got the same error, did you fixed it?

me three

same here

find a solution, you can try to install thpp from https://github.com/facebook/thpp/blob/master/INSTALL.md

authors: fucusy junhocho sizhangyu xiao1228

repo: facebook/fblualib


text:
Flow v0.34.0 regression: Flow check never completes in project

I just found that Flow v0.34.0 doesn't appear to ever terminate on the project react-menu-list. Flow v0.33.0 works fine and runs in under 10 seconds. I can reproduce all of this in OS X and Linux.
Here's the instructions to reproduce the issue yourself:
$ git clone https://github.com/StreakYC/react-menu-list.git
$ cd react-menu-list/
$ git checkout flow34
$ npm i
$ ./node_modules/.bin/flow

Thanks for the report with the detailed repro. I think @jeffmo is looking into this, but I'll confirm tomorrow. Stay tuned and sorry for the trouble!

I've taken a quick look, and it seems to be some bad interaction with the kefir-bus npm module. I'm able to get flow 34 working in this repository with
$ cd react-menu-list
$ npm install -g flow-typed
$ flow-typed create-stub kefir-bus

And then adding the following to the ignores section:
<PROJECT_ROOT>/node_modules/kefir-bus/.*

However, it doesn't repro in isolation. I tried something like
$ mkdir foo
$ cd foo
$ npm init -y
$ flow init
$ npm install kefir-bus flow-bin
$ ./node_modules/.bin/flow check

but flow terminated.
Here's a gist of the last 3000 lines after running flow check --verbose-indent --profile for a few minutes: https://gist.github.com/gabelevi/ccbee0c3503467bbf125a5b27bb10bea
We will keep investigating. Thanks again for the report!

For those reading, here is kefir-bus/index.js.flow

And kefir/kefir.js.flow

OK, after some digging, I have a single-file repro. The issue isn't non-termination, but time complexity blowup. That is, given enough time Flow would finish, but the time required grows very quickly.
/* @flow */

class Observable {}

type Bus<T> = Observable & {
  +a: () => Bus<T>;
  +b: () => Bus<T>;
  +c: () => Bus<T>;
};

declare var bus: Bus<any>;

(bus: Bus<any>);

To reproduce, it's sufficient to have a polymorphic intersection type where one of the branches refers back to the intersection itself. It's important that the object properties be covariant for this to reproduce. Invariant properties have the effect of pinning down types earlier, which prevents the blowup.
The reason this code exhibits this behavior now and not in earlier versions is because we changed the interpretation of "method syntax" properties in object types to be covariant. You can work around the issue by making those properties invariant.
I am still working on a real fix, because we shouldn't exhibit this behavior even with covariant properties, but wanted to report back with the repro and workaround in the mean time.

The commit referencing this says it only partially fixed the issue, so should this be re-opened?

Still experiencing this on v0.35.0

I'm afraid the fix just missed the v0.35.0 branch cut. It will be in 0.36.0, which should be deployed this week.

authors: AgentME gabelevi hwfwalton samwgoldman

repo: facebook/flow


text:
Extending classes with proxied constructor causes false positive

Let's start from example:
class Foo {
  constructor() {
    return new Proxy(this, {});
  }
}
class Bar extends Foo {}

const bar1: Foo = new Bar();
const bar2: Bar = new Bar();

which seems to be 100% correct from JS point of view, see http://runkit.com/akusmierz/github-facebook-flow-5037.
But for some reason, Flow thinks the Bar instance is only inherited from Foo...
https://flow.org/try/#0MYGwhgzhAEBiD29oG8BQ1rHgOwgFwCcBXYPeAgCgEoV0NoCBTPIg7abRgd2gAUD4ADwCeFPAAsAlhAA0KAL5UA3HXmo1oSDABCYAtEaC8jbABMYCJMjWosuPNABGegIwAuOImgBeDt2i6lMq2OPhOegBMHoE+fjyB1EpAA

We now decide that non-void return of class constructors won't be supported


text:
Missing type annotation for T even when return type is specified

I want to define a wrapper function which takes a generic input T and wraps it in an object. All return types are defined and it also works, if the returned structure is simply T. But returning a new object which contains T does not work. I wouldn't know where to add another return type?
Is it possible to get the following to typecheck while using a generic wrapper function?
/* @flow */

declare function id<T>(fn: T): T;
declare function wrap<T>(fn: T): {fn: T};

export const a = id(3); // works
export const b = wrap(3); // does not work

https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVATApgYxgQwCcswoBXAOxwBcBLOCsWjAHgBUA+ACigoC4wbAJQC2Abky4CxUpRr1GCQvgAO7br1EiwAb02CAvhNRYAHiriFqYHAwDO1-GAC8TDFwDMQsWGDAwCJYA1nYm5pbWthQOYABGLgHKKp7evv4YcFh2YBRw1oGEQUA

By the way, it works without the export in front of the const for whatever reason. Being explicit happens to work too, as in
export const b = wrap<number>(3);

My general understanding is that flow's type inference at module borders is minimalistic to reduce overall performance overhead. That's why it works without the export token or with explicit typing the exported variable.
I know this limitation exists for cases, such as functions, for which return types have to be annotated explicitly. Apparently, it's also the case when exporting variables which are the return value of type-parameterized functions. So, maybe this is not an issue in the end.

The issue here is that wrap uses T in an invariant position. If you mark fn as covariant with + the issue goes away.

My general understanding is that flow's type inference at module borders is minimalistic to reduce overall performance overhead. That's why it works without the export token or with explicit typing the exported variable.

Yep! That's right. Right now we ask for annotations on any types used in invariant or contravariant positions that are reachable through exports. id only used T is a covariant position, which is why we did not complain.

Awesome, that's exactly the kind of information I was looking for. If the flow error contained that hint, it would be even better, of course.
Thank you, @jbrown215!

@philippotto I've done some work recently to try to improve this error message a bit. Do you have recommendations for phrasing the covariance in a concise and clear way? I didn't explain why the annotation was required because I find that variance is usually a subject that most people don't ever really learn. Also, these annotations can be super deep down in the structure of the type, so working out exactly how they are invariant or contravariant is also not always clear just by a loose inspection.
If you have recommendations for rephrasing I'll definitely put up a diff to run it by the team.

@philippotto I've done some work recently to try to improve this error message a bit. Do you have recommendations for phrasing the covariance in a concise and clear way? I didn't explain why the annotation was required because I find that variance is usually a subject that most people don't ever really learn. Also, these annotations can be super deep down in the structure of the type, so working out exactly how they are invariant or contravariant is also not always clear just by a loose inspection.

I think the most important part is that the error message differs from the usual Missing type annotation for T message which, for example, appears if you export a function without a return type annotation. That's why searching for the above error message yields a lot of unhelpful discussions right now (at least for the case in this issue).
Also, I'd definitely include the information about covariance, since this is at least googleable.
Maybe something like this?
"Missing type annotation for T. Make sure to annotate any types used in invariant or contravariant positions that are reachable through exports. Alternatively, consider marking annotations as covariant when possible."


text:
Object.assign does not work as expected in classes

Flow version: 0.97.0
Expected behavior
The following code:
class Test {
  constructor( param1, param2 ) {
    Object.assign( this, { param1, param2 })
  }
}

let T = new Test( 'A', 'B' )

console.log( 'Params:', T.param1, T.param2 )

should pass.
Actual behavior
Flow produces 4 errors saying properties param1 and param2 are missing in Test.
Well, they were indeed missing, until I explicitly assigned them... :)

https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVBjGBDAzrsAFQFNcAXMAb1TDAzgDtyAnAVwzLmYAowAHbM2wBbAIwAafoJEAmMAEoqNWmADyAIwBWxDgDo8uAJYBzBrzIALQ7kmUpQsZIEO5AX3nLXqL6hjEKhGAAvGAMxEgk5LwA5ACC0ZLRAELRCuj0THB+uvDGMQAK0sK4AFwJRLrOIhIVVcJy8kA

https://flow.org/try/#0PTAEAEDMBsHsHcBQiDG0CGBnToAqBTTAF1AG9FRQAHdAJ3QFsBGALlGNoEsA7AcwG4K1OowBMbDjwFCUsbhwCuKIrFoAKGvWYAaYVtEBKMkMpEAFp0wA6TYyagAvHrv9QIUJB74Toc5ZsiDKKOzkGu7p7c3pSUAPIARgBW+MpWWJicvNxqfpi6pKFMurZBoAC+BuFg6NCYsB5eQmWIzYjQ+CS4IVHweIREagBEAIKDuoMAQoOVyLLysO1WcLxDAAqBmCxjeAFaRTslhoJAA

Ok, I see. I've gotten used to Flow automatically detecting types using class property syntax, so I wasn't thinking about the need to define fields before the constructor in this case. Thanks for clearing that up.

@wchargin any chance we could reduce some boilerplate by inferring types in the following code
export class Test {
  x: number
  y: number
  z: number

  constructor(
    x: number,
    y: number,
    z: number
  ) {
    Object.assign( this, { x, y, z })
  }

so that it can be shortened to this
export class Test {
  x: number
  y: number
  z: number

  constructor( x, y, z ) {
    Object.assign( this, { x, y, z })
  }

since it would only make sense that objects with those keys being assigned to this would have to be numbers?

Dchhfjfchift

@soulofmischief: Flow does infer such types:
// @flow
class C {
  x: number;
  y: number;
  constructor(x, y) {
    this.x = x; // fine
    Object.assign(this, { y }); // also fine
  }
}

But the class in your example is exported, which means that its
constructor is also exported, and exported symbols must always be
explicitly typed. This is valuable for documentation purposes: I don’t
want to have to read the implementation of your constructor and
cross-reference it against the field definitions—maybe in superclasses,
maybe in other modules!—just to figure out what the parameter types are
supposed to be. It also makes typechecking significantly more efficient,
because each module can be typechecked independently.

(Independent of types or Flow, I’d hesitate to use Object.assign to
initialize fields at all. If I want to see where this.x is assigned
(which is something that I frequently want), I start by grepping for
“.x = ”; using “tricks” to save a few keystrokes now hampers your
readability and searchability later.)

authors: Tuti1808 soulofmischief wchargin


text:
Add React.StrictMode

Rebase of #6078

Thanks for the PR! We've since added this as part of the change that added the react hooks API libdefs.


text:
Async setupFiles

🚀 Feature Proposal

setupFiles should support module.exports = async () => {/* async setup here */} kind of functionality.
Motivation

Async setupFiles would enable setting up new database for each test file and store the database name to config.js file.
Example
const config = require('../config');
module.exports = async () => {
  const randomDatabaseName = randomName();
  await createDatabase(randomDatabaseName);
  config.DATABASE_NAME = randomDatabaseName
};

config.DATABASE_NAME is then used in the actual tests to establish the actual connection.
Pitch
Why does this feature belong in the Jest core platform?
There is currently no way to achieve this behaviour with synchronous setupFiles nor with custom env, but this would make working with parallel tests using database much easier.
I think this would be the second best option after this: https://github.com/facebook/jest/issues/11039

If you use ESM you can use top level await. So if you name your setup file something.mjs and enable ESM mode.
Not to say we shouldn't support exported functions from setup files, but I think it's cleaner with TLA. Thoughts?

If you use ESM you can use top level await. So if you name your setup file something.mjs and enable ESM mode.
Not to say we shouldn't support exported functions from setup files, but I think it's cleaner with TLA. Thoughts?

ESM & TLA sounds like a decent option, didn't think about that :+1: Does Jest wait for it to finish before continuing?

ESM & TLA sounds like a decent option, didn't think about that :+1: Does Jest wait for it to finish before continuing?

Yes, all ESM module resolution and loading is async and Jest awaits it.
Specifically: https://github.com/facebook/jest/blob/e651a21653b481731b8566ca843501bdc7ad1b75/packages/jest-repl/src/cli/runtime-cli.ts#L106-L114

Yes, all ESM module resolution and loading is async and Jest awaits it.
Specifically: https://github.com/facebook/jest/blob/e651a21653b481731b8566ca843501bdc7ad1b75/packages/jest-repl/src/cli/runtime-cli.ts#L106-L114

It seems that .mjs would be quite hacky solution and it does not have all the necessary variables like __dirname available :/ This could turn out to be usable in future, but right now it's not quite there yet. Also current version of ESlint doesn't seem to like top level awaits yet. So I'd say it's still way too early for ESM.

It seems that .mjs would be quite hacky solution and it does not have all the necessary variables like __dirname available :/ This could turn out to be usable in future, but right now it's not quite there yet. Also current version of ESlint doesn't seem to like top level awaits yet. So I'd say it's still way too early for ESM.

I would want to second the feature proposal. In my view it is quite common that you have async operations for setting up your tests. Those could be as already mentioned DB connection handling or reading credentials from an external secret store, ...

This sounds exactly what I need and cannot currently find an alternative solution.
I am testing a lambda function that sets up a database connection on load, e.g.
// src/handlers/graphql.ts
const loadingConnection = setupDatabase();

export const handler = async (
  event: APIGatewayProxyEvent,
  context: Context,
  callback: Callback
): Promise<APIGatewayProxyResult> => {
  const connection = await loadingConnection;
  ...

Then because my test is importing the file, e.g.
// src/handlers/graphql.spec.ts
import { handler } from './graphql';

describe('handler', () => {
  it('handles graphql queries', async () => {

If I had the database connection set up in the handler, I am able to create the database in a setupFilesAfterEnv file, e.g.
// src/test/setupFilesAfterEnv/database.setup.ts
beforeAll(async () => {
  const dbname = ['graphql', process.env.NODE_ENV, process.env.JEST_WORKER_ID].filter(Boolean).join('-');
  const connectionOptions = await getConnectionOptions();
  await createDatabase({}, {...connectionOptions, dbname});
});

However this doesn't work as the beforeAll runs after the handler file is imported, e.g.
src/test/setupFilesAfterEnv/database.setup.ts root code run
src/handlers/graphql.ts root code run
src/handlers/graphql.spec.ts root code run
src/test/setupFilesAfterEnv/database.setup.ts beforeAll run
src/handlers/graphql.spec.ts it run
src/handlers/graphql.ts handler run

If anyone has any suggestions, even hacky temporary ones it would be much appreciated!

Trivial to support calling a function exported from the module if it exists and await the result, so I'll happily merge a PR doing so 🙂

@owenbendavies Not sure this is your problem or if you found a solution but my beforeAll wouldn't wait and the tests would start. Adding a jest timeout fixed this.
beforeAll(async () => {
  // This timeout need to be here otherwise jest moves on after a few seconds and does not
  // await the TestServer with no warning.
  jest.setTimeout(20000);
  await new TestServer();
});

@clintonmedbery thank you for the suggestion, unfortunately it's an order issue rather than a time issue so this doesn't help.

https://github.com/facebook/jest/releases/tag/v28.0.0-alpha.6

authors: SimenB clintonmedbery kbrueckner owenbendavies villesau

repo: facebook/jest


text:
collectCoverageFrom doesn't match glob

🐛 Bug Report
Collect coverage from config or CLI doesn't work properly.
To Reproduce

Have a repository with ts, and stories.ts files on the same folder.
Run yarn jest --coverage --collectCoverageFrom='src/**/!(*.stories).{ts,tsx}' --watchAll
(Or yarn test...)
See ts and tsx files covered, as expected.
Wrongly see .stories files covered, even though the glob excluding it is correct.

I have also tried running simply yarn jest with this config (also fails):
module.exports = [
    collectCoverageFrom: ['src/**/!(*.stories).{ts,tsx}'],
]

Expected behavior
According to the glob src/**/!(*.stories).{ts,tsx} the coverage files should include only files:

inside src
ending in ts or tsx
without .stories

Link to repl or repo (highly encouraged)
The repo I'm using right now.
envinfo
  System:
    OS: Linux 5.11 Pop!_OS 20.04 LTS
    CPU: (8) x64 Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz
  Binaries:
    Node: 14.15.3 - /usr/local/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 6.14.9 - /usr/local/bin/npm
  npmPackages:
    jest: ^26.6.3 => 26.6.3

I cloned your repo and run yarn jest --coverage, I got the coverage report
-------------------------------------------------------------------|---------|----------|---------|---------|-------------------
File                                                               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-------------------------------------------------------------------|---------|----------|---------|---------|-------------------
All files                                                          |     100 |      100 |     100 |     100 |
 @types                                                            |       0 |        0 |       0 |       0 |
  index.d.ts                                                       |       0 |        0 |       0 |       0 |
 @types/generated                                                  |       0 |        0 |       0 |       0 |
  contentful.d.ts                                                  |       0 |        0 |       0 |       0 |
 components/atoms/Back                                             |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
  styles.ts                                                        |     100 |      100 |     100 |     100 |
 components/atoms/BottomBar                                        |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
  styles.ts                                                        |     100 |      100 |     100 |     100 |
 components/atoms/BottomBar/HomeButton                             |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
  styles.ts                                                        |     100 |      100 |     100 |     100 |
 components/atoms/BottomBar/LocaleSwitcher                         |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
  styles.ts                                                        |     100 |      100 |     100 |     100 |
 components/atoms/Button                                           |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
  styles.ts                                                        |     100 |      100 |     100 |     100 |
 components/atoms/Embed                                            |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
 components/atoms/Footer                                           |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
  styles.ts                                                        |     100 |      100 |     100 |     100 |
 components/atoms/Header                                           |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
  styles.ts                                                        |     100 |      100 |     100 |     100 |
 components/atoms/InlineEmbed                                      |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
 components/atoms/Input                                            |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
  styles.ts                                                        |     100 |      100 |     100 |     100 |
 components/atoms/Loading                                          |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
  styles.ts                                                        |     100 |      100 |     100 |     100 |
 components/atoms/NewHead                                          |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
 components/atoms/Project                                          |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
  styles.ts                                                        |     100 |      100 |     100 |     100 |
 components/atoms/Typography                                       |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
 components/atoms/Video                                            |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
  styles.ts                                                        |     100 |      100 |     100 |     100 |
 components/sections/home                                          |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
  styles.ts                                                        |     100 |      100 |     100 |     100 |
 components/sections/page                                          |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
  styles.ts                                                        |     100 |      100 |     100 |     100 |
 components/sections/page/projects                                 |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
  styles.ts                                                        |     100 |      100 |     100 |     100 |
 components/sections/page/text                                     |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
  styles.ts                                                        |     100 |      100 |     100 |     100 |
 components/utils/documentToReactComponentsOptions                 |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
 components/utils/documentToReactComponentsOptions/handleEmbedded  |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
  styles.ts                                                        |     100 |      100 |     100 |     100 |
 components/utils/documentToReactComponentsOptions/handleParagraph |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
 components/utils/makeSafeDate                                     |     100 |      100 |     100 |     100 |
  index.ts                                                         |     100 |      100 |     100 |     100 |
 functions                                                         |     100 |      100 |     100 |     100 |
  fetchContentful.ts                                               |     100 |      100 |     100 |     100 |
 i18n                                                              |     100 |      100 |     100 |     100 |
  en.ts                                                            |     100 |      100 |     100 |     100 |
  i18n.ts                                                          |     100 |      100 |     100 |     100 |
  pt.ts                                                            |     100 |      100 |     100 |     100 |
 pages                                                             |     100 |      100 |     100 |     100 |
  404.tsx                                                          |     100 |      100 |     100 |     100 |
  [slug].tsx                                                       |     100 |      100 |     100 |     100 |
  _app.tsx                                                         |     100 |      100 |     100 |     100 |
  index.tsx                                                        |     100 |      100 |     100 |     100 |
 pages/[slug]                                                      |     100 |      100 |     100 |     100 |
  about.tsx                                                        |     100 |      100 |     100 |     100 |
 pages/projects                                                    |     100 |      100 |     100 |     100 |
  [slug].tsx                                                       |     100 |      100 |     100 |     100 |
 styles                                                            |     100 |      100 |     100 |     100 |
  GlobalStyle.ts                                                   |     100 |      100 |     100 |     100 |
  styled.d.ts                                                      |       0 |        0 |       0 |       0 |
  theme.ts                                                         |     100 |      100 |     100 |     100 |
 test                                                              |     100 |      100 |     100 |     100 |
  test-helper.tsx                                                  |     100 |      100 |     100 |     100 |
-------------------------------------------------------------------|---------|----------|---------|---------|-------------------

and I don't see any files with .stories

Whoa @ahnpnl this is weird. I'm on linux and it doesn't work.

maybe run with --no-cache

Same bug. Globbing is missing whole folders. This would be super rad if this bug was fixed.

authors: ahnpnl angelod1as fsblemos stoplion


text:
Jest doesn't works with JSX which imports CSS

Do you want to request a feature or report a bug?
Bug
What is the current behavior?
If app.jsx have import './app.css'; it's impossible to run test, I got this error:
yarn run:test v0.21.3
$ NODE_ENV=client jest -u
 FAIL  src/__tests__/app.test.js
  ● Test suite failed to run

    /home/svipben/Documents/react-boilerplate/src/client/app/app.css:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){body {
                                                                                ^
    SyntaxError: Unexpected token {

      at transformAndBuildScript (node_modules/jest-runtime/build/transform.js:320:12)
      at Object.<anonymous> (src/client/app/app.jsx:7:1)
      at Object.<anonymous> (src/__tests__/app.test.js:2:12)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        0.693s
Ran all test suites.
error Command failed with exit code 1.

What is the expected behavior?
To run tests without error...
Please provide your exact Jest configuration and mention your Jest, node, yarn/npm version and operating system.
OS: Linux Ubuntu 16.04
Jest: Latest
Yarn: Latest
Node: Latest
babel-jest: Latest
.babelrc:
        "client": {
            "presets": [
                "latest", // All you need to compile what's in ES2015+
                "flow", // Flow support
                "react", // Strip flow types and transform JSX
                "stage-2" // Experimental syntax extensions
            ],
            "sourceMaps": true // Compile with Source Maps
        },

jest: NODE_ENV=client jest -u
P.S. Everything runs well if I comment/remove import './app.css';

@svipben https://facebook.github.io/jest/docs/webpack.html#mocking-css-modules

@maximderbin Thanks!

@maximderbin Thank you! It resolves my issue by adding moduleNameMapper

@svipben @maximderbin @simonxl where do I have to add this moduleNameMapper?
I see in the doc that we shall add it in the packag.json but which one?
tnx

@sarahmarciano moduleNameMapper is a part of your configuration. By default, you can set the config in package.json (the one which features jest in dependencies) under "jest" key, like this:
{
  "dependencies": {...}
  "jest": {
    "moduleNameMapper": {...}
  }
}

I solved this by using the moduleNameMapper key in the jest configurations in the package.json file
{
   "jest":{
        "moduleNameMapper":{
             "\\.(css|less|sass|scss)$": "<rootDir>/__mocks__/styleMock.js",
             "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js"
        }
   }
}

After this you will need to create the two files as described below

mocks/styleMock.js

module.exports = {};

mocks/fileMock.js

module.exports = 'test-file-stub';

If you are using CSS Modules then it's better to mock a proxy to enable className lookups.
hence your configurations will change to:
{
  "jest":{
     "moduleNameMapper": {
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
      "\\.(css|less|scss|sass)$": "identity-obj-proxy"
    },
  }
}

But you will need to install identity-obj-proxy package as a dev dependancy i.e.
yarn add identity-obj-proxy -D

For more information. You can refer to the jest docs

@dennisja - so I'm not using CSS Modules, so I tried setting up the moduleNameMapper config. However, it appears that when I run jest via npm test, my config is completely ignored. I still run into the same Unexpected token { error.
Would you happen to see anything that pops out as an error within my package.json file?
{
  "name": "react-project",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "axios": "^0.18.0",
    "bootstrap": "^4.0.0",
    "react": "^16.2.0",
    "react-dom": "^16.2.0",
    "react-redux": "^5.0.6",
    "react-router-dom": "^4.2.2",
    "react-scripts": "1.1.1",
    "react-spinkit": "^3.0.0",
    "redux": "^3.7.2",
    "redux-thunk": "^2.2.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "jest",
    "test:watch": "react-scripts test -- --watch",
    "eject": "react-scripts eject"
  },
  "devDependencies": {
    "babel-jest": "20.x",
    "babel-preset-env": "^1.6.1",
    "babel-preset-react": "^6.24.1",
    "jest": "20.x"
  },
  "jest": {
    "moduleNameMapper": {
      "\\.(css|less|sass|scss)$": "<rootDir>/__mocks__/styleMock.js",
      "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js"
    }
  }
}

I have my mocks directory located at, /react-project/mocks in case I perhaps have that setup in error.

Note that the approaches recommended here will not work if your CSS modules export values which your JSX files depend on. Most guides assume you're only using CSS modules to export class names. I wish there was a guide for properly mocking CSS modules.

@matthew-dean what do you mean "properly mocking CSS modules"? Can you describe your use case a bit more? I have great experience using identity-obj-proxy

:export {
  sizeMobile: $size-mobile / 1px;
  sizePhablet: $size-phablet / 1px;
  sizeSmallTablet: $size-small-tablet / 1px;
  sizeTablet: $size-tablet / 1px;
  sizeDesktop: $size-desktop / 1px;
  sizeLargeDesktop: $size-large-desktop / 1px;
}

import styles from './variables.scss'

const tileSize = parseFloat(styles.sizeTablet) / 3
//...
render() {
  return <Tile style={{width: tileSize}} />
}

This is a contrived example, just demonstrating that you can share constants (values) between CSS modules and JS, and that conditional rendering or dynamic props can be assigned based on values.
But with identity-obj-proxy, these values can't be cast to integers, let alone the actual values that are present. So if you have JSX code that relies on constants defined in your CSS modules, then you can't test this without properly mocking the CSS module (having an object returned that has the values as testable integers).  identity-obj-proxy only assumes that your CSS modules contain an object with nothing more than scoped CSS classnames; it does not support the other aspect of CSS modules which is the ability to export values / constants that in turn get used in JS operations.

@SimenB
Incidentally, I WAS able to mock the CSS module successfully like this:
const styles = require('styles/variables.scss')

jest.mock('styles/variables.scss', () => {
  return {
    sizePhablet: 500,
    sizeSmallTablet: 768,
    sizeTablet: 1024,
    sizeDesktop: 1440,
    sizeLargeDesktop: 1920
  }
})

Hopefully that's useful for someone else who is using all the features of CSS modules and, like me, was tearing their hair out at all the default "just use identity-obj-proxy" advice.

I solved this problem by using 'jest-transform-css'.
After installing, added the below in the jest config.
"transform": {
      "^.+\\.js$": "babel-jest",
      ".+\\.(css|styl|less|sass|scss)$": "jest-transform-css"
    }

Now css files are transpiled just like js files did.

I'm using an external package and it imports its own files to a single file by using the following:
@import "progress-tracker/progress-tracker-variables.scss";
Whenever I run the Jest for to start testing

the error above shows up. I already have specified css mockup inside the package.json

Im looking forward to get some help about that issue. Any tricks, suggestions?

I'm using Babel 7, babel-jest ^24.5.0, Jest ^24.1.0.
After following the above advice, I'm still getting this error when I try to import a function or object into a Jest test file (e.g. Post.test.js) when the target file (e.g. Post.js) imports a CSS file - e.g. ./postStyles.css.
Jest encountered an unexpected token

SyntaxError: Unexpected token .

Details:

    /Users/ben/Desktop/Work/code/bengrunfeld/src/front-end/components/Post/postStyles.css:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){.post h1, .post h2, .post h3 {

      3 |
      4 | import { PostText } from './styles'
    > 5 | import './postStyles.css'

As per the article linked above, this is in my package.json:
"jest": {
    "moduleFileExtensions": ["js", "jsx"],
    "moduleDirectories": ["node_modules", "bower_components", "shared"],

    "moduleNameMapper": {
      "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js",
      "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js",

      "^react(.*)$": "<rootDir>/vendor/react-master$1",
      "^config$": "<rootDir>/configs/app-config.js"
    }
  },

and in the root directory, I have __mocks__/styleMock.js which has the following code:
module.exports = {};

Lastly, my jest.config.js:
module.exports = {
  setupFiles: ['<rootDir>/src/test/setup.js']
}

Which in turn configures Enzyme:
import Enzyme from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'

Enzyme.configure({ adapter: new Adapter() })

I am struggling to solve almost same issue where my scss file contain @import statements. Test fails telling SyntaxError: Invalid or unexpected token

I was able to resolve this by adding @babel/polyfill as a dev dependency

same here @fthomas82

I solved this by using the moduleNameMapper key in the jest configurations in the package.json file
{
   "jest":{
        "moduleNameMapper":{
             "\\.(css|less|sass|scss)$": "<rootDir>/__mocks__/styleMock.js",
             "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js"
        }
   }
}

After this you will need to create the two files as described below

__mocks__/styleMock.js

module.exports = {};

__mocks__/fileMock.js

module.exports = 'test-file-stub';

If you are using CSS Modules then it's better to mock a proxy to enable className lookups.
hence your configurations will change to:
{
  "jest":{
     "moduleNameMapper": {
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
      "\\.(css|less|scss|sass)$": "identity-obj-proxy"
    },
  }
}

But you will need to install identity-obj-proxy package as a dev dependancy i.e.
yarn add identity-obj-proxy -D

For more information. You can refer to the jest docs

It worked for me. Thanks!!!

I solved this problem by using 'jest-transform-css'.
After installing, added the below in the jest config.
"transform": {
      "^.+\\.js$": "babel-jest",
      ".+\\.(css|styl|less|sass|scss)$": "jest-transform-css"
    }

Now css files will get transpiled just like js files did.

Thanks, bro @krajasekhar
It works for me 👍

I added suggested config to packages.json, without success, then I realized I had a jest.config.js in my project root directory, Jest uses that config file over packages.json.
For reference here is my jest.config.js file:
module.exports = {
  setupFilesAfterEnv: ['<rootDir>/.setup-tests.js'],
  testPathIgnorePatterns: ['<rootDir>/.next/', '<rootDir>/node_modules/'],
  transform: {
    '^.+\\.js$': 'babel-jest',
    '.+\\.(css|styl|less|sass|scss)$': 'jest-transform-css',
  },
};

I have to import a raw css in my code
import "./cloud.css?raw"
I also modified jest config
  "jest":{      "moduleNameMapper": {       "\\.(css|less|scss|sass|css?raw)$": "identity-obj-proxy"     },
still, I am getting test error on the import line. Any idea how to mock raw import?

If somebody arrives here:
This module is the most updated I have seen: https://www.npmjs.com/package/jest-css-modules-transform
transform: {
    '^.+\\.(js|jsx|ts|tsx)$': '<rootDir>/node_modules/babel-jest',
    ".+\\.(css|styl|less|sass|scss)$": "jest-css-modules-transform"
  },
  transformIgnorePatterns: [
    '/node_modules/',
    '^.+\\.module\\.(css|sass|scss)$',
  ],
  moduleNameMapper: {
    '^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy'
  },

I added suggested config to packages.json, without success, then I realized I had a jest.config.js in my project root directory, Jest uses that config file over packages.json.
For reference here is my jest.config.js file:
module.exports = {
  setupFilesAfterEnv: ['<rootDir>/.setup-tests.js'],
  testPathIgnorePatterns: ['<rootDir>/.next/', '<rootDir>/node_modules/'],
  transform: {
    '^.+\\.js$': 'babel-jest',
    '.+\\.(css|styl|less|sass|scss)$': 'jest-transform-css',
  },
};

Thanks to everybody and specially to you brother! It was a kind of logic thing but I was missing that ...

it worked for me when I add the moduleNameMapper in the jest.config.ts, not the package.json

If you are using Jest for images snapshots there is not much choice to parse SCSS into CSS and inject it in the tests. I tried "sass-jest" and "sass-jest-transform" and they didn't work. I'm wondering if I will have to write my own?

Hey! I'm still having this error after trying all the options. If I remove the "?type=global" it works, but then I run out of styles...

My jest.config.js:
`module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom', // https://jestjs.io/docs/en/configuration#testenvironment-string
roots: [''],
testPathIgnorePatterns: ['/\\[/\\]'],
transformIgnorePatterns: ['[/\\]node_modules[/\\].+\.(ts|tsx)$'],
automock: false,
restoreMocks: true,
// Runs special logic, such as cleaning up components
// when using React Testing Library and adds special
// extended assertions to Jest
setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'],
// Module file extensions for importing
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node', 'css'],
// tsconfig.json paths aliases
moduleNameMapper: {
'^@maria/api(.)$': '/main/core/api/$1',
'^@maria/bifrost(.)$': '/main/core/bifrost/$1',
'^@maria/request(.)$': '/main/core/request/$1',
'^@maria/metrics(.)$': '/main/core/metrics/$1',
'^@maria/utils(.)?': '/main/core/utils',
'^@maria/models(.)$': '/main/app/models/$1',
'^@maria/components(.)$': '/main/app/components/$1',
'^@maria/hooks(.)$': '/main/app/hooks/$1',
'^@maria/hocs(.)$': '/main/app/hocs/$1',
'^@maria/layout(.)$': '/main/app/layout/$1',
'^@maria/providers(.)$': '/main/app/providers/$1',
'^@maria/assets(.)$': '/main/app/assets/$1',
'^@maria/selectors(.)$': '/main/app/selectors/$1',
'^@maria/screens(.)$': '/main/app/screens/$1',
'^@maria/containers(.)$': '/main/app/containers/$1',
'^@maria/validators(.)$': '/main/app/validators/$1',
'^@maria/server(.)$': '/server/$1',
'^@maria/test(.)$': 'main/app/test/$1',
'\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'/mocks/fileMock.js',
'\.(css|less|sass|scss|css?type=global)$': '/mocks/styleMock.js',
},
// Jest transformations -- this adds support for TypeScript and styled-jsx
transform: {
'^.+\.(ts|tsx)?$': 'babel-jest',
'.+\.css$': 'jest-styled-jsx-transformer',
},
}
`

I move my config from  jest.config.js to my package.json and worked

I came across this issue when importing CSS files from node_modules:
import "react-grid-layout/css/styles.css";
import "react-resizable/css/styles.css";

This was my configuration:
transform: {
  "^.+\\.(css|scss)$": here("./jest/transforms/css-transform"),
};

While it works fine with local CSS files, It didn't for the imports above. The reason is that transformIgnorePatterns includes node_modules by default, hence the CSS transform will be skipped for those files. This change was necessary:
transformIgnorePatterns: [
  "[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs|cjs|ts|tsx)$",
],

authors: CeamKrier FJKhan Mano534 ShadOoW SimenB bengrunfeld danielrsantana darekkay dennisja fthomas82 idindrakusuma joseigor krajasekhar luiznasciment0 matthew-dean maximderbin neginqantas olignyf rafinskipg rogeliosamuel621 sarahmarciano simonxl smokinjoe svipas svipben thymikee yanlee26


text:
UncaughtException in a promise does not fail tests.

Do you want to request a feature or report a bug?
Bug
What is the current behavior?
Jest doesn't report an uncaughtException when it happens in a promise.
       const EventEmitter = require('events');

        // Succeed
        it('should fail promise', () => {
            const connection = new EventEmitter();

            const fn = jest.fn(() => {
                connection.emit('error', new Error());
                return Promise.reject(new Error());
            });

            return Promise.resolve().then(fn).catch(() => {});
        });

        // Fails
        it('should fail standard', () => {
            const connection = new EventEmitter();
            connection.emit('error', new Error());
        });

What is the expected behavior?
Both tests should fail.

Promise.resolve does not execute functions passed to it. Try Promise.resolve().then(() => connection.emit('error', new Error())).

Sorry my reduction of the test case was not enough:
        const EventEmitter = require('events');

        // Succeed
        it('should fail promise', () => {
            const connection = new EventEmitter();

            const fn = jest.fn(() => {
                connection.emit('error', new Error());
                return Promise.reject(new Error());
            });

            return Promise.resolve().then(fn).catch(() => {});
        });

        // Fails
        it('should fail standard', () => {
            const connection = new EventEmitter();
            connection.emit('error', new Error());
        });

Why did you closed both issues? The second test case provided shows the bug.
I have non testable code because some dependencies throw an error event AND a promise rejection.

How do you expect the promise to throw, if you catch it?

The issue is that an event emitter emitting an error event throws an uncaughtException at process level if there is no listener for the 'error' event. You can't catch it in your function.
In the first test, it should fail because there is an uncaught exception. It seems the promise rejecting cancel the output for jest, I don't know why but it makes code that uses amqplib untestable.

For reference, here is the Node documentation referring to why the test should fails:
https://nodejs.org/api/events.html#events_error_events

Can we reopen the issue please ? It a serious issue to get a false positive on a test.

Same problem. I haven't found a solution yet.

I think it works if you return the dispatch:
it('should fail when promise fail', () => {
        const store = mockStore(initialState);

        return store.dispatch(fetchSomething).then(() => {
            expect(store.getActions()).toEqual(expectedActions);
            expect(store.getState()).toEqual(expectedState);
        });
    });

authors: Naouak Xalio08 cpojer oliviertassinari thymikee


text:
Feature request: add option to skip nonmatching properties when snapshot does not match

I often test object from the database-like:
{
    "campaign_banner_id": null,
    "campaign_email_id": null,
    "campaign_id": 1,
    "is_last_message": null,
    "notification_id": null,
    "notification_processed_id": null,
    "type": "join",
    "user_id": 1,
    "timestamp": "2018-04-01T14:45:54.555Z"
  }

they are usually bigger and not just flat and small like this, but this will suffice as example.
Now when I have a snapshot assertion it will fail because the timestamp prop is different each time the test is run. This is in some cases solvable by mocking out time, but often I am doing an integration test where the time would have to be mocked on my system level. I am not aware of any reliable way to mock a time on system level-changing it won't help because test execution takes some time and this time is always different.
So my only option currently is to use something like
import omitDeep from 'omit-deep-lodash'
expect(omitDeep(myObject, ['timestamp'])).toMatchSnapshot()

this works, but it makes it a little tedious to write these assertions. Couldn't we store this information into the snapshots themselves? Like a list of paths in the snapshots that should be skipped when comparing?
Ideally jest should be able to write this upon a snapshot failuire where currently I can press u to update so I would press s or p to skip failed properties.
It should also work for properties which are deeper than on the root of the compared object.

IMO this functionality is covered by #5847

authors: SimenB capaj


text:
add versioned documentation to the website

Summary
Hi 👋
This PR adds versioned documentation to the website using Docusaurus' built-in support for it (https://docusaurus.io/docs/en/versioning.html). Current docs on the website are master only which may cause confusion about what's available at that time (see #5190).
I adjusted pages/en/versions.js to have correct links to latest/master/past versions along with brief descriptions for each of them.
I also added a link to the release notes of the latest version pointing to CHANGELOG.md, and a link to the source code for the latest (master) version. I looked at a few other projects that use this feature and how they customized that page, e.g. https://facebook.github.io/relay/en/versions.html.
Notes

When a new version is published we should also run yarn run version x.x.x inside the website's folder to generate docs for that version. I couldn't figure out if this is automated or manual. Should I document it somewhere? Possibly add it to a publish script?
I created documentation for the latest version (v22.2.2), do we plan on going back to past versions and creating docs for them?
Normally the website will show docs for the latest stable version. Docs for master or earlier versions can be accessed from the versions page.
This is a fairly large PR (in terms of lines of code) but only files in the docs folder and sidebar files that differ from those of the latest version will get copied each time a new version is specified (see https://docusaurus.io/docs/en/versioning.html#fallback-functionality).

Test plan
No changes at all

@thymikee thanks for the review 🙂
Here's a screenshot of how the new versions page looks, it can be accessed by clicking on the version next to the Jest logo (top left corner). Other than that and the version at the top it looks exactly the same.

I agree that separating the documentation to its own repo should probably happen sooner or later.
We can also consider only having a small number of documented versions of Jest on the website, similar to Relay (https://facebook.github.io/relay/en/versions.html).  They have docs only for master/latest/classic. Other projects (like https://github.com/facebook/react-native-website) already have their docs in its own repo.

Codecov Report

Merging #5541 into master will not change coverage.
The diff coverage is n/a.

@@           Coverage Diff           @@
##           master    #5541   +/-   ##
=======================================
  Coverage   61.71%   61.71%
=======================================
  Files         213      213
  Lines        7149     7149
  Branches        4        4
=======================================
  Hits         4412     4412
  Misses       2736     2736
  Partials        1        1

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 133a9a1...6036226. Read the comment docs.

@thymikee is this GTG?

Looks good. Next step would be to automate it while cutting a release

Is there any way we can choose not to have a full copy of all docs on the main branch of Jest? Like, is there any way to keep it only in gh-pages or a docs branch?

Is there any way we can choose not to have a full copy of all docs on the main branch of Jest? Like, is there any way to keep it only in gh-pages or a docs branch?

@ericnakagawa can you shed some light on that?

I'll merge it an hope it will make people happy. Thanks so much for working on this! As said, ideally we can move all the copies of old versions in a different branch.

@cpojer closed instead of merged?

Oh yeah, oops!

authors: SimenB codecov-io cpojer ronami thymikee


text:
Navbar header fixes

This is in response to a minor tweak required as mentioned in #7265

Adjusted font sizes a bit
Removed underline from the Jest-version header.

Codecov Report

Merging #7576 into master will not change coverage.
The diff coverage is n/a.

@@           Coverage Diff           @@
##           master    #7576   +/-   ##
=======================================
  Coverage   67.99%   67.99%
=======================================
  Files         248      248
  Lines        9490     9490
  Branches        5        6    +1
=======================================
  Hits         6453     6453
  Misses       3035     3035
  Partials        2        2

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e8b3d59...e14ce5b. Read the comment docs.


text:
Migrate the codebase from flow to typescript

@justinhaaheim is tracking plans and progress in separate documents. If you have questions or want to get involved reach out to him.

Hi, I'd like to help with this. Is there any updates on this and how can I get involve?

Packages

[x] lexical-clipboard
[x] lexical-code
[x] lexical-dragon
[x] lexical-file
[x] lexical-hashtag
[x] lexical-headless
[x] lexical-history
[ ] lexical-link
[ ] lexical-list
[x] lexical-mark
[ ] lexical-markdown
[ ] lexical-offset
[ ] lexical-overflow
[x] lexical-plain-text
[x] lexical-playground
[ ] lexical-react
[x] lexical-rich-text
[ ] lexical-selection
[ ] lexical-table
[ ] lexical-text
[ ] lexical-utils

Special Packages

[ ] lexical
[ ] shared
[ ] lexical-yjs

Can you share anything on the reason behind the migration?

authors: FezVrasta ivan-ngchakming justinhaaheim maasencioh

repo: facebook/lexical


text:
Collaboration example doesn't work correctly in Next.js

Lexical version: 0.4.1
Steps To Reproduce

Create a component with the example from https://lexical.dev/docs/collaboration/react
Import the component without SSR from a Next.js page
Spin up a y-websocket server
Build the NextJS project and start it
Open the page, chrome developer tab mentions this error: https://github.com/yjs/yjs/issues/438

Link to code example: https://lexical.dev/docs/collaboration/react

The current behavior
Collaboration works as intended
The expected behavior
The editor doesn't update between instances. (Typing something in one editor will not show up in the other editor)
"Yjs was already imported. This breaks constructor checks and will lead to issues! - https://github.com/yjs/yjs/issues/438"

Hey @Hypercoded, try the following steps:

Add the following line to your webpack config in next.config.js, so all imports point to the same version of yjs   webpack: (   config,   { buildId, dev, isServer, defaultLoaders, nextRuntime, webpack } ) => {   config.resolve.alias.yjs = path.resolve("node_modules/yjs/dist/yjs.cjs");   return config; },
When importing yjs, use the cjs version const Y = require("yjs");

Hey @Hypercoded, try the following steps:

Add the following line to your webpack config in next.config.js, so all imports point to the same version of yjs   webpack: ( config, { buildId, dev, isServer, defaultLoaders, nextRuntime, webpack } ) => { config.resolve.alias.yjs = path.resolve("node_modules/yjs/dist/yjs.cjs"); return config; },
When importing yjs, use the cjs version const Y = require("yjs");

Got it, thank you. That works!

authors: EhsaanIqbal Hypercoded


text:
Bug: Lexical Rich Text Sandbox

On the Rich Text Sandbox when I try to select an element from the dropdown menu :

There is a type error

Lexical version:
0.6.2
Steps To Reproduce

Go to : https://codesandbox.io/s/lexical-rich-text-example-5tncvy
select an element from de dropwdown select

Link to code example:
https://codesandbox.io/s/lexical-rich-text-example-5tncvy
The current behavior
You cant select an option
The expected behavior
You should be able to select an option

Should be fixed now. Sorry, it was updated to a newer version where the API for that changed.

Ah, my save didn't get applied. Try again once more – sorry.

authors: RiedelNicolas trueadm


text:
Bug: Where to find - LexicalTabIndentationPlugin?

As denoted in these notes, indentation on tab press is no longer enabled by default, and the suggested solution is to use LexicalTabIndentationPlugin; however, I am failing to find the plugin.
Is this an oversight, or was the idea that we should create a plugin ourselves to enable back the tab indents?
Frankly, (despite this note), I think it's a great feature to have enabled by default in Rich editor. That said, IMHO, this would be true for plain text, but I would argue that Rich Text Editing would benefit from having slightly more focus than simply indexing through.
Alternatively, maybe Lexical could pioneer something like tab + alt for indents and tab + alt + shift for outdents? 😃

Oh gawd, hate when this happens - creating an issue and finding the answer right after 🤦🏼 😅
https://github.com/facebook/lexical/blob/8cb0c5ba04fa546e869aa8e35653aaac5f0adcab/packages/lexical-react/src/LexicalTabIndentationPlugin.tsx.
Sorry folks 😁

Try doing:
import { TabIndentationPlugin } from '@lexical/react/LexicalTabIndentationPlugin';

Hey @trueadm, many thanks; this works! 🥳

authors: ScottAgirs trueadm


text:
Show there is a bug in ElementNode.hasFormat

Opening a PR to show how the tests fail after adding this commit.

Ran into this bug while implementing an active indicator on toolbar buttons similar to how Playground does.
Notice how multiple buttons end up active because hasFormat is returning true.

I could also be misusing the API :man_shrugging: . Here's my code:
class SomeClass {
  active(editor: LexicalEditor): boolean {
    const selection = $getSelection();

    if (!$isRangeSelection(selection) && !$isNodeSelection(selection)) {
      return false;
    }

    return this.allNodesHaveFormat(selection.getNodes(), this.format);
  }

  allNodesHaveFormat(nodes: LexicalNode[], format: ElementFormatType): boolean {
    return all(nodes, node => this.nodeHasFormat(node, format));
  }

  nodeHasFormat(node: LexicalNode, format: ElementFormatType): boolean {
    const element = $getNearestBlockElementAncestorOrThrow(node);
    return element.hasFormat(format);
  }
}

SomeClass.active does get called in a context where the $ functions should work.
  React.useEffect(() => {
    return mergeRegister(
      editor.registerUpdateListener(({editorState}) => {
        editorState.read(() => {
          setActive(someClassInstance.active(editor))
        });
      }),
    )
  }, [editor]);

This doesn't seem right. We use bitwise as you can have multiple formats active at once.

Oh, the lovely format function.. it always causes confusion even within the team. This method should be called align instead (it was inherited from TextNode but works in different ways). Unfortunately, we can't fully rename it because that would imply some annoying JSON serialization changes we don't want to push forward.

@trueadm what is ElementFormatType justify? Is the idea that a node could be aligned left, center or right, and justified at the same time?
Or is it that ElementNode.__format is encoding more than just the ElementFormatType?
Sorry for the false alarm.

The idea was that by being bitwise, we might want to add additional format types in the future. Right now it's kind of exclusive to alignment, but that was more of an implementation detail that has existed since forever.

Thank you both for the context. I can think of two possible ways of fixing it then.
Change bitwise values
If I understand correctly. The issue is that 1, 2, 3, and 4 don't work as bitwise values.
For example, checking if a node with align left(1) has align right(3) returns true because their values &ed return non 0.
1 == 0b01
3 == 0b11

  0b01
& 0b11
-------
  0b01

Should we change it to:
-export const IS_ALIGN_LEFT = 1;
-export const IS_ALIGN_CENTER = 2;
-export const IS_ALIGN_RIGHT = 3;
-export const IS_ALIGN_JUSTIFY = 4;
+export const IS_ALIGN_LEFT = 1 << 1;
+export const IS_ALIGN_CENTER = 1 << 2;
+export const IS_ALIGN_RIGHT = 1 << 3;
+export const IS_ALIGN_JUSTIFY = 1 << 4;

Would this break serialized/deserialized EditorState?
Add ElementNode.hasAlignment
Or can we add a ElementNode.hasAlignment(t: ElementAlignmentType): boolean that only has to worry about alignment and implement it how I implemented hasFormat on 7b3a5d5f4de12c96def68db5287cfbdbbc31678d ?
type ElementAlignmentType = 'left' | 'center' | 'right' | 'justify' | '';

type ElementFormatType = ElementAlignmentType; // don't break the existing type

Later, if some other formatting options make their way here, it can be changed to:
type ElementFormatType = ElementAlignmentType | SomethingElse

Or:
diff --git a/packages/lexical/src/nodes/LexicalElementNode.ts b/packages/lexical/src/nodes/LexicalElementNode.ts
index 402dbcbe..377dc79f 100644
--- a/packages/lexical/src/nodes/LexicalElementNode.ts
+++ b/packages/lexical/src/nodes/LexicalElementNode.ts
@@ -240,8 +240,8 @@ export class ElementNode extends LexicalNode {
   }
   hasFormat(type: ElementFormatType): boolean {
     if (type !== '') {
-      const formatFlag = ELEMENT_TYPE_TO_FORMAT[type];
-      return (this.getFormat() & formatFlag) !== 0;
+      const formatFlag = 1 << ELEMENT_TYPE_TO_FORMAT[type];
+      return ((1 << this.getFormat()) & formatFlag) !== 0;
     }
     return false;
   }

I'm going to guess this is the correct solution.

-export const IS_ALIGN_LEFT = 1;
-export const IS_ALIGN_CENTER = 2;
-export const IS_ALIGN_RIGHT = 3;
-export const IS_ALIGN_JUSTIFY = 4;
+export const IS_ALIGN_LEFT = 1 << 1;
+export const IS_ALIGN_CENTER = 1 << 2;
+export const IS_ALIGN_RIGHT = 1 << 3;
+export const IS_ALIGN_JUSTIFY = 1 << 4;

Ah this seems like a mistake on my side of things. Given this, your original PR makes much more sense, as this isn't using bitwise (as it was intended to). As you allude to, changing this is a bigger breaking change. I think we should stick with your original. Sorry for the churn.

Closing this due to becoming stale.

authors: thegreatercurve trueadm wilbertom zurfyx


text:
Fix: Bug - 6000: Changing the font size when inputting does not take …

…effect

Description

Describe the changes in this pull request
Closes: #
Test plan
Before
Insert relevant screenshots/recordings/automated-tests
After
Insert relevant screenshots/recordings/automated-tests

Before:
https://github.com/facebook/lexical/assets/740916/8ad37d7a-974b-456c-9d44-0fc3219950e8
After:
https://github.com/facebook/lexical/assets/740916/a053411e-3834-4bc7-ad6d-746d5b49027e


text:
How to implement another operations beyond the basic ones?

Sorry for posting a question like this here. If there is another place better for you let me know.
So, I would like to know if I can achieve more operations beyond the basic ones that implements GraphStore and NodeStore.
Supose I want to achieve some 3 levels deep traversals, is there some place on the code reserved for these flexibilities? I found on your sigmod paper this phrase: "There are features, such as complex search queries, that cannot be eﬃciently implemented using this interface and are implemented as separate specialized services.". Could you explain what does it mean?
Thanks.

You could implement traversals on top of the Linkbench API with multiple calls.
Some other graph benchmarks focus more on those kind of multi-hop traversals and that has a place but they weren't as relevant for the workload Linkbench was modelling.
When I wrote that sentence about search queries I was alluding to some other backend services Facebook uses for things like Graph Search or text search.  E.g. if you want to efficiently query, say, "people in Chicago named Tim who like Justin Bieber" you need additional indexes and a different query API.
I'm not sure if this is the appropriate place either - I suppose we can take the conversation into email if we want to get more in depth.

Other products handle more complex query processing. Perhaps we need a few more interns like Tim Armstrong to do awesome work leading to SIGMOD/VLDB/ICDE papers explaining the workload on those systems. Well, it would also help to have public conference papers explaining those systems but that has yet to happen. I am not sure that it is a good idea to have the basic social graph OLTP service try to support more complex queries. That might hurt quality of service (response time, etc). This is an interesting question though.

Thanks for the answers! I understand the whole point of the Linkbench. I think the main basic operations and only single hops are a good representation of actual OLTP needs as a whole service. And with this basic operations helps to validate if graph databases are good enough for theses use cases and not only for specific deep traversals.

authors: luccasmaso mdcallag timarmstrong

repo: facebook/linkbench


text:
per-method curl options

The curl function in WebDriverBase.php has this code:
foreach ($extra_opts as $option => $value) {
  curl_setopt($curl, $option, $value);
}

It would be nice to be able to pass $extra_opts to this function for one curl invocation but I don't see how to do this.  Put another way, if I'm sending a message to selenium by making a call like:
$session->open("http://www.foo.com");
I don't see how to add extra curl options for that call.
Perhaps adding an additional argument named $extra_opts to __call in WebDriverBase.php would do it at least for the "simple" messages but I bet there are a number of ways.  I'll take a crack at a patch if you're interested.

hey, so i was thinking about this, and i'm hesitant to add any functionality to support this, because while you may find it occasionally useful, each kitchen-sink debugging addition like this ultimately obscures discoverability of the 99% of functionality that most people care about.  if you have dug into the code to the point of wanting to test your frame() call and manipulate the curl options, then i think it's better to just have you add that code manually as you did, or even create a fork with that feature if you find it useful, but my current inclination is to keep the client "very thin" and minimal as the readme espouses.  ;o)
let me know what you think.  i could be persuaded otherwise :)

yeah a verbose=true sort of flag.

$extra_opts is used internally by the framework :) so it's needed.

repo: facebook/php-webdriver