Skip to content
This repository was archived by the owner on Jul 6, 2025. It is now read-only.

Commit 5a4e235

Browse files
committed
initial commit
1 parent 0c8b016 commit 5a4e235

File tree

13 files changed

+755
-0
lines changed

13 files changed

+755
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules/
2+
package-lock.json

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
# pastebin.js
22
An OOP JavaScript wrapper for the Pastebin API
3+
4+
docs coming soon :tm:

package.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "pastebin",
3+
"version": "1.0.0",
4+
"description": "An OOP JavaScript wrapper for the Pastebin API",
5+
"main": "src/index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/cAttte/pastebin.js.git"
12+
},
13+
"keywords": [
14+
"pastebin",
15+
"paste",
16+
"api"
17+
],
18+
"author": "catte_",
19+
"license": "MIT",
20+
"bugs": {
21+
"url": "https://github.com/cAttte/pastebin.js/issues"
22+
},
23+
"homepage": "https://github.com/cAttte/pastebin.js#readme",
24+
"dependencies": {
25+
"node-fetch": "^2.6.0",
26+
"querystring": "^0.2.0",
27+
"xml2js": "^0.4.23"
28+
}
29+
}

src/index.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module.exports.PastebinClient = require("./struct/PastebinClient")
2+
module.exports.PastebinError = require("./struct/PastebinError")
3+
module.exports.Paste = require("./struct/Paste")
4+
module.exports.User = require("./struct/User")
5+
module.exports.PasteStore = require("./struct/stores/PasteStore")
6+
module.exports.UserStore = require("./struct/stores/UserStore")
7+
module.exports.UserPasteStore = require("./struct/stores/UserPasteStore")

src/struct/ClientUser.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
const User = require("./User")
2+
3+
/**
4+
* The Pastebin user of the logged in client.
5+
*/
6+
module.exports = class ClientUser extends User {
7+
/**
8+
* Data passed to the ClientUser constructor.
9+
* @typedef {Object} ClientUserData
10+
* @property {string} username The user's username
11+
* @property {string?} format The user's format setting
12+
* @property {Expiry?} expiry The user's expiry setting
13+
* @property {string} avatarURL The user's avatar URL
14+
* @property {Privacy?} privacy The user's privacy setting
15+
* @property {string?} website The user's website URL
16+
* @property {string?} email The user's website URL
17+
* @property {string?} location The user's location
18+
* @property {boolean} pro Whether the user is a PRO account or not
19+
*/
20+
21+
/**
22+
* @param {PastebinClient} client The client used to get this user
23+
* @param {ClientUserData} data
24+
*/
25+
constructor(client, data) {
26+
super(client)
27+
/**
28+
* The client used to get this user
29+
* @type {PastebinClient}
30+
*/
31+
this.client = client
32+
/**
33+
* The user's username
34+
* @type {string}
35+
*/
36+
this.username = data.username
37+
/**
38+
* The user's format setting
39+
* @type {Format?}
40+
*/
41+
this.format = data.format || null
42+
/**
43+
* The user's expiry setting
44+
* @type {Expiry?}
45+
*/
46+
this.expiry = data.expiry || null
47+
/**
48+
* The user's avatar URL
49+
* @type {string}
50+
*/
51+
this.avatarURL = data.avatarURL
52+
/**
53+
* The user's privacy setting
54+
* @type {Privacy}
55+
*/
56+
this.privacy = data.privacy
57+
/**
58+
* The user's website URL
59+
* @type {string?}
60+
*/
61+
this.website = data.website || null
62+
/**
63+
* The user's email
64+
* @type {string?}
65+
*/
66+
this.email = data.email || null
67+
/**
68+
* The user's location
69+
* @type {string?}
70+
*/
71+
this.location = data.location || null
72+
/**
73+
* Whether the user is a PRO account or not
74+
* @type {boolean}
75+
*/
76+
this.pro = data.pro
77+
/**
78+
* All of the user's cached pastes
79+
* @type {UserPasteStore}
80+
*/
81+
this.pastes = new UserPasteStore(client, this)
82+
}
83+
}

src/struct/DataResolvers.js

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
const PastebinError = require("./PastebinError")
2+
3+
module.exports = class Resolvers {
4+
constructor() { throw new PastebinError() }
5+
6+
/**
7+
* The content of a paste. If an object, it will be stringified as JSON. If a Buffer or a primitive value, it will be converted with `String()`
8+
* @typedef {*} ContentResolvable
9+
*/
10+
static resolveContent(value) {
11+
if (!value)
12+
throw new PastebinError("Paste content is invalid.")
13+
else if (typeof value !== "object" || value instanceof Buffer)
14+
value = String(value)
15+
else if (typeof value === "object")
16+
value = JSON.stringify(value)
17+
if (value.length > 512000)
18+
throw new PastebinError("Paste content must not exceed 512,000 characters.")
19+
return value
20+
}
21+
22+
static resolveTitle(value) {
23+
if (typeof value !== "string")
24+
throw new PastebinError("Paste title must be a string.")
25+
if (value.length > 255)
26+
throw new PastebinError("Paste title must not exceed 255 characters.")
27+
return value
28+
}
29+
30+
/**
31+
* A "format," which will be used for syntax highlighting. You can see the full list [here](https://pastebin.com/api#5).
32+
* @typedef {string} Format
33+
*/
34+
static resolveFormat(value) {
35+
const formats = ["4cs","6502acme","6502kickass","6502tasm","abap","actionscript","actionscript3","ada","aimms","algol68","apache","applescript","apt_sources","arduino","arm","asm","asp","asymptote","autoconf","autohotkey","autoit","avisynth","awk","bascomavr","bash","basic4gl","dos","bibtex","blitzbasic","b3d","bmx","bnf","boo","bf","c","c_winapi","c_mac","cil","csharp","cpp","cpp-winapi","cpp-qt","c_loadrunner","caddcl","cadlisp","ceylon","cfdg","chaiscript","chapel","clojure","klonec","klonecpp","cmake","cobol","coffeescript","cfm","css","cuesheet","d","dart","dcl","dcpu16","dcs","delphi","oxygene","diff","div","dot","e","ezt","ecmascript","eiffel","email","epc","erlang","euphoria","fsharp","falcon","filemaker","fo","f1","fortran","freebasic","freeswitch","gambas","gml","gdb","genero","genie","gettext","go","groovy","gwbasic","haskell","haxe","hicest","hq9plus","html4strict","html5","icon","idl","ini","inno","intercal","io","ispfpanel","j","java","java5","javascript","jcl","jquery","json","julia","kixtart","kotlin","latex","ldif","lb","lsl2","lisp","llvm","locobasic","logtalk","lolcode","lotusformulas","lotusscript","lscript","lua","m68k","magiksf","make","mapbasic","markdown","matlab","mirc","mmix","modula2","modula3","68000devpac","mpasm","mxml","mysql","nagios","netrexx","newlisp","nginx","nim","text","nsis","oberon2","objeck","objc","ocaml","ocaml-brief","octave","oorexx","pf","glsl","oobas","oracle11","oracle8","oz","parasail","parigp","pascal","pawn","pcre","per","perl","perl6","php","php-brief","pic16","pike","pixelbender","pli","plsql","postgresql","postscript","povray","powerbuilder","powershell","proftpd","progress","prolog","properties","providex","puppet","purebasic","pycon","python","pys60","q","qbasic","qml","rsplus","racket","rails","rbs","rebol","reg","rexx","robots","rpmspec","ruby","gnuplot","rust","sas","scala","scheme","scilab","scl","sdlbasic","smalltalk","smarty","spark","sparql","sqf","sql","standardml","stonescript","sclang","swift","systemverilog","tsql","tcl","teraterm","thinbasic","typoscript","unicon","uscript","upc","urbi","vala","vbnet","vbscript","vedit","verilog","vhdl","vim","visualprolog","vb","visualfoxpro","whitespace","whois","winbatch","xbasic","xml","xorg_conf","xpp","yaml","z80","zxbasic"]
36+
if (typeof value !== "string")
37+
throw new PastebinError("Paste format must be a string.")
38+
value = String.prototype.toLowerCase.call(value)
39+
if (!formats.includes(value))
40+
throw new PastebinError("Paste format must be a valid format.")
41+
return value
42+
}
43+
44+
/**
45+
* A privacy setting. Can be one of the following:
46+
* * `0` (or `"public"`)
47+
* * `1` (or `"unlisted"`)
48+
* * `2` (or `"private"`)
49+
* @typedef {(string|number)} Privacy
50+
*/
51+
static resolvePrivacy(value) {
52+
const privacyValues = ["public", "unlisted", "private"]
53+
if (typeof value !== "number" && typeof value !== "string")
54+
throw new PastebinError("Paste privacy must be a number or a string.")
55+
if (typeof value === "number" && ![0, 1, 2].includes(value))
56+
throw new PastebinError("As a number, paste privacy must be 0, 1, or 2.")
57+
if (typeof value === "string" && !privacyValues.includes(value.toLowerCase()))
58+
throw new PastebinError("As a string, paste privacy must be 'public', 'unlisted' or 'private'.")
59+
60+
if (typeof value === "string") return privacyValues.indexOf(value)
61+
else return value
62+
}
63+
64+
/**
65+
* An expiry setting. Can be one of the following:
66+
* * `"NEVER"` (or `"N"`)
67+
* * `"10 MINUTES"` (or `"10M"`)
68+
* * `"1 HOUR"` (or `"1H"`)
69+
* * `"1 DAY"` (or `"1D"`)
70+
* * `"1 WEEK"` (or `"1W"`)
71+
* * `"2 WEEKS"` (or `"2W"`)
72+
* * `"1 MONTH"` (or `"1M"`)
73+
* * `"6 MONTHS"` (or `"6M"`)
74+
* * `"1 YEAR"` (or `"1Y"`)
75+
* @typedef {(string|number)} Expiry
76+
*/
77+
static resolveExpiry(value) {
78+
const expiryValues = {
79+
"never": "n",
80+
"10 minutes": "10m",
81+
"1 hour": "1h",
82+
"1 day": "1d",
83+
"1 week": "1w",
84+
"2 weeks": "2w",
85+
"1 month": "1m",
86+
"6 months": "6m",
87+
"1 year": "1y"
88+
}
89+
if (typeof value !== "string")
90+
throw new PastebinError("Paste expiry must be a string.")
91+
value = value.toLowerCase()
92+
if (!Object.keys(expiryValues).includes(value) && !Object.values(expiryValues).includes(value))
93+
throw new PastebinError("Paste expiry must be 'n' (never), '10m', '1h', '1d', '1w', '2w', '1m', '6m', '1y', or their long equivalents.")
94+
if (Object.keys(expiryValues).includes(value))
95+
value = expiryValues[value]
96+
return value.toUpperCase()
97+
}
98+
}

src/struct/Paste.js

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
const PastebinClient = require("./PastebinClient")
2+
const PastebinError = require("./PastebinError")
3+
4+
/**
5+
* A Pastebin paste.
6+
*/
7+
module.exports = class Paste {
8+
/**
9+
* @param {PastebinClient} client The client used to get this paste
10+
* @param {Object} data
11+
* @param {string} data.key The key of the paste
12+
* @param {string?} data.title The title of this paste
13+
* @param {User?} data.author The author of this paste
14+
* @param {string?} data.content The content of the paste
15+
* @param {number?} data.size The length of the content of the paste
16+
* @param {Date?} data.date The date the paste was posted
17+
* @param {Format?} data.format The format of the paste
18+
* @param {Privacy?} data.privacy The privacy setting of the paste
19+
* @param {Expiry?} data.expiry The expiry time of the paste
20+
* @param {Date?} data.expiryDate The expiry date of the paste
21+
* @param {number?} data.hits The number of times anyone saw this paste
22+
*/
23+
constructor(client, data) {
24+
/**
25+
* The client used to get this paste
26+
* @type {PastebinClient}
27+
*/
28+
this.client = client
29+
/**
30+
* The key of this paste
31+
* @type {string}
32+
*/
33+
this.key = data.key
34+
/**
35+
* The title of this paste
36+
* @type {string?}
37+
*/
38+
this.title = data.title
39+
/**
40+
* The author of this paste
41+
* @type {User?}
42+
*/
43+
this.author = data.author
44+
/**
45+
* The content of this paste
46+
* @type {string?}
47+
*/
48+
this.content = data.content
49+
/**
50+
* The length of the content of this paste
51+
* @type {number?}
52+
*/
53+
this.size = data.size || (data.content || { length: null }).length
54+
/**
55+
* The date this paste was posted
56+
* @type {Date?}
57+
*/
58+
this.date = data.date
59+
/**
60+
* The format (syntax highlighting) of this paste
61+
* @type {Format?}
62+
*/
63+
this.format = data.format
64+
/**
65+
* The privacy setting of this paste
66+
* @type {Privacy?}
67+
*/
68+
this.privacy = data.privacy
69+
/**
70+
* The expiry time of this paste
71+
* @type {Expiry?}
72+
*/
73+
this.expiry = data.expiry
74+
/**
75+
* The expiry date of this paste
76+
* @type {Date?}
77+
*/
78+
this.expiryDate = data.expiryDate
79+
/**
80+
* The number of times anyone saw this paste
81+
* @type {number?}
82+
*/
83+
this.hits = data.hits
84+
/**
85+
* Whether the paste is deleted or not
86+
* @type {boolean}
87+
*/
88+
this.deleted = false
89+
}
90+
91+
/**
92+
* The URL of this paste
93+
* @type {string}
94+
*/
95+
get url() {
96+
return this.client.constructor.BASE_URL + this.key
97+
}
98+
99+
/**
100+
* Fetch the content of this paste and store it
101+
*/
102+
async fetch() {
103+
const { content } = await this.client.getPaste(this.key)
104+
this.content = content
105+
}
106+
107+
/**
108+
* Delete this paste
109+
*/
110+
async delete() {
111+
if (!this.client.credentials.apiKey)
112+
throw new PastebinError("API key is required to delete a paste.")
113+
if (!this.client.credentials.userKey)
114+
throw new PastebinError("User key is required to delete a paste.")
115+
const { error } = await this.client.constructor.post(this.client.constructor.POST_URL, {
116+
api_dev_key: this.client.credentials.apiKey,
117+
api_user_key: this.client.credentials.userKey,
118+
api_option: "delete",
119+
api_paste_key: this.key
120+
})
121+
if (error) switch (error) {
122+
case "invalid api_dev_key":
123+
throw new PastebinError("Invalid API key.")
124+
case "invalid api_user_key":
125+
throw new PastebinError("Invalid user key.")
126+
case "invalid permission to remove paste":
127+
throw new PastebinError("No permission to delete this paste.")
128+
default:
129+
throw new PastebinError(`Unknown error: ${error}.`)
130+
}
131+
this.deleted = true
132+
return this
133+
}
134+
}

0 commit comments

Comments
 (0)