It's my Birthday :D

Pyth, 73 72 71 69 67 bytes

?Qjb+m*+\ dQ"$|"*RhyeS,1Q"-~-""Congratulations on your new baby! :D

Try it online.

Output for n < 0 contains 2 leading newlines, as permitted in comments. To get rid of them, use

?QjbfT+jR*\ hQ"$|"*RhyeS,1Q"-~-""Congratulations on your new baby! :D

CJam, 76 75 bytes

ri_W>\_1e>)" $ |--~~--"2/f*Wf<N*"Congratulations on your new baby! :D"?_8>?

Try it online in the CJam interpreter.

How it works

ri           e# Read an integer from STDIN.
_W>          e# Check if it is greater than -1.
\_           e# Swap input and Boolean and copy the input.
1e>)         e# Take the maximum of input and 1 and increment the result.
             e# Let's call the result R.
" $ |--~~--" e# Push that string.
2/           e# Split it into [" $" " |" "--" "~~" "--"].
f*           e# Repeat each chunk R times.
Wf<          e# Discard the last character of each repeated chunk.
N*           e# Join the repreated chunks, separating by linefeeds.

"Congratulations on your new baby! :D"

?            e# If the input is non-zero, select the cake; else, keep the string.
_8>          e# Push a copy and discard the first 8 characters (single candle).
?            e# Select the unmodified cake/string if the input was non-negative,
             e# a candleless cake otherwise.

Ruby, 120 bytes

Revision 1 (120 bytes)

18 bytes saved thanks to manatwork

n=gets.to_i
puts ['Congratulations on your new baby! :D',%w{\ $ \ | - ~ -}.map{|e|e.ljust 2*n+1,e},'---
~~~
---'][n<=>0]

Revision 0 (138 bytes)

n=gets.to_i
n>0&&[' $',' |',?-,?~,?-].each{|e|puts''.rjust(2*n+1,e)}
puts ['Congratulations on your new baby! :D','','---
~~~
---'][n<=>0]

For positive numbers: this iterates through a string corresponding to each line of the cake. These are used as pad strings to right justify the empty string to length 2*n+1. This avoids any complications with having to print an odd number of characters, when the natural repetition is equal to the pitch of the candles (i.e. 2 characters.) n>0&& is necessary to avoid outputting a single column in case of input zero.

For all numbers: "n<=>0" finds the sign of the input. The baby message is output for n=0, and an empty string for positive n (as correct output has already been given above.) For negative n, Ruby interprets the -1 as meaning the last element of the array, and outputs the candleless cake.