If your cards have complex behavior such as the examples you gave, the best solution is probably to create a little domain specific language.
Card behaviors are defined as programs in this language, and the game contains an interpreter for this language.
You need to make the language powerful enough to be able to express any reasonable in-game logic that might be needed by newly defined card types, and programs need to be able to access and manipulate game state.
Possible implementation options for a DSL are a Forth-like system (incredibly simple) or an embedded Lua interpreter (also relatively simple), but as you use JavaScript/NodeJS you already have a nice language to use as basis.