jueves, 5 de noviembre de 2020

Exporting TS React components handling SVGs in a NPM package to be consumed potentially by CRA

Use the same SVG module definition as CRA: https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/lib/react-app.d.ts#L47


declare module '*.svg' {

  import * as React from 'react';

  export const ReactComponent: React.FunctionComponent<React.SVGProps<

    SVGSVGElement

  > & { title?: string }>;

  const src: string;

  export default src;

}


Use both @svgr/webpack and url-loader together in webpack config:

{
  test: /\.svg$/,
  use: ['@svgr/webpack', 'url-loader'], 
} 



miércoles, 4 de noviembre de 2020

Cannot find module 'assert' (from Doctrine) when adding React Styleguidist with plain Webpack

 Error:

utility.js:32 Uncaught Error: Cannot find module 'assert'
    at webpackMissingModule (utility.js:32)
    at eval (utility.js:32)
    at eval (utility.js:33)
    at Object../node_modules/doctrine/lib/utility.js (main.bundle.js:6860)
    at __webpack_require__ (main.bundle.js:23007)
    at fn (main.bundle.js:23218)
    at eval (typed.js:27)
    at eval (typed.js:1304)
    at Object../node_modules/doctrine/lib/typed.js (main.bundle.js:6844)
    at __webpack_require__ (main.bundle.js:23007)

This comes from Doctrine, which doesn't declares "assert" as a (peer) dependency. I installed the latest version (2.x) and it didn't work either. I compared with another app that had that dependency satisfied transitively from another module and it had "assert":"1.4.1" installed. I manually installed that one and it worked.


miércoles, 13 de mayo de 2020

Shutting up ASP.NET debug logs using Serilog

Log example:

{
"@t": "2020-05-13T23:39:04.3578970Z",
"@mt": "Executed action method {ActionName}, returned result {ActionResult} in {ElapsedMilliseconds}ms.",
// ...
"SourceContext": "Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker",
//...
}

Serilog configuration:

"Serilog": {
"WriteTo": [
{
"Name": "Console",
"Args": {
"formatter": "Serilog.Formatting.Compact.CompactJsonFormatter, Serilog.Formatting.Compact",
"restrictedToMinimumLevel": "Information"
}
}
],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft.AspNetCore": "Warning",
"System": "Warning"
}
}
},

lunes, 28 de octubre de 2019

Newtonsoft Json.NET + JsonApiSerializer: Path 'data'...type requires a JSON array

Sample code

    class Program
    {
        private static readonly HttpClient client = new HttpClient();

        static void Main(string[] args)
        {
            var cats = ProcessCats().Result;

            foreach (var cat in cats)
            {
                Console.WriteLine(cat);
                Console.WriteLine();
            }
        }

        private static async Task<Cat[]> ProcessCats()
        {
            client.DefaultRequestHeaders.Accept.Clear();
//...

            var stream = await client.GetStreamAsync("https://myapi/cats");

            var serializerSettings = new JsonApiSerializerSettings();
            var serializer = JsonSerializer.CreateDefault(serializerSettings);

            using (var textReader = new StreamReader(stream))
            using (var jsonReader = new JsonTextReader(textReader))
                return serializer.Deserialize<Cat[]>(jsonReader);

        }
    }

   public class Cat
    {
        public string Name { get; set; }

        public override string ToString()
        {
            var sb = new StringBuilder();
            sb.Append("class Cat {\n");
            sb.Append("  Name: ").Append(Name).Append("\n");
            sb.Append("}\n");
            return sb.ToString();
        }
    }


Error

Unhandled Exception: System.AggregateException: One or more errors occurred. (Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'Cat[]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'data', line 1, position 8.) ---> Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'Cat[]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'data', line 1, position 8.
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)
   at WebAPIClient.Program.ProcessCats() in /Users/esteban-work/tmp/delete/samples/csharp/getting-started/console-webapiclient/Program.cs:line 42
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at WebAPIClient.Program.Main(String[] args) in /Users/esteban-work/tmp/delete/samples/csharp/getting-started/console-webapiclient/Program.cs:line 17

Fix

Remember to check if the root element has an Id property.

   public class Cat
    {
        public string Id { get; set; }
        public string Name { get; set; }

        public override string ToString()
        {
            var sb = new StringBuilder();
            sb.Append("class ContactForClient {\n");
            sb.Append("  Id: ").Append(Id).Append("\n");
            sb.Append("  Name: ").Append(Name).Append("\n");
            sb.Append("}\n");
            return sb.ToString();
        }
    }


References




miércoles, 23 de enero de 2019

nginx: [emerg] host not found in upstream "nodejs" enabling TLS in AWS EB

Error:

2019-01-23 22:44:55    ERROR   [Instance: i-xx] Command failed on instance. Return code: 1 Output: (TRUNCATED)... /etc/nginx/sites-enabled/elasticbeanstalk-nginx-docker-proxy.conf:11
nginx: [emerg] host not found in upstream "nodejs" in /etc/nginx/conf.d/https.conf:19
nginx: configuration file /etc/nginx/nginx.conf test failed
Failed to start nginx, abort deployment.
Hook /opt/elasticbeanstalk/hooks/appdeploy/enact/01flip.sh failed. For more detail, check /var/log/eb-activity.log using console or EB CLI.

I was using a .ebextensions/singlehttps.config sample file from a Node Web Server Elastic Beanstalk app, with something like this,

location / {
proxy_pass http://nodejs;
proxy_set_header Connection "";
proxy_http_version 1.1;

but no upstream declaration because according AWS doc, "the default nginx configuration forwards traffic to an upstream server named nodejs at 127.0.0.1:8081".

But this App is a docker one (which has a Node app running on port 3500), not a nodejs one.

Looking at the EB instance's /etc/nginx/conf.d dir, this file declares a default upstream for docker:

elasticbeanstalk-nginx-docker-upstream.conf:

upstream docker {
    server xx.xx.x.x:yyy;
    keepalive 256;
}

Then,


location / {
proxy_pass http://docker;
proxy_set_header Connection "";
proxy_http_version 1.1;


domingo, 13 de enero de 2019

rb-inotify requires Ruby version >= 2.2 (installing compass)

compass 1.0.3 depends on rb-inotify >= 0.9 and rb-inotify launched a new version on December 15, 2018 which depends on Ruby >= 2.2 (the Ruby version installed through 'apt-get install -y ruby-full' on node:6.10 is 'ruby 2.1.5p273')

# lock rb-inotify version because the next one (0.10.0) depends on ruby >= 2.2
RUN gem install --no-rdoc --no-ri rb-inotify -v 0.9.10
# -​-conservative to instruct it to use the existing rb-inotify (0.9.10) instead of resolving rb-inotify >= 0.9
RUN gem install --no-rdoc --no-ri compass -v 1.0.3 -- -​-conservative

domingo, 8 de julio de 2018

Angular (ng test): Error: No provider for [object WindowConstructor]

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [...],
providers: [
...
{ provide: Window, useValue: window }
],