proiectro 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Online Projects EU
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,349 @@
1
+ # proiectro
2
+
3
+ Official TypeScript/JavaScript SDK for the [Proiect.ro](https://proiect.ro) API.
4
+
5
+ Full type safety for every endpoint, request, and response.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install proiectro
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import { client, tenantOrgs, addSubtenant } from 'proiectro';
17
+
18
+ // Authenticate (baseUrl defaults to https://proiect.ro)
19
+ client.setConfig({
20
+ auth: () => 'your_api_key_here',
21
+ });
22
+
23
+ // Define your workspace
24
+ const workspace = { path: { tenant_path: 'my-workspace' } };
25
+
26
+ // List customers
27
+ const { data, error } = await tenantOrgs(workspace);
28
+
29
+ if (data) {
30
+ console.log('Customers:', data);
31
+ }
32
+ ```
33
+
34
+ ## Authentication
35
+
36
+ Create an API key in your workspace under **Settings > API Keys**. The SDK sends it as a Bearer token automatically.
37
+
38
+ ```typescript
39
+ import { client } from 'proiectro';
40
+
41
+ client.setConfig({
42
+ auth: () => 'your_api_key_here',
43
+ });
44
+ ```
45
+
46
+ The `auth` callback is called on every authenticated request. You can return the key from an environment variable, a secret manager, or any async source:
47
+
48
+ ```typescript
49
+ client.setConfig({
50
+ auth: () => process.env.PROIECTRO_API_KEY,
51
+ });
52
+ ```
53
+
54
+ To point at a different server (e.g. staging or self-hosted), override the `baseUrl`:
55
+
56
+ ```typescript
57
+ client.setConfig({
58
+ baseUrl: 'https://staging.proiect.ro',
59
+ auth: () => process.env.PROIECTRO_API_KEY,
60
+ });
61
+ ```
62
+
63
+ ## Workspace
64
+
65
+ Most API operations are scoped to a workspace (tenant). Define it once and spread it into every call:
66
+
67
+ ```typescript
68
+ const workspace = { path: { tenant_path: 'my-workspace' } };
69
+
70
+ await tenantOrgs(workspace);
71
+ await addSubtenant({ ...workspace, body: { name: 'Acme Corp' } });
72
+ await listProjects(workspace);
73
+ ```
74
+
75
+ A few operations are user-scoped (notifications, invitations) and don't need a workspace path.
76
+
77
+ ## Usage Examples
78
+
79
+ ### Customers
80
+
81
+ ```typescript
82
+ import {
83
+ tenantOrgs,
84
+ addSubtenant,
85
+ editSubtenant,
86
+ deleteSubtenant,
87
+ } from 'proiectro';
88
+
89
+ const workspace = { path: { tenant_path: 'my-workspace' } };
90
+
91
+ // List all customers
92
+ const { data: customers } = await tenantOrgs(workspace);
93
+
94
+ // Create a customer
95
+ const { data: created } = await addSubtenant({
96
+ ...workspace,
97
+ body: {
98
+ name: 'Acme Corp',
99
+ parent_id: 'org-uuid',
100
+ },
101
+ });
102
+
103
+ // Update a customer
104
+ await editSubtenant({
105
+ path: { tenant_path: 'my-workspace', subtenant_id: 'customer-uuid' },
106
+ body: { name: 'Acme Corporation' },
107
+ });
108
+
109
+ // Delete a customer
110
+ await deleteSubtenant({
111
+ path: { tenant_path: 'my-workspace', subtenant_id: 'customer-uuid' },
112
+ });
113
+ ```
114
+
115
+ ### Proposals
116
+
117
+ ```typescript
118
+ import {
119
+ addProposal,
120
+ editProposal,
121
+ changeProposalStage,
122
+ orgProposals,
123
+ } from 'proiectro';
124
+
125
+ const workspace = { path: { tenant_path: 'my-workspace' } };
126
+
127
+ // List proposals for a customer
128
+ const { data: proposals } = await orgProposals({
129
+ path: { tenant_path: 'my-workspace', org_id: 'customer-uuid' },
130
+ });
131
+
132
+ // Create a proposal
133
+ await addProposal({
134
+ ...workspace,
135
+ body: {
136
+ name: 'Q1 Consulting',
137
+ parent_id: 'customer-uuid',
138
+ funnel_id: 'funnel-uuid',
139
+ },
140
+ });
141
+
142
+ // Move a proposal to the next stage
143
+ await changeProposalStage({
144
+ ...workspace,
145
+ body: {
146
+ proposal_id: 'proposal-uuid',
147
+ stage_id: 'next-stage-uuid',
148
+ },
149
+ });
150
+ ```
151
+
152
+ ### Projects & Work Items
153
+
154
+ ```typescript
155
+ import {
156
+ listProjects,
157
+ projectWorkItems,
158
+ addWorkItem,
159
+ updateWorkItemStatus,
160
+ } from 'proiectro';
161
+
162
+ const workspace = { path: { tenant_path: 'my-workspace' } };
163
+
164
+ // List all projects
165
+ const { data: projects } = await listProjects(workspace);
166
+
167
+ // Get work items for a project
168
+ const { data: workItems } = await projectWorkItems({
169
+ path: { tenant_path: 'my-workspace', project_id: 'project-uuid' },
170
+ });
171
+
172
+ // Create a work item
173
+ await addWorkItem({
174
+ ...workspace,
175
+ body: {
176
+ name: 'Design mockups',
177
+ project_id: 'project-uuid',
178
+ work_item_type_id: 'type-uuid',
179
+ },
180
+ });
181
+
182
+ // Update work item status
183
+ await updateWorkItemStatus({
184
+ ...workspace,
185
+ body: {
186
+ work_item_id: 'work-item-uuid',
187
+ status: 'in_progress',
188
+ },
189
+ });
190
+ ```
191
+
192
+ ### Payments
193
+
194
+ ```typescript
195
+ import {
196
+ addPayment,
197
+ markPaymentPaid,
198
+ } from 'proiectro';
199
+
200
+ const workspace = { path: { tenant_path: 'my-workspace' } };
201
+
202
+ // Create a payment
203
+ await addPayment({
204
+ ...workspace,
205
+ body: {
206
+ proposal_id: 'proposal-uuid',
207
+ amount: '5000.00',
208
+ currency: 'EUR',
209
+ due_date: '2026-03-15',
210
+ },
211
+ });
212
+
213
+ // Mark a payment as paid
214
+ await markPaymentPaid({
215
+ ...workspace,
216
+ body: { payment_id: 'payment-uuid' },
217
+ });
218
+ ```
219
+
220
+ ### Tags
221
+
222
+ ```typescript
223
+ import {
224
+ tenantTags,
225
+ addTag,
226
+ tagOrg,
227
+ untagOrg,
228
+ } from 'proiectro';
229
+
230
+ const workspace = { path: { tenant_path: 'my-workspace' } };
231
+
232
+ // List all tags
233
+ const { data: tags } = await tenantTags(workspace);
234
+
235
+ // Create a tag
236
+ await addTag({
237
+ ...workspace,
238
+ body: { name: 'VIP', color: '#ff0000' },
239
+ });
240
+
241
+ // Tag a customer
242
+ await tagOrg({
243
+ ...workspace,
244
+ body: { org_id: 'customer-uuid', tag_id: 'tag-uuid' },
245
+ });
246
+ ```
247
+
248
+ ### Support Requests
249
+
250
+ ```typescript
251
+ import {
252
+ addInternalSupportRequest,
253
+ mySupportRequests,
254
+ } from 'proiectro';
255
+
256
+ const workspace = { path: { tenant_path: 'my-workspace' } };
257
+
258
+ // List my support requests
259
+ const { data: tickets } = await mySupportRequests(workspace);
260
+
261
+ // Create a support request
262
+ await addInternalSupportRequest({
263
+ ...workspace,
264
+ body: {
265
+ title: 'Server configuration issue',
266
+ description: 'Need help with DNS setup',
267
+ type_id: 'type-uuid',
268
+ severity_id: 'severity-uuid',
269
+ },
270
+ });
271
+ ```
272
+
273
+ ### Team
274
+
275
+ ```typescript
276
+ import {
277
+ tenantTeam,
278
+ inviteToTeam,
279
+ } from 'proiectro';
280
+
281
+ const workspace = { path: { tenant_path: 'my-workspace' } };
282
+
283
+ // List team members
284
+ const { data: team } = await tenantTeam(workspace);
285
+
286
+ // Invite someone to the team
287
+ await inviteToTeam({
288
+ ...workspace,
289
+ body: { email: 'colleague@example.com' },
290
+ });
291
+ ```
292
+
293
+ ## Error Handling
294
+
295
+ Every SDK function returns `{ data, error, request, response }`:
296
+
297
+ ```typescript
298
+ const { data, error, response } = await tenantOrgs({
299
+ path: { tenant_path: 'my-workspace' },
300
+ });
301
+
302
+ if (error) {
303
+ console.error('Status:', response?.status);
304
+ console.error('Error:', error);
305
+ } else {
306
+ console.log('Success:', data);
307
+ }
308
+ ```
309
+
310
+ ## Interceptors
311
+
312
+ Add request/response interceptors for logging, retries, or custom headers:
313
+
314
+ ```typescript
315
+ import { client } from 'proiectro';
316
+
317
+ // Log all requests
318
+ client.interceptors.request.use((request) => {
319
+ console.log(`${request.method} ${request.url}`);
320
+ return request;
321
+ });
322
+
323
+ // Log all responses
324
+ client.interceptors.response.use((response) => {
325
+ console.log(`${response.status} ${response.url}`);
326
+ return response;
327
+ });
328
+ ```
329
+
330
+ ## TypeScript
331
+
332
+ Every request and response is fully typed. Your editor will autocomplete path parameters, body fields, and response shapes:
333
+
334
+ ```typescript
335
+ import type { OutputTenantInfo, AddSubtenantData } from 'proiectro';
336
+ ```
337
+
338
+ ## Requirements
339
+
340
+ - Node.js >= 18 (uses native `fetch`)
341
+ - TypeScript >= 5.0 (optional, works with plain JavaScript too)
342
+
343
+ ## API Documentation
344
+
345
+ Full API reference is available at [proiect.ro/api/v1/docs](https://proiect.ro/api/v1/docs).
346
+
347
+ ## License
348
+
349
+ MIT