freelancer-kit 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +142 -0
- package/examples/post_bid.js +21 -0
- package/package.json +3 -1
- package/src/classes/Bid.js +82 -0
- package/src/index.js +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Freelancer Kit 🚀
|
|
2
|
+
|
|
3
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
|
+
[](https://www.javascript.com/)
|
|
5
|
+
|
|
6
|
+
This repository provides a comprehensive JavaScript toolkit for interacting with the Freelancer API. Designed for Node.js environments, it simplifies common tasks such as authentication, profile management, and project searching.
|
|
7
|
+
|
|
8
|
+
## Features ✨
|
|
9
|
+
|
|
10
|
+
* **Authentication:** Securely authenticate with the Freelancer API using OAuth 2.0.
|
|
11
|
+
* **Token Management:** Easily handle access and refresh tokens for persistent API access.
|
|
12
|
+
* **Profile Retrieval:** Fetch and manage your Freelancer profile information.
|
|
13
|
+
* **Project Searching:** Efficiently search for projects based on various criteria.
|
|
14
|
+
* **Create Bid:** you can create a bid.
|
|
15
|
+
|
|
16
|
+
## Installation 📥
|
|
17
|
+
|
|
18
|
+
You can install `freelancer-kit` directly from npm:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install freelancer-kit
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Alternatively, if you are developing locally or wish to contribute, you can clone the repository and install dependencies:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
git clone https://github.com/Murtesa-developer/freelancer-kit.git
|
|
28
|
+
cd freelancer-kit
|
|
29
|
+
npm install
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Usage Examples 💡
|
|
33
|
+
|
|
34
|
+
### Authentication Example
|
|
35
|
+
|
|
36
|
+
```javascript
|
|
37
|
+
const { FreelancerAuth } = require("../src/index");
|
|
38
|
+
|
|
39
|
+
(async () => {
|
|
40
|
+
const clientId = "app_id";
|
|
41
|
+
const clientSecret = "client_secret";
|
|
42
|
+
const redirectUri = "https://example.com/callback";
|
|
43
|
+
const sandbox = true;
|
|
44
|
+
|
|
45
|
+
const flags = {
|
|
46
|
+
messaging: true,
|
|
47
|
+
project_create: true,
|
|
48
|
+
project_manage: false,
|
|
49
|
+
contest_create: false,
|
|
50
|
+
contest_manage: false,
|
|
51
|
+
user_information: true,
|
|
52
|
+
location_tracking_create: false,
|
|
53
|
+
location_tracking_view: false,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const auth = new FreelancerAuth({ clientId, clientSecret, redirectUri, sandbox, flags });
|
|
57
|
+
|
|
58
|
+
const authUrl = auth.generateAuthLink();
|
|
59
|
+
console.log("Open this link in your browser to authorize the app:");
|
|
60
|
+
console.log(authUrl);
|
|
61
|
+
const code = await FreelancerAuth.askCode("Enter the code you received: ");
|
|
62
|
+
|
|
63
|
+
const tokens = await auth.exchangeCode(code.trim());
|
|
64
|
+
|
|
65
|
+
console.log("Access Token:", tokens.access_token);
|
|
66
|
+
console.log("Refresh Token:", tokens.refresh_token);
|
|
67
|
+
})();
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Self Profile Example
|
|
71
|
+
|
|
72
|
+
```javascript
|
|
73
|
+
const { SelfProfile } = require("../src/index");
|
|
74
|
+
(async () => {
|
|
75
|
+
try {
|
|
76
|
+
const profile = new SelfProfile({
|
|
77
|
+
accessToken: "access_token",
|
|
78
|
+
sandbox: true
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const res = await profile.getMyProfile({
|
|
82
|
+
avatar: true,
|
|
83
|
+
display_info: true,
|
|
84
|
+
profile_description: true,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
console.log(res);
|
|
88
|
+
} catch (err) {
|
|
89
|
+
console.error("Error:", err.message);
|
|
90
|
+
}
|
|
91
|
+
})();
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Search Projects Example
|
|
95
|
+
|
|
96
|
+
```javascript
|
|
97
|
+
const { SearchProjects } = require("../src/index");
|
|
98
|
+
|
|
99
|
+
const projects = new SearchProjects({
|
|
100
|
+
accessToken: "access_token",
|
|
101
|
+
sandbox: true,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
(async () => {
|
|
105
|
+
try {
|
|
106
|
+
const result = await projects.search({
|
|
107
|
+
query: "software",
|
|
108
|
+
project_types: ["fixed"],
|
|
109
|
+
min_price: 50,
|
|
110
|
+
max_price: 1000,
|
|
111
|
+
jobs: [1, 2, 3], // job id
|
|
112
|
+
languages: ["en"],
|
|
113
|
+
project_statuses: ["active"],
|
|
114
|
+
sort_field: "time_updated",
|
|
115
|
+
limit: 10,
|
|
116
|
+
full_description: true,
|
|
117
|
+
user_details: true,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
console.log(result.result.projects);
|
|
121
|
+
} catch (err) {
|
|
122
|
+
console.error("Error:", err.details || err.message);
|
|
123
|
+
}
|
|
124
|
+
})();
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Contributing 🤝
|
|
128
|
+
|
|
129
|
+
We welcome contributions to `freelancer-kit`
|
|
130
|
+
## License 📜
|
|
131
|
+
|
|
132
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
133
|
+
|
|
134
|
+
## API Documentation 📚
|
|
135
|
+
|
|
136
|
+
The `freelancer-kit` library exposes several classes to interact with the Freelancer API.
|
|
137
|
+
|
|
138
|
+
### `FreelancerAuth` 🔐
|
|
139
|
+
|
|
140
|
+
Handles authentication and token management.
|
|
141
|
+
|
|
142
|
+
---
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const { Bid } = require("../src/index");
|
|
2
|
+
|
|
3
|
+
(async () => {
|
|
4
|
+
try {
|
|
5
|
+
const bid = new Bid({
|
|
6
|
+
accessToken: "access_token",
|
|
7
|
+
sandbox: true,
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const res = await bid.placeBid("project_id", {
|
|
11
|
+
amount: "how much money",
|
|
12
|
+
period: "how many days",
|
|
13
|
+
description: "description",
|
|
14
|
+
milestone_percentage: "milestone percentage",
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
console.log(`SUCCESS: Bid placed successfully (ID: ${res.result.id})`);
|
|
18
|
+
} catch (err) {
|
|
19
|
+
console.error(`FAILED: ${err.message}`);
|
|
20
|
+
}
|
|
21
|
+
})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "freelancer-kit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Unofficial Node.js toolkit for integrating with the Freelancer.com API",
|
|
5
5
|
"author": "MURTESA",
|
|
6
6
|
"license": "MIT",
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
"freelancer",
|
|
10
10
|
"freelancer-kit",
|
|
11
11
|
"freelancer-api",
|
|
12
|
+
"freelancer-client",
|
|
13
|
+
"freelance",
|
|
12
14
|
"nodejs",
|
|
13
15
|
"sdk",
|
|
14
16
|
"client",
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const fetch = require("node-fetch");
|
|
2
|
+
|
|
3
|
+
class Bid {
|
|
4
|
+
constructor({ accessToken, sandbox = false }) {
|
|
5
|
+
if (!accessToken) {
|
|
6
|
+
throw new Error("accessToken is required");
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
this.accessToken = accessToken;
|
|
10
|
+
this.sandbox = sandbox;
|
|
11
|
+
|
|
12
|
+
this.projectBaseUrl = sandbox
|
|
13
|
+
? "https://www.freelancer-sandbox.com/api/projects/0.1"
|
|
14
|
+
: "https://www.freelancer.com/api/projects/0.1";
|
|
15
|
+
|
|
16
|
+
this.userBaseUrl = sandbox
|
|
17
|
+
? "https://www.freelancer-sandbox.com/api/users/0.1"
|
|
18
|
+
: "https://www.freelancer.com/api/users/0.1";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async request(method, url, body = null) {
|
|
22
|
+
const options = {
|
|
23
|
+
method,
|
|
24
|
+
headers: {
|
|
25
|
+
"Content-Type": "application/json",
|
|
26
|
+
"freelancer-oauth-v1": this.accessToken,
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
if (body) {
|
|
31
|
+
options.body = JSON.stringify(body);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const res = await fetch(url, options);
|
|
35
|
+
const data = await res.json();
|
|
36
|
+
|
|
37
|
+
if (!res.ok) {
|
|
38
|
+
const error = new Error(data?.message || "Freelancer API Error");
|
|
39
|
+
error.status = res.status;
|
|
40
|
+
error.details = data;
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return data;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async getMyUserId() {
|
|
48
|
+
const data = await this.request(
|
|
49
|
+
"GET",
|
|
50
|
+
`${this.userBaseUrl}/self/`
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
if (!data?.result?.id) {
|
|
54
|
+
throw new Error("Failed to retrieve self user ID");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return Number(data.result.id);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async placeBid(projectId, bidData = {}) {
|
|
61
|
+
const bidderId = await this.getMyUserId();
|
|
62
|
+
|
|
63
|
+
const payload = {
|
|
64
|
+
project_id: Number(projectId),
|
|
65
|
+
bidder_id: bidderId,
|
|
66
|
+
amount: Number(bidData.amount),
|
|
67
|
+
period: Number(bidData.period),
|
|
68
|
+
description: String(bidData.description || ""),
|
|
69
|
+
milestone_percentage: bidData.milestone_percentage ?? 0,
|
|
70
|
+
sponsored: Boolean(bidData.sponsored),
|
|
71
|
+
highlighted: Boolean(bidData.highlighted),
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
return this.request(
|
|
75
|
+
"POST",
|
|
76
|
+
`${this.projectBaseUrl}/bids/`,
|
|
77
|
+
payload
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
module.exports = Bid;
|