Repository navigation
Expand file tree
/
Copy pathfastControllerApi.js
More file actions
171 lines (154 loc) · 5.97 KB
/
Copy pathfastControllerApi.js
File metadata and controls
171 lines (154 loc) · 5.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import {SessionClient} from 'https://bassmastacod.github.io/web-snippets/apiClient.js';
/**
* Generic base API class that provides standard CRUD operations
* Extends SessionClient with common patterns found across API services
*/
export class FastControllerApi extends SessionClient {
/**
* Find records with optional criteria, ordering, and pagination
* @param {Object} [criteria] - Search criteria as key-value pairs
* @param {string} [xOrderBy] - Field to order by (prefix with ! for descending)
* @param {number} [xPerPage] - Number of items per page
* @param {number} [xPage] - Page number (1 for first page)
* @param {Function} [onSuccess] - Callback executed on successfully receiving a response
*/
async find(criteria = {}, xOrderBy, xPerPage, xPage, onSuccess) {
const searchParams = new URLSearchParams();
for (const [key, value] of Object.entries(criteria)) {
if (value !== undefined && value !== null) {
searchParams.append(key, value);
}
}
const headers = {};
if (xPage) {
headers['x-page'] = xPage.toString();
}
if (xPerPage) {
headers['x-per-page'] = xPerPage.toString();
}
if (xOrderBy) {
headers['x-order'] = xOrderBy;
}
let queryStart = ''
let query = searchParams.toString();
if (query) {
queryStart = this.baseUrl.includes('?') ? '&' : '?';
}
return this.request('GET', queryStart + query, null, headers, {}, onSuccess);
}
/**
* Create a new record
* @param {Object} [data] - Data to create
*/
async create(data) {
return this.post('', data);
}
/**
* Upsert (create or update) a record
* @param {Object} data - Data to upsert
*/
async upsert(data) {
return this.put('', data);
}
/**
* Fetch a single record by primary key
* @param {string|number} pk - Primary key value
*/
async fetch(pk) {
return this.get(`/${pk}`);
}
/**
* Update a record (full update)
* @param {string|number} pk - Primary key value
* @param {Object} data - Data to update (must contain primary key)
*/
async update(pk, data) {
return this.put(`/${pk}`, data);
}
/**
* Modify a record (partial update)
* @param {string|number} pk - Primary key value
* @param {Object} partialData - Partial data to update
*/
async modify(pk, partialData) {
return this.patch(`/${pk}`, partialData);
}
/**
* Remove a record
* @param {string|number} pk - Primary key value
*/
async remove(pk) {
return this.delete(`/${pk}`);
}
/**
* Rename/change primary key of a record
* @param {string|number} pk - Current primary key value
* @param {string|number} newPk - New primary key value
*/
async rename(pk, newPk) {
return this.post(`/${pk}/rename`, newPk);
}
/**
* Merge two records into one
* @param {string|number} sourcePk - Primary key value of the source record
* @param {string|number} destPk - Primary key value of the destination record
*/
async merge(sourcePk, destPk) {
return this.post(`/${sourcePk}/merge/${destPk}`);
}
/**
* Get all records (alias for find with no criteria)
*/
async all() {
return this.find();
}
/**
* Get a specific page of records
* @param {number} pageNumber - Page number (1 for first page)
* @param {Object} [criteria] - Search criteria as key-value pairs
* @param {number} [perPage] - Number of items per page
* @param {string} [orderBy] - Field to order by (prefix with ! for descending)
* @returns {Promise<{results: Array, totalCount: (string|null)}>} - A promise that resolves with an object containing:
* - results: An array of records for the requested page.
* - totalCount: The total number of records as a string, or null if not provided.
*/
async getPage(pageNumber, criteria, perPage = 20, orderBy) {
return this.find(criteria, orderBy, perPage, pageNumber, async response => {
const results = response.status === 204 ? [] : await response.json();
const totalCount = response.headers.get('x-total-count');
return {results, totalCount}
})
}
/**
* Get the total count of records matching the criteria
* @param {Object} [criteria] - Search criteria as key-value pairs
* @returns {Promise<string|null>} - A promise that resolves to the total count of records as a string, or null if not provided
*/
async count(criteria) {
return this.find(criteria, null, 1, 1, async response => {
return response.headers.get('x-total-count')
})
}
/**
* Get a single item (first result) from the query
* @param {Object} [criteria] - Search criteria as key-value pairs
* @param {string} [orderBy] - Field to order by (prefix with ! for descending)
* @param {number} [pageNumber] - Page number (1 for first page)
*/
async getSingle(criteria, orderBy, pageNumber) {
const results = await this.find(criteria, orderBy, 1, pageNumber);
return Array.isArray(results) && results.length > 0 ? results[0] : null;
}
/**
* Find records with a limited number of results
* @param {Object} criteria - Search criteria as key-value pairs
* @param {number} limit - Limit on the number of results per page
* @param {string} [orderBy] - Field to order by (prefix with ! for descending)
* @returns {Promise<{results: Array, totalCount: (string|null)}>} - A promise that resolves with an object containing:
* - results: An array of records for the requested limit.
* - totalCount: The total number of records as a string, or null if not provided.
*/
async limitFind(criteria, limit, orderBy) {
return this.getPage(1, criteria, limit, orderBy);
}
}