Skip to content

Commit

Permalink
dove & typescript refactor (#118)
Browse files Browse the repository at this point in the history
* refactor!: init typescript

* refactor!: init typescript

* vite

* refactor!: update dependencies
- remove 'order' & 'sku' service because of stripe v11
- move to feathers v5
- use unbuild for building

* chore: update dependencies

* chore: update dependencies

* fix(subscriptions): build

* chore: stripe as peerDependency & docs
  • Loading branch information
fratzinger authored Aug 31, 2023
1 parent 433d0a0 commit b389ee4
Show file tree
Hide file tree
Showing 90 changed files with 11,707 additions and 9,144 deletions.
48 changes: 48 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"root": true,
"env": {
"node": true
},
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint", "prettier"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"rules": {
"quotes": ["warn", "double", "avoid-escape"],
"indent": ["warn", 2, { "SwitchCase": 1 }],
"semi": ["warn", "always"],
"@typescript-eslint/no-unused-vars": "warn",
"no-console": "off",
"camelcase": "warn",
"require-atomic-updates": "off",
"prefer-destructuring": [
"warn",
{
"AssignmentExpression": { "object": false, "array": false },
"VariableDeclarator": { "object": true, "array": true }
},
{
"enforceForRenamedProperties": false
}
],
"object-curly-spacing": ["warn", "always"],
"prefer-const": ["warn"],
"@typescript-eslint/consistent-type-imports": [
"warn",
{ "prefer": "type-imports" }
]
},
"overrides": [
{
"files": ["test/**/*.ts"],
"rules": {
"@typescript-eslint/ban-ts-comment": ["off"],
"@typescript-eslint/no-explicit-any": ["off"],
"@typescript-eslint/no-unused-vars": ["off"]
}
}
]
}
8 changes: 0 additions & 8 deletions .github/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,6 @@ Although we generally accept many PRs they can be rejected for many reasons. We

Before running the tests from the `test/` folder `npm test` will run ESlint. You can check your code changes individually by running `npm run lint`.

### ES6 compilation

Feathers uses [Babel](https://babeljs.io/) to leverage the latest developments of the JavaScript language. All code and samples are currently written in ES2015. To transpile the code in this repository run

> npm run compile
__Note:__ `npm test` will run the compilation automatically before the tests.

### Tests

[Mocha](http://mochajs.org/) tests are located in the `test/` folder and can be run using the `npm run mocha` or `npm test` (with ESLint and code coverage) command.
Expand Down
26 changes: 26 additions & 0 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x, 18.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm run test

build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18.x
- run: npm install
- run: npm run build
15 changes: 0 additions & 15 deletions .istanbul.yml

This file was deleted.

3 changes: 0 additions & 3 deletions .mocharc.json

This file was deleted.

10 changes: 0 additions & 10 deletions .npmignore

This file was deleted.

4 changes: 0 additions & 4 deletions .travis.yml

This file was deleted.

2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2015 Feathers
Copyright (c) 2023 Feathers

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
124 changes: 58 additions & 66 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
# feathers-stripe

[![Greenkeeper badge](https://badges.greenkeeper.io/feathersjs-ecosystem/feathers-stripe.svg)](https://greenkeeper.io/)

[![Build Status](https://travis-ci.org/feathersjs-ecosystem/feathers-stripe.png?branch=master)](https://travis-ci.org/feathersjs-ecosystem/feathers-stripe)
[![Dependency Status](https://img.shields.io/david/feathersjs-ecosystem/feathers-stripe.svg?style=flat-square)](https://david-dm.org/feathersjs-ecosystem/feathers-stripe)
[![CI](https://github.com/feathersjs-ecosystem/feathers-stripe/workflows/CI/badge.svg)](https://github.com/feathersjs-ecosystem/feathers-stripe/actions?query=workflow%3ACI)
[![Dependency Status](https://img.shields.io/librariesio/release/npm/feathers-stripe)](https://libraries.io/npm/feathers-stripe)
[![Download Status](https://img.shields.io/npm/dm/feathers-stripe.svg?style=flat-square)](https://www.npmjs.com/package/feathers-stripe)
[![Slack Status](http://slack.feathersjs.com/badge.svg)](http://slack.feathersjs.com)
[![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/qa8kez8QBx)

> A Feathers service for Stripe
## Installation

```
npm install feathers-stripe --save
npm install stripe@^13 feathers-stripe --save
```

## Documentation
Expand All @@ -22,25 +20,25 @@ Please refer to the [Stripe API Docs](https://stripe.com/docs/api/node) and the
- Feathers `find` -> Stripe `list`
- Feathers `get` -> Stripe `retrieve`
- Feathers `create` -> Stripe `create`
- Feathers `patch` -> Stripe `update` (in most cases). Some special cases include paying an invoice or an order when you pass `{pay: true}` as part of `hook.data`. See each service's code for more info.
- Feathers `update` -> Stripe `update`
- Feathers `patch` -> Stripe `update` (in most cases). Some special cases include paying an invoice or an order when you pass `{pay: true}` as part of `context.data`. See each service's code for more info.
- Feathers `remove` -> Stripe `del` (in most cases). Some special cases include transfers and charges create a reversal/refund. See each service's code for more info.

If a method is not supported by Stripe for a given resource it is not support here as well.
If a method is not supported by Stripe for a given resource it is not supported here as well.

Use `params.stripe` to pass additional parameters like `expand`, `idempotencyKey`, `apiVersion`, etc to the underlying Stripe methods.

Many methods support/require passing special properties to `hook.data` and `hook.query` to better inform the underlying stripe methods. You are encouraged to read the source code for each service to better understand their usage. For example, the `Card` service requires a `customer` to be provided.
Many methods support/require passing special properties to `context.data` and `context.query` to better inform the underlying stripe methods. You are encouraged to read the source code for each service to better understand their usage. For example, the `Card` service requires a `customer` to be provided.

```js
const card = await app.service('stripe/cards').create({
customer: 'cust_123',
source: { token: 'tok_123' }
```ts
const card = await app.service("stripe/cards").create({
customer: "cust_123",
source: { token: "tok_123" }
});
// stripe.customers.createSource(customer, { source: { ... } });

const card = await app.service('stripe/cards').get('card_123', {
query: { customer: 'cust_123' }
const card = await app.service("stripe/cards").get("card_123", {
query: { customer: "cust_123" }
});
// stripe.customers.retrieveSource(query.customer, id);
```
Expand All @@ -63,7 +61,6 @@ The following services are supported and map to the appropriate Stripe resource:
- `ExternalAccount`
- `InvoiceItem`
- `Invoice`
- `Order`
- `PaymentIntent`
- `PaymentMethod`
- `Payout`
Expand All @@ -73,7 +70,6 @@ The following services are supported and map to the appropriate Stripe resource:
- `Recipient`
- `Refund`
- `SetupIntent`
- `Sku`
- `Source`
- `SubscriptionItem`
- `Subscription`
Expand All @@ -83,18 +79,17 @@ The following services are supported and map to the appropriate Stripe resource:
- `Transfer`
- `Webhook`


**This is pretty important!** Since this connects to your Stripe account you want to make sure that you don't expose these endpoints via your app unless the user has the appropriate permissions. You can prevent any external access by doing this:

```js
const { Forbidden } = require('@feathersjs/errors');
```ts
import { Forbidden } from "@feathersjs/errors";

app.service('stripe/cards').hooks({
app.service("stripe/cards").hooks({
before: {
all: [
context => {
if(context.params.provider) {
throw new Forbidden('You are not allowed to access this');
(context) => {
if (context.params.provider) {
throw new Forbidden("You are not allowed to access this");
}
}
]
Expand All @@ -104,8 +99,8 @@ app.service('stripe/cards').hooks({

**This is pretty important!** You are also encouraged to use some kind of rate limiter. Checkout the [Stripe Rate Limit Docs](https://stripe.com/docs/rate-limits)

```js
const Bottleneck = require('bottleneck');
```ts
import Bottleneck from 'bottleneck';

// Configure 100 reqs/second for production, 25 for test mode
const readLimiter = new Bottleneck({ minTime: 10 });
Expand Down Expand Up @@ -159,38 +154,40 @@ app.service('stripe/cards').hooks({

## Complete Example

Here's an example of a Feathers server that uses `feathers-authentication` for local auth. It includes a `users` service that uses `feathers-mongoose`. *Note that it does NOT implement any authorization.*
Here's an example of a Feathers server that uses `feathers-authentication` for local auth. It includes a `users` service that uses `feathers-mongoose`. _Note that it does NOT implement any authorization._

```js
const feathers = require('@feathersjs/feathers');
const express = require('@feathersjs/express');
const socketio = require('@feathersjs/socketio');
var { Charge } = require('feathers-stripe');
```ts
import { feathers } from "@feathersjs/feathers";
import express from "@feathersjs/express";
import socketio from "@feathersjs/socketio";
import Stripe from 'stripe';
import { ChargeService } from "feathers-stripe";

// Initialize the application
var app = feathers()
const app = feathers()
.configure(express.rest())
.configure(socketio())
// Needed for parsing bodies (login)
.use(express.json())
.use(express.urlencoded({ extended: true }))
// A simple Message service that we can used for testing
.use('/stripe/charges', new Charge({ secretKey: 'your secret stripe key' }))
.use('/', feathers.static(__dirname + '/public'))
.use(
"/stripe/charges",
new ChargeService({ stripe: new Stripe('sk_test_...') })
)
.use("/", feathers.static(__dirname + "/public"))
.use(express.errorHandler({ html: false }));

const validateCharge = () => (hook) => {
console.log("Validating charge code goes here");
};

function validateCharge() {
return function(hook) {
console.log('Validating charge code goes here');
};
}


const chargeService = app.service('stripe/charges');
const chargeService = app.service("stripe/charges");

chargeService.before({
create: [validateCharge()]
chargeService.hooks({
before: {
create: [validateCharge()]
}
});

const charge = {
Expand All @@ -200,32 +197,29 @@ const charge = {
description: "Charge for [email protected]"
};

chargeService.create(charge).then(result => {
console.log('Charge created', result);
}).catch(error => {
console.log('Error creating charge', error);
});
chargeService
.create(charge)
.then((result) => {
console.log("Charge created", result);
})
.catch((error) => {
console.log("Error creating charge", error);
});

app.listen(3030);

console.log('Feathers authentication app started on 127.0.0.1:3030');
console.log("Feathers authentication app started on 127.0.0.1:3030");
```

## Webhook

You can setup a webhook using the helper function `setupWebhook` in your service

setupWebhook: (app, route, {
endpointSecret: 'webhook-endpoint-secret',
secretKey: 'your-secret-key'
handlers: {}
})

```js
module.exports = function (app) {
setupWebhook(app, '/stripe-webhook', {
endpointSecret: 'whsec_ededqwdwqdqwdqwd778qwdwqdq',
secretKey: 'sk_test_OINqdwqdE89EFqdwwdwqdqdWDQ',
```ts
export default function (app) {
setupWebhook(app, "/stripe-webhook", {
endpointSecret: "whsec_ededqwdwqdqwdqwd778qwdwqdq",
stripe: new Stripe("sk_test_..."),
handlers: {
customer: {
subscription: {
Expand All @@ -238,14 +232,12 @@ module.exports = function (app) {
});

// Get our initialized service so that we can register hooks
const service = app.service('stripe-webhook');
const service = app.service("stripe-webhook");

service.hooks(hooks);
};
}
```

## License

Copyright (c) 2019

Licensed under the [MIT license](LICENSE).
15 changes: 15 additions & 0 deletions build.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { defineBuildConfig } from "unbuild";
import pkg from "./package.json";

export default defineBuildConfig({
entries: ["./src/index"],
outDir: "./dist",
declaration: true,
externals: [
...Object.keys(pkg.dependencies),
...Object.keys(pkg.devDependencies)
],
rollup: {
emitCJS: true
}
});
Loading

0 comments on commit b389ee4

Please sign in to comment.