1- import { ArticleConfig , ArticleApi , ArticlePublishedStatus , UpdateStatus } from './dev-to-git.interface' ;
1+ import {
2+ ArticleConfig ,
3+ ArticleApi ,
4+ ArticlePublishedStatus ,
5+ UpdateStatus ,
6+ ArticleApiResponse ,
7+ } from './dev-to-git.interface' ;
28import got from 'got' ;
39import fs from 'fs' ;
410import extractFrontMatter from 'front-matter' ;
@@ -19,7 +25,24 @@ interface ImageToReplace {
1925}
2026
2127export class Article {
22- constructor ( private articleConfig : ArticleConfig ) { }
28+ // dev.to API returns a maximum of 1000 articles but would by default return only 30
29+ // https://docs.dev.to/api/#tag/articles/paths/~1articles~1me~1all/get
30+ // instead of having to manage the pagination I think it's safe to assume people using
31+ // dev-to-git won't have more than 1000 articles for now
32+ // also note that we're using a property instead of a method here so that the result is
33+ // shared/reused for all the different articles with only 1 HTTP call
34+ private articles : Promise < Record < number , string > > = got ( `https://dev.to/api/articles/me/all?per_page=1000` , {
35+ json : true ,
36+ method : 'GET' ,
37+ headers : { 'api-key' : this . token } ,
38+ } ) . then ( ( res : got . Response < ArticleApiResponse [ ] > ) =>
39+ res . body . reduce < Record < number , string > > ( ( articlesMap , article ) => {
40+ articlesMap [ article . id ] = article . body_markdown ;
41+ return articlesMap ;
42+ } , { } ) ,
43+ ) ;
44+
45+ constructor ( private articleConfig : ArticleConfig , private token : string ) { }
2346
2447 private updateLocalImageLinks ( article : string ) : string {
2548 let searchImageResult ;
@@ -55,14 +78,7 @@ export class Article {
5578 return this . updateLocalImageLinks ( article ) ;
5679 }
5780
58- private fetchArticleBodyMarkdown ( articleId : number ) : Promise < string | null > {
59- return got ( `https://dev.to/api/articles/${ articleId } ` , {
60- json : true ,
61- method : 'GET' ,
62- } ) . then ( ( x : got . Response < ArticleApi > ) => x . body . body_markdown ) ;
63- }
64-
65- public async publishArticle ( token : string ) : Promise < ArticlePublishedStatus > {
81+ public async publishArticle ( ) : Promise < ArticlePublishedStatus > {
6682 const body : ArticleApi = {
6783 body_markdown : this . readArticleOnDisk ( ) ,
6884 } ;
@@ -80,34 +96,36 @@ export class Article {
8096
8197 let remoteArticleBodyMarkdown : string | null ;
8298
83- // if it's a draft, the article cannot be fetched so we just re-publish drafts
84- if ( frontMatter . published ) {
85- try {
86- remoteArticleBodyMarkdown = await this . fetchArticleBodyMarkdown ( this . articleConfig . id ) ;
87- } catch ( error ) {
88- return {
89- updateStatus : UpdateStatus . ERROR as UpdateStatus . ERROR ,
90- articleId : this . articleConfig . id ,
91- articleTitle : frontMatter . title ,
92- error,
93- published : frontMatter . published ,
94- } ;
95- }
99+ try {
100+ const articles : Record < number , string > = await this . articles ;
101+ remoteArticleBodyMarkdown = articles [ this . articleConfig . id ] ;
96102
97- if ( remoteArticleBodyMarkdown && remoteArticleBodyMarkdown . trim ( ) === body . body_markdown . trim ( ) ) {
98- return {
99- articleId : this . articleConfig . id ,
100- updateStatus : UpdateStatus . ALREADY_UP_TO_DATE as UpdateStatus . ALREADY_UP_TO_DATE ,
101- articleTitle : frontMatter . title ,
102- published : frontMatter . published ,
103- } ;
103+ if ( ! remoteArticleBodyMarkdown ) {
104+ throw new Error ( ) ;
104105 }
106+ } catch ( error ) {
107+ return {
108+ updateStatus : UpdateStatus . ERROR as UpdateStatus . ERROR ,
109+ articleId : this . articleConfig . id ,
110+ articleTitle : frontMatter . title ,
111+ error,
112+ published : frontMatter . published ,
113+ } ;
114+ }
115+
116+ if ( remoteArticleBodyMarkdown && remoteArticleBodyMarkdown . trim ( ) === body . body_markdown . trim ( ) ) {
117+ return {
118+ articleId : this . articleConfig . id ,
119+ updateStatus : UpdateStatus . ALREADY_UP_TO_DATE as UpdateStatus . ALREADY_UP_TO_DATE ,
120+ articleTitle : frontMatter . title ,
121+ published : frontMatter . published ,
122+ } ;
105123 }
106124
107125 return got ( `https://dev.to/api/articles/${ this . articleConfig . id } ` , {
108126 json : true ,
109127 method : 'PUT' ,
110- headers : { 'api-key' : token } ,
128+ headers : { 'api-key' : this . token } ,
111129 body,
112130 } )
113131 . then ( ( ) => ( {
0 commit comments