Skip to content

Commit

Permalink
using mappers and add track item
Browse files Browse the repository at this point in the history
  • Loading branch information
shiny0110 committed Apr 17, 2024
1 parent 763dba1 commit 4acf5c0
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 9 deletions.
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,21 @@ For further reference, please consider the following sections:
### Project Structure

📂 src

┣ 📂 datasources

┣ 📄 spotify-api.ts
┣ 📄 context.ts

┣ 📄 graphql.d.ts

┣ 📄 index.ts

┗ 📄 schema.graphql
┣ 📄 models.ts

┣ 📄 resolvers.ts

┣ 📄 schema.graphql

┗ 📄 types.ts

### Installing Dependencies

Expand Down
4 changes: 4 additions & 0 deletions codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ const config: CodegenConfig = {
plugins: ["typescript", "typescript-resolvers"],
config: {
contextType: "./context#DataSourceContext",
mappers: {
Playlist: "./models#PlaylistModel",
Track: "./models#TrackModel"
},
},
},
},
Expand Down
8 changes: 4 additions & 4 deletions src/datasources/spotify-api.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { RESTDataSource } from "@apollo/datasource-rest";
import { Playlist } from "../types";
import { PlaylistModel } from "../models";

export class SpotifyAPI extends RESTDataSource {
baseURL = "https://spotify-demo-api-fe224840a08c.herokuapp.com/v1/";

async getFeaturedPlaylists(): Promise<Playlist[]> {
async getFeaturedPlaylists(): Promise<PlaylistModel[]> {
const response = await this.get<{
playlists: {
items: Playlist[]
items: PlaylistModel[]
}
}>("browse/featured-playlists");
return response?.playlists?.items ?? [];
}

getPlaylist(playlistId: string): Promise<Playlist> {
getPlaylist(playlistId: string): Promise<PlaylistModel> {
return this.get(`playlists/${playlistId}`);
}
}
19 changes: 19 additions & 0 deletions src/models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Represents a playlist object returned by the REST API
export type PlaylistModel = {
id: string;
name: string;
description: string;
tracks: {
items: {
track: TrackModel
}[];
}
};

export type TrackModel = {
id: string;
name: string;
duration_ms: number;
explicit: boolean;
uri: string;
};
9 changes: 9 additions & 0 deletions src/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,13 @@ export const resolvers: Resolvers = {
return dataSources.spotifyApi.getPlaylist(id);
}
},
Playlist: {
tracks: ({ tracks }) => {
const { items = [] } = tracks;
return items.map(({ track }) => track);
}
},
Track: {
durationMs: (parent) => parent.duration_ms
},
};
17 changes: 17 additions & 0 deletions src/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,21 @@ type Playlist {
name: String!
"Describes the playlist, what to expect and entices the user to listen."
description: String
"The tracks of the playlist."
tracks: [Track!]!
}


"A single audio file, usually a song."
type Track {
"The ID for the track."
id: ID!
"The name of the track"
name: String!
"The track length in milliseconds."
durationMs: Int!
"Whether or not the track has explicit lyrics (true = yes it does; false = no it does not OR unknown)"
explicit: Boolean!
"The URI for the track, usually a Spotify link."
uri: String!
}
37 changes: 35 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { GraphQLResolveInfo } from 'graphql';
import { PlaylistModel, TrackModel } from './models';
import { DataSourceContext } from './context';
export type Maybe<T> = T | null;
export type InputMaybe<T> = Maybe<T>;
Expand Down Expand Up @@ -26,6 +27,8 @@ export type Playlist = {
id: Scalars['ID']['output'];
/** The name of the playlist. */
name: Scalars['String']['output'];
/** The tracks of the playlist. */
tracks: Array<Track>;
};

export type Query = {
Expand All @@ -41,6 +44,21 @@ export type QueryPlaylistArgs = {
id: Scalars['ID']['input'];
};

/** A single audio file, usually a song. */
export type Track = {
__typename?: 'Track';
/** The track length in milliseconds. */
durationMs: Scalars['Int']['output'];
/** Whether or not the track has explicit lyrics (true = yes it does; false = no it does not OR unknown) */
explicit: Scalars['Boolean']['output'];
/** The ID for the track. */
id: Scalars['ID']['output'];
/** The name of the track */
name: Scalars['String']['output'];
/** The URI for the track, usually a Spotify link. */
uri: Scalars['String']['output'];
};



export type ResolverTypeWrapper<T> = Promise<T> | T;
Expand Down Expand Up @@ -114,24 +132,29 @@ export type DirectiveResolverFn<TResult = {}, TParent = {}, TContext = {}, TArgs
export type ResolversTypes = {
Boolean: ResolverTypeWrapper<Scalars['Boolean']['output']>;
ID: ResolverTypeWrapper<Scalars['ID']['output']>;
Playlist: ResolverTypeWrapper<Playlist>;
Int: ResolverTypeWrapper<Scalars['Int']['output']>;
Playlist: ResolverTypeWrapper<PlaylistModel>;
Query: ResolverTypeWrapper<{}>;
String: ResolverTypeWrapper<Scalars['String']['output']>;
Track: ResolverTypeWrapper<TrackModel>;
};

/** Mapping between all available schema types and the resolvers parents */
export type ResolversParentTypes = {
Boolean: Scalars['Boolean']['output'];
ID: Scalars['ID']['output'];
Playlist: Playlist;
Int: Scalars['Int']['output'];
Playlist: PlaylistModel;
Query: {};
String: Scalars['String']['output'];
Track: TrackModel;
};

export type PlaylistResolvers<ContextType = DataSourceContext, ParentType extends ResolversParentTypes['Playlist'] = ResolversParentTypes['Playlist']> = {
description?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
id?: Resolver<ResolversTypes['ID'], ParentType, ContextType>;
name?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
tracks?: Resolver<Array<ResolversTypes['Track']>, ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
};

Expand All @@ -140,8 +163,18 @@ export type QueryResolvers<ContextType = DataSourceContext, ParentType extends R
playlist?: Resolver<Maybe<ResolversTypes['Playlist']>, ParentType, ContextType, RequireFields<QueryPlaylistArgs, 'id'>>;
};

export type TrackResolvers<ContextType = DataSourceContext, ParentType extends ResolversParentTypes['Track'] = ResolversParentTypes['Track']> = {
durationMs?: Resolver<ResolversTypes['Int'], ParentType, ContextType>;
explicit?: Resolver<ResolversTypes['Boolean'], ParentType, ContextType>;
id?: Resolver<ResolversTypes['ID'], ParentType, ContextType>;
name?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
uri?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
};

export type Resolvers<ContextType = DataSourceContext> = {
Playlist?: PlaylistResolvers<ContextType>;
Query?: QueryResolvers<ContextType>;
Track?: TrackResolvers<ContextType>;
};

0 comments on commit 4acf5c0

Please sign in to comment.