Observable.fromPromise does not exist ONLY when building on CircleCI - node.js

Can anybody please help me figuring this out. The code fragment below runs in a NodeJS Typescript environment en this works fine on multiple machines across multiple platforms but fails to build on CircleCI with the following:
error TS2339: Property 'fromPromise' does not exist on type 'typeof Observable'.
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/frompromise';
import 'rxjs/add/operator/do';
return Observable.fromPromise(col.insertOne(document))
What is different in the CircleCI environment that causes this and what would be a solution?

With RxJS 5.5+, the Observable prototype does not include any static methods. For this reason, you will need to take one of two approaches to include the fromPromise (and other) static methods.
RxJS v5.5.2 is the default dependency version for Angular 5.
Approach 1 (preferred option)
To use the fromPromise method, independently import it from rxjs/observable.
import { fromPromise } from 'rxjs/observable/fromPromise';
let observable = fromPromise(promise);
This approach is beneficial for reducing the bundle size, as it will import only what you need by patching the Observable prototype.
Approach 2 (unoptimized approach)
To use the static Observable.fromPromise as you previously have, you will need to import Observable from rxjs/Rx.
import Rx from 'rxjs/Rx';
This method will import the entire core set of functionality, resulting in a larger bundle size.

OK, it must not be my day. The problem was the capital 'P' in the import statement.
import 'rxjs/add/observable/fromPromise';
This is no problem on platforms with a case insensitive filesystem so I didn't notice it on Mac OS/X and also not on Windows. but CircleCI uses Linux.

Related

unable to figure out error from passport-custom

trying to use passport-custom and the very first line, from pseudocode at npmjs, errors out:
import passportCustom from 'passport-custom';
The is no default import in index.js when I open it up under node_modules/passport-custom/lib
I must be missing something fundamental here, don't know what though
Try to use CommonJS const passportCustom = require("passport-custom") You probably have older version of Node.js which does not support ES6 modules.
There is no default export. So you will have to name the items you want to import (put them in curly braces).
//Example:
import { a,b,c,d} from 'youPackage';
//Your case:
import { passportCustom } from 'passport-custom';
Above are called named imports. When a package exports one item by default using: export default passportCustom ;, you could have use your code. You can access the code of the package to have a look for yourself.

Typescript imports destroys lookup?

I am trying to use a nodejs library like uuid in my typescript app. This simple import works just fine if I want to only use it in a specific class:
import { v4 } from "uuid";
class MyClass {
...
}
However, this makes the class MyClass not "discoverable" by any other files in my solution. Sure I could export it, but that forces me to import the class in every usage, and the problem spreads like a cancer to every file. Do I really have to import/export every single class/file in my application just because I want to produce a simple UUID?
I saw that I can use require instead, however typescript doesn't know what that keyword is. I found this question but neither installing #types/node nor the quick and dirty declare var require any works.
It really seems like I am jumping through a lot of unnecessary hoops just to generate a uuid in typescript. Am I doing something very wrong?
Thanks

How to write a tensorflowjs-dependent library that will import from either tfjs or tfjs-node appropriately

I am writing a TypeScript library that is basically a clone of the python tensorflow-probability package. I am intending to use this library in other projects, both server-side and in the browser. When the downstream project imports the tfjs-probability code, I would like the tfjs backend to utilize whatever resources are available in the runtime of the user.
Is there a canonical way to write the library code so that it imports tensor from '#tensorflow/tfjs' when the package should be used on the front-end, but imports from '#tensorflow/tfjs-node', when used in a node environment?
Should I be configuring this in my build tool (webpack)?
for example. In my tfjs-probability package I have:
import { tensor } from '#tensorflow/tfjs'; // alternately '#tensorflow/tfjs-node'
export class NormalDist { //code that uses tensors }
and I am imagining that I would do something like this in a downstream project:
import { NormalDist } from 'tfjs-probability';
const n = new NormalDist()
and somehow my library would be smart enough to know whether to use tensorflowjs webgl (in the browser) or tensorflowjs-node.

Can't import exported functions

I am having strange issues with Typescript when I import things from a file which exports them. Sometimes I will export a function, then import it to another file, then I use the function and it is not a function anymore. When I define the function in the same file, all of a sudden the function is a function?!?!?
Why would a function stop being a function when it is exported? I have had similar problems with classes too.
The hard part of this issue is I can't recreate a simple example because it only happens when I am using some kind of higher level package.
For example, I had a similar issue with sequelize-typescript here: my github issue with typescript-sequelize
Below is some codes showing off the basic issue I'm having with one of the decorators from InversifyJS.
container.ts
import {fluentProvide} from "inversify-binding-decorators";
export const provideSingleton = (identifier: any) => {
return fluentProvide(identifier)
.inSingletonScope()
.done(true);
};
test.service.ts
import {provideSingleton} from './container'
#provideSingleton(TYPES.TEST)
export default class TestService {}
The strangest thing is when I put the provideSingleton in the same file as the TestService, everything works!?!?!
Basically to recreate the issue, simply follow the example from here: inversify-binding-decorators - Using #provideFluent multiple times. However there is an issue with the example, so please see this issue: fluentProvide example needed. The above provideSingleton reflects the changes from that issue. Then you simply import the provideSingleton function from another file instead of defining it in the same like in the example.
Can anyone explain to me what I'm missing? Why oh why would certain exported items not bee seen as the type they are? Is there a step I'm not seeing that NodeJS takes to make the item actually exported and therefore different? Can I force the function to resolve as a function so it can be used as such?
ENV:
NodeJS: 10.9.0
Typescript: 3.0.1
Mac: 10.13.16
So it looks like you can get issues like this when NodeJS can't handle a recursive import. I'm not exactly sure how to check you are getting this error other than your symptoms are like what I stated above. Basically the recursion caused my function to not load and therefore undefined is not a function.
It would be easy to notice if you had code like so:
a.ts
import B from './b';
export default class A extends B {}
b.ts
import A from './a';
export default class B extends A {}
In my case, I think my function provideSingleton did not like the file I put it in because of some conflicting code in the file, which all I had was:
import {Container} from 'inversify';
import "reflect-metadata";
import {fluentProvide} from "inversify-binding-decorators";
const container = new Container();
function ProvideSingleton(identifier: any) {
return fluentProvide(identifier)
.inSingletonScope()
.done(true);
}
export {container, ProvideSingleton}
In the end, if this issue comes up, try another file for your function and pay good attention to how the order of the loading happens. Although NodeJS handles recursive imports most of the time, you can still trip it out.

TypeScript 0.8.2 importing Node.js modules in internal modules

Okay, as I can see you would like to use internal modules in your project. Well, there was a workaround in TypeScript 0.8.1.1, you could define non exported module (internal) and add imports above it. In 0.8.2 it seems that this doesn't work anymore. Only option I see here would be to completely omit import syntax and use standard require for node modules. I don't know if this is a good idea but please, share your opinions. I know that using import syntax will make module external (language specification), but that wasn't true in 0.8.1.1, bug maybe?
In TypeScript 0.8.1.1 this worked and doesn't work in 0.8.2 anymore:
import path = module('path');
import fs = module('fs');
module SomeNamespace.Controller {
export class Index {
...
}
}
I could reference file including above code using reference syntax on top of file in other internal modules and normally call:
var ctrl = new SomeNamespace.Controller.Index;
ctrl.index();
It seems that in 0.8.2 this is the only way what it works for internal modules:
var path = require('path');
var fs = require('fs');
module SomeNamespace.Controller {
export class Index {
...
}
}
Are there any other possibilities to mix internal modules with Node.js modules? Is there something wrong with above require usage (it compiles and runs okay ...)?
I think that TypeScript 0.8.2 takes us closer to the specification.
The syntax:
import x = module('SomeModule');
Is specifically an ExternalModuleReference in the TypeScript Language Specification.
An internal module would be imported using:
///<reference path="SomeModule.ts" />
import x = SomeModule;
But importing an internal module won't generate you a require statement in your JavaScript.
Taken from TypeScript Language Specification 0.8 - 9.2.2 Import Declarations
ImportDeclaration:
import Identifier = ModuleReference ;
ModuleReference:
ExternalModuleReference
ModuleName
ExternalModuleReference:
module ( StringLiteral )
Ok, this error is due to the version of the TypeScript.
In TypeScript 0.8.1.1 to import an external module the syntax has to be:
export import <moduleName> = module(“<path>”);
This is a bug identified in the latest version of TypeScript, you can return to the previous version or change the syntax to make it compatible with v0.8.1.1. Have in mind that this is a bug and in future versions, you should be able to use the original syntax.
This is the official thread for this bug:
http://typescript.codeplex.com/discussions/405800

Resources