Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Multiple Funding Sources #68

Merged
merged 2 commits into from
Feb 5, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions accepted/0018-multiple-funding-sources.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# RFC: Multiple Funding Sources

## Summary

Allow the `funding` field, which currently can contain a string or an object, to contain an array of those things as well.

## Motivation

- One package author can have more than one source of funding - GitHub Sponsors and Tidelift, for example.
- One package can have multiple authors, each with their own source(s) of funding: two different GitHub Sponsors, for example.
- This mirrors how GitHub's own sponsor button works as well: a repo can have multiple funding sources, and any source whose model is not a single project typically can have an array of multiple users.

Being forced to create a landing page - especially on an unknown domain, defeating any inference of the `type` from the URL - is a high burden for anyone in this scenario.

## Detailed Explanation

- the `funding` field, which currently can have an X, will also be able to have an array of X.
- the `npm fund` output will display all URLs in the array.

## Rationale and Alternatives

One alternative is to make no changes. The tradeoff made here would be, npm and package.json stay simpler; in exchange for maintainers who need funding to have to incur more burden.

Another alternative is for npm to *host* a funding page that consolidates multiple URLs - however, this would both still require multiple URLs, and is something that could be enhanced later if the command line UI for multiple URLs becomes untenable.

I believe this RFC is the simplest and most intuitive choice to meet the needs of maintainers.

## Implementation

The `package.json` side is surely trivial; the difficulty will be in `npm fund` output. There will be a bit of UI design needed, and that will determine the implementation difficulty.

The `--json` output of `npm fund` will also change when there's an array, but this should be trivial for consumers - change `process(fundingValue)` to `[].concat(fundingValue).map(process)`, or something equivalent. Since this sort of change was considered acceptable for https://github.com/npm/cli/pull/472, I presume it would be acceptable here as well.

Expected code that will need to change is the same as in this PR: https://github.com/npm/cli/pull/472/files

## Prior Art

- The `repository` field works in this same manner; it can be a string, an object, or an array of either.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, definitely didn't know that! Cool. But in same time, what's the use case for array? And I'm curious how this will be shown in the npm page :D

Copy link
Contributor Author

@ljharb ljharb Feb 25, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tunnckoCore see the RFC; but i have 200+ packages, all of which could have both the same Github Sponsors URL for me personally, and a unique Tidelift URL for the package.

It's up to npm to decide how it shows on the website; hopefully I get the chance to weigh in before they launch a change :-D

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's clear, i value that. I asked about the repository field, because didn't know it support an array.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case this might be a mistake on my part :-) https://docs.npmjs.com/files/package.json#repository says it can be a string or an object; I was thinking of the "author" field (which is also string or object) vs the "contributors" field (which is an array of strings-or-objects).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hahaa. Good catch, huh?

Cool, everything is clear now :)

- the GitHub Sponsor button and `FUNDING.yml` has affordances for multiple funding sources as well.

## Unresolved Questions and Bikeshedding

As part of this change, it'd be spiffy to colorize the URL and package name output, but that's also fine to defer to a separate RFC/PR.

Here's some example `npm fund` output in the `resolve` repo:
```sh
[email protected], @ljharb/[email protected], [email protected], [email protected], [email protected]
├── url: https://github.com/sponsors/ljharb
└─┬ [email protected]
└── url: https://github.com/sponsors/isaacs
```

I'd expect this to change to something like:
```sh
[email protected], @ljharb/[email protected], [email protected], [email protected], [email protected]
├── url: https://github.com/sponsors/ljharb
@ljharb/[email protected]
├── url: https://tidelift.com/funding/github/npm/@ljharb/eslint-config
[email protected]
├── url: https://tidelift.com/funding/github/npm/resolve
└─┬ [email protected]
└── url: https://github.com/sponsors/isaacs
```

The deduping might get a bit tricky since instead of a package name either being "by itself" or "grouped with others that have the same funding source", two packages could share one funding source, and then *not* share another funding source.

## Update: resolution to above bikeshedding

While working out the implementation with @ruyadorno, we decided the following:

- No longer display top-level package funding information, since this information is both useless to the maintainer of that package (since they provided the funding information) and also to avoid some tricky problems around deduping
- Invert the human output: instead of a deduped list of package names being the "key", the URL will be the "key"
- JSON output will be unchanged, except that the `funding` info, when specified as an array, will be an array in the output

Here's some example `npm fund` output in the `resolve` repo:
```sh
[email protected], @ljharb/[email protected], [email protected], [email protected], [email protected]
├── url: https://github.com/sponsors/ljharb
└─┬ [email protected]
└── url: https://github.com/sponsors/isaacs
```

With the `@ljharb/eslint-config` package adding an array with two URLs, the `resolve` output will change to (modulo archy formatting):
```sh
[email protected]
├─┬ https://github.com/sponsors/ljharb
│ └── @ljharb/[email protected], [email protected], [email protected], [email protected]
├─┬ https://tidelift.com/funding/github/npm/@ljharb/eslint-config
│ └── @ljharb/[email protected]
└─┬ https://github.com/sponsors/isaacs
└── [email protected]