Skip to content

Commit

Permalink
create typescript sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
thisisjofrank committed Apr 14, 2023
0 parents commit 7e95b9b
Show file tree
Hide file tree
Showing 89 changed files with 19,764 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
INTEGRATION_TESTS_SPOTIFY_CLIENT_ID=your_spotify_client_id_for_tests
INTEGRATION_TESTS_SPOTIFY_CLIENT_SECRET=your_spotify_client_secret_for_tests
[email protected]
INTEGRATION_TESTS_USER_PASSWORD=some-valid-password
VITE_SPOTIFY_CLIENT_ID=your_spotify_client_id_for_tests
VITE_REDIRECT_TARGET=http://localhost:3000
18 changes: 18 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
!**/glob-import/dir/node_modules
.DS_Store
.idea
*.cpuprofile
*.local
*.log
/.vscode/
/docs/.vitepress/cache
/packages/vite/LICENSE
dist
dist-ssr
explorations
node_modules
temp
TODOs.md
.eslintcache
/*.env
/example/.env
9 changes: 9 additions & 0 deletions CODEOWNERS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# This file registers ownership for certain parts of the repository.

Review from a member of the corresponding code owner is required to merge pull requests.

The last matching pattern takes precedence.
https://help.github.com/articles/about-codeowners/


Owners: @spotify/dx
69 changes: 69 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Code of Conduct

This code of conduct outlines our expectations for participants within the **Spotify FOSS** community, as well as steps to reporting unacceptable behavior. We are committed to providing a welcoming and inspiring community for all and expect our code of conduct to be honored. Anyone who violates this code of conduct may be banned from the community.

Our open source community strives to:

- **Be friendly and patient.**
- **Be welcoming**: We strive to be a community that welcomes and supports people of all backgrounds and identities. This includes, but is not limited to members of any race, ethnicity, culture, national origin, colour, immigration status, social and economic class, educational level, sex, sexual orientation, gender identity and expression, age, size, family status, political belief, religion, and mental and physical ability.
- **Be considerate**: Your work will be used by other people, and you in turn will depend on the work of others. Any decision you take will affect users and colleagues, and you should take those consequences into account when making decisions. Remember that we're a world-wide community, so you might not be communicating in someone else's primary language.
- **Be respectful**: Not all of us will agree all the time, but disagreement is no excuse for poor behavior and poor manners. We might all experience some frustration now and then, but we cannot allow that frustration to turn into a personal attack. It’s important to remember that a community where people feel uncomfortable or threatened is not a productive one.
- **Be careful in the words that we choose**: we are a community of professionals, and we conduct ourselves professionally. Be kind to others. Do not insult or put down other participants. Harassment and other exclusionary behavior aren't acceptable.
- **Try to understand why we disagree**: Disagreements, both social and technical, happen all the time. It is important that we resolve disagreements and differing views constructively. Remember that we’re different. The strength of our community comes from its diversity, people from a wide range of backgrounds. Different people have different perspectives on issues. Being unable to understand why someone holds a viewpoint doesn’t mean that they’re wrong. Don’t forget that it is human to err and blaming each other doesn’t get us anywhere. Instead, focus on helping to resolve issues and learning from mistakes.

## Definitions

Harassment includes, but is not limited to:

- Offensive comments related to gender, gender identity and expression, sexual orientation, disability, mental illness, neuro(a)typicality, physical appearance, body size, race, age, regional discrimination, political or religious affiliation
- Unwelcome comments regarding a person’s lifestyle choices and practices, including those related to food, health, parenting, drugs, and employment
- Deliberate misgendering. This includes deadnaming or persistently using a pronoun that does not correctly reflect a person's gender identity. You must address people by the name they give you when not addressing them by their username or handle
- Physical contact and simulated physical contact (eg, textual descriptions like “_hug_” or “_backrub_”) without consent or after a request to stop
- Threats of violence, both physical and psychological
- Incitement of violence towards any individual, including encouraging a person to commit suicide or to engage in self-harm
- Deliberate intimidation
- Stalking or following
- Harassing photography or recording, including logging online activity for harassment purposes
- Sustained disruption of discussion
- Unwelcome sexual attention, including gratuitous or off-topic sexual images or behaviour
- Pattern of inappropriate social contact, such as requesting/assuming inappropriate levels of intimacy with others
- Continued one-on-one communication after requests to cease
- Deliberate “outing” of any aspect of a person’s identity without their consent except as necessary to protect others from intentional abuse
- Publication of non-harassing private communication

Our open source community prioritizes marginalized people’s safety over privileged people’s comfort. We will not act on complaints regarding:

- ‘Reverse’ -isms, including ‘reverse racism,’ ‘reverse sexism,’ and ‘cisphobia’
- Reasonable communication of boundaries, such as “leave me alone,” “go away,” or “I’m not discussing this with you”
- Refusal to explain or debate social justice concepts
- Communicating in a ‘tone’ you don’t find congenial
- Criticizing racist, sexist, cissexist, or otherwise oppressive behavior or assumptions

### Diversity Statement

We encourage everyone to participate and are committed to building a community for all. Although we will fail at times, we seek to treat everyone both as fairly and equally as possible. Whenever a participant has made a mistake, we expect them to take responsibility for it. If someone has been harmed or offended, it is our responsibility to listen carefully and respectfully, and do our best to right the wrong.

Although this list cannot be exhaustive, we explicitly honor diversity in age, gender, gender identity or expression, culture, ethnicity, language, national origin, political beliefs, profession, race, religion, sexual orientation, socioeconomic status, and technical ability. We will not tolerate discrimination based on any of the protected
characteristics above, including participants with disabilities.

### Reporting Issues

If you experience or witness unacceptable behavior—or have any other concerns—please report it by contacting us via **[email protected]**. All reports will be handled with discretion. In your report please include:

- Your contact information.
- Names (real, nicknames, or pseudonyms) of any individuals involved. If there are additional witnesses, please
include them as well. Your account of what occurred, and if you believe the incident is ongoing. If there is a publicly available record (e.g. a mailing list archive or a public IRC logger), please include a link.
- Any additional information that may be helpful.

After filing a report, a representative will contact you personally, review the incident, follow up with any additional questions, and make a decision as to how to respond. If the person who is harassing you is part of the response team, they will recuse themselves from handling your incident. If the complaint originates from a member of the response team, it will be handled by a different member of the response team. We will respect confidentiality requests for the purpose of protecting victims of abuse.

### Attribution & Acknowledgements

We all stand on the shoulders of giants across many open source communities. We'd like to thank the communities and projects that established codes of conduct and diversity statements as our inspiration:

- [Django](https://www.djangoproject.com/conduct/reporting/)
- [Python](https://www.python.org/community/diversity/)
- [Ubuntu](http://www.ubuntu.com/about/about-ubuntu/conduct)
- [Contributor Covenant](http://contributor-covenant.org/)
- [Geek Feminism](http://geekfeminism.org/about/code-of-conduct/)
- [Citizen Code of Conduct](http://citizencodeofconduct.org/)
155 changes: 155 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# How to Contribute

We'd love to get patches from you!

## Getting Started

If you find a bug, please open an issue, create a PR or [chat to the team on our forum](https://community.spotify.com/t5/Spotify-for-Developers/bd-p/Spotify_Developer).

## Building dependencies

Because this SDK uses `fetch` both in Node and the Browser, and ESM, it requires the following:

- Node 18.0.0 or higher
- A modern, version infinite, browser

To install the project, cd into the project and run

```bash
npm install
```

## Building the Project

To run the project, cd into the project and run

```bash
npm run start
```

## Tests

To run the tests, you need to have a Spotify account.

You will need to create a new app in the Spotify Developer portal, and add a redirect URI of `http://localhost:3000`.

Add the following environment variables:

- `INTEGRATION_TESTS_SPOTIFY_CLIENT_ID`
- `INTEGRATION_TESTS_SPOTIFY_CLIENT_SECRET`
- `INTEGRATION_TESTS_USER_EMAIL`
- `INTEGRATION_TESTS_USER_PASSWORD`

The latter two credentials are used to run integration tests in the scope of a *real user account*. This is required to test endpoints that require a user's authorization, such as `followPlaylist`. You need to make sure that your user has access to whichever Spotify app your client credentials and secret are for.

You can run the tests with `npm run test`, or using a plugin like [Wallaby](https://wallabyjs.com/).

We support `dotenv`, so you can add these to a `.env` file in the root of the repository.

To run the embedded example app, you will need to add the following environment variables:

- `VITE_SPOTIFY_CLIENT_ID`=the same value as set in INTEGRATION_TESTS_SPOTIFY_CLIENT_ID
- `VITE_REDIRECT_TARGET`=http://localhost:3000

For the example app to work, this .env file needs to be in the ./example folder.

## Workflow

We follow the [GitHub Flow Workflow](https://guides.github.com/introduction/flow/)

### TODO: Below is an Example

1. Fork the project
2. Check out the `main` branch
3. Create a feature branch
4. Write code and tests for your change
5. From your branch, make a pull request
6. Work with repo maintainers to get your change reviewed
7. Wait for your change to be pulled
8. Delete your feature branch

## Testing

To run the tests, you need to have a Spotify account.

You will need to create a new app in the Spotify Developer portal, and add a redirect URI of `http://localhost:3000`.

You will need to add the following environment variables:

- `INTEGRATION_TESTS_SPOTIFY_CLIENT_ID`
- `INTEGRATION_TESTS_SPOTIFY_CLIENT_SECRET`
- `INTEGRATION_TESTS_USER_EMAIL`
- `INTEGRATION_TESTS_USER_PASSWORD`

The latter two credentials are used to run integration tests in the scope of a *real user account*. This is required to test endpoints that require a user's authorization, such as `followPlaylist`. You need to make sure that your user has access to whichever Spotify app your client credentials and secret are for.

You can run the tests with `npm run test`, or using a plugin like [Wallaby](https://wallabyjs.com/).

We support `dotenv`, so you can add these to a `.env` file in the root of the repository.

To run the embedded example app, you will need to add the following environment variables:

```bash
VITE_SPOTIFY_CLIENT_ID=the same value as set in INTEGRATION_TESTS_SPOTIFY_CLIENT_ID
VITE_REDIRECT_TARGET=http://localhost:3000
```

For the example app to work, this .env file needs to be in the ./example folder.

## Issues

When creating an issue please try to adhere to the following format:

module-name: One line summary of the issue (less than 72 characters)

### Expected behavior

As concisely as possible, describe the expected behavior.

### Actual behavior

As concisely as possible, describe the observed behavior.

### Steps to reproduce the behavior

List all relevant steps to reproduce the observed behavior.

## Pull Requests

We adhere to a specific format for commit messages. Please write your commit
messages along these guidelines:

module-name: One line description of your change (less than 72 characters)

Problem

Explain the context and why you're making that change. What is the problem
you're trying to solve? In some cases there is not a problem and this can be
thought of being the motivation for your change.

Solution

Describe the modifications you've done.

Result

What will change as a result of your pull request? Note that sometimes this
section is unnecessary because it is self-explanatory based on the solution.

Some important notes regarding the summary line:

- Describe what was done; not the result
- Use the active voice
- Use the present tense
- Capitalize properly
- Do not end in a period — this is a title/subject
- Prefix the subject with its scope

# License

By contributing your code, you agree to license your contribution under the
terms of the [LICENSE](LICENSE)

# Code of Conduct

Read our [Code of Conduct](CODE_OF_CONDUCT.md) for the project.
13 changes: 13 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Copyright (c) 2020 Spotify, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
15 changes: 15 additions & 0 deletions OWNERS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Owners

- See [CONTRIBUTING.md](CONTRIBUTING.md) for general contribution guidelines.

## Core Developers

- $FIRSTNAME $LASTNAME ($GHUSERNAME, Spotify)
- $FIRSTNAME $LASTNAME ($GHUSERNAME, Spotify)
- $FIRSTNAME $LASTNAME ($GHUSERNAME, Spotify)

## Triagers

- FIRSTNAME LASTNAME (@GHUSERNAME, $AFFILIATION)
- FIRSTNAME LASTNAME (@GHUSERNAME, $AFFILIATION)
- FIRSTNAME LASTNAME (@GHUSERNAME, $AFFILIATION)
16 changes: 16 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Security Policy

We're big believers in protecting your privacy and security. As a company, we not only have a vested interest, but also a deep desire to see the Internet remain as safe as possible for us all.

So, needless to say, we take security issues very seriously.

In our opinion, the practice of 'responsible disclosure' is the best way to safeguard the Internet. It allows individuals to notify companies like Spotify of any security threats before going public with the information. This gives us a fighting chance to resolve the problem before the criminally-minded become aware of it.

Responsible disclosure is the industry best practice, and we recommend it as a procedure to anyone researching security vulnerabilities.

## Reporting a Vulnerability

If you have discovered a vulnerability in this open source project or another serious security issue,
please submit it to the Spotify bounty program hosted by HackerOne.

https://hackerone.com/spotify
7 changes: 7 additions & 0 deletions catalog-info.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: Web-API-Typescript-SDK
spec:
type: library
owner: DX
2 changes: 2 additions & 0 deletions example/.env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
VITE_SPOTIFY_CLIENT_ID=your_spotify_client_id_for_tests
VITE_REDIRECT_TARGET=http://localhost:3000
8 changes: 8 additions & 0 deletions example/env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
interface ImportMetaEnv {
readonly VITE_SPOTIFY_CLIENT_ID: string
readonly VITE_REDIRECT_TARGET: string
}

interface ImportMeta {
readonly env: ImportMetaEnv
}
26 changes: 26 additions & 0 deletions example/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>Example</title>
<script src="./script.ts" type="module"></script>
<link rel="stylesheet" href="./style.css">
</head>

<body>
<h1>Display Spotify profile data</h1>

<section id="profile">
<h2>Logged in as <span id="displayName"></span></h2>
<span id="avatar"></span>
<ul>
<li>User ID: <span id="id"></span></li>
<li>Email: <span id="email"></span></li>
<li>Spotify URI: <a id="uri" href="#"></a></li>
<li>Link: <a id="url" href="#"></a></li>
<li>Profile Image: <span id="imgUrl"></span></li>
</ul>
</section>

</html>
26 changes: 26 additions & 0 deletions example/script.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { SpotifyApi } from "../src/index";
import AuthorizationCodeWithPKCEStrategy from "../src/auth/AuthorizationCodeWithPKCEStrategy";

const implicitGrantStrategy = new AuthorizationCodeWithPKCEStrategy(
import.meta.env.VITE_SPOTIFY_CLIENT_ID,
import.meta.env.VITE_REDIRECT_TARGET,
['user-read-private', 'user-read-email', 'playlist-modify-public', 'playlist-modify-private, user-read-playback-state, user-modify-playback-state']
);

const spotify = new SpotifyApi(implicitGrantStrategy);
const profile = await spotify.currentUser.profile();
console.log(profile);

document.getElementById("displayName")!.innerText = profile.display_name;
if (profile.images[0]) {
const profileImage = new Image(200, 200);
profileImage.src = profile.images[0].url;
document.getElementById("avatar")!.appendChild(profileImage);
}
document.getElementById("id")!.innerText = profile.id;
document.getElementById("email")!.innerText = profile.email;
document.getElementById("uri")!.innerText = profile.uri;
document.getElementById("uri")!.setAttribute("href", profile.external_urls.spotify);
document.getElementById("url")!.innerText = profile.href;
document.getElementById("url")!.setAttribute("href", profile.href);
document.getElementById("imgUrl")!.innerText = profile.images[0]?.url ?? '(no profile image)';
Loading

0 comments on commit 7e95b9b

Please sign in to comment.