septor-store 0.0.6 → 1.0.1
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 +40 -1
- package/dist/index.cjs +22 -5
- package/dist/index.d.cts +24 -17
- package/dist/index.d.ts +24 -17
- package/dist/index.js +22 -5
- package/package.json +35 -39
package/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# Vue 3 + TypeScript + Vite
|
|
2
|
+
|
|
2
3
|
<p align="center">
|
|
3
4
|
<img src="https://github.com/ssengedonazil/septor-store-testing/blob/POM/assets/septor-store.png?raw=true" alt="Septor Logo" width="180" />
|
|
4
5
|
</p>
|
|
@@ -22,6 +23,7 @@ septor-store is a structured and scalable state management solution built on top
|
|
|
22
23
|
| Post + Submit Support | Easily manage POST data and track responses |
|
|
23
24
|
| Flexible Callbacks | Use custom callbacks on state update |
|
|
24
25
|
| Loading & Error States | Built-in support for loading/errors |
|
|
26
|
+
| clean all the state against the store id
|
|
25
27
|
|
|
26
28
|
- Automatic API Call Queue Management Prevents multiple simultaneous calls to the same endpoint by tracking ongoing requests.
|
|
27
29
|
- Session Storage Caching Support Optionally caches API responses in sessionStorage for faster retrieval and offline resilience.
|
|
@@ -266,7 +268,44 @@ const handleSubmit = async () => {
|
|
|
266
268
|
</script>
|
|
267
269
|
|
|
268
270
|
```
|
|
271
|
+
|
|
272
|
+
### Usage **EXAMPLE 3** Remove all the data stored(cleare)🤭
|
|
273
|
+
|
|
274
|
+
```
|
|
275
|
+
Note: StateClean this activates the opearation
|
|
276
|
+
|
|
277
|
+
const usePomStore = pomPinia('myCustomStoreId',null,{StateClean:true});
|
|
278
|
+
const pomStore = usePomStore();
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
const handleSubmit = async () => {
|
|
282
|
+
const config = {
|
|
283
|
+
StateStore: 'packageList',
|
|
284
|
+
reqs: {
|
|
285
|
+
url: '/api/packagelist', //call your endpoint
|
|
286
|
+
method: 'post',
|
|
287
|
+
data: user.value,
|
|
288
|
+
},
|
|
289
|
+
reload: true,
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const res = await pomStore.stateGenaratorApi(config, (oldData) => {
|
|
293
|
+
console.log('Previous post result if any:', oldData)
|
|
294
|
+
})
|
|
295
|
+
result.value = res
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
pomStore.WipeStates(stateId) // remove just a paticular id (eg packageList)
|
|
299
|
+
pomStore.WipeStates() // remove all the states
|
|
300
|
+
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
🤝 Contributing and Feedback
|
|
304
|
+
We welcome all contributions and feedback to improve septor-store!
|
|
305
|
+
If you encounter any bugs, have suggestions, or want to contribute,
|
|
306
|
+
please open an issue or submit a pull request:
|
|
307
|
+
👉 Report Issues or Suggestions : <https://github.com/ssengedonazil/septor-store-testing>
|
|
308
|
+
|
|
269
309
|
If you find this package useful, consider supporting me:
|
|
270
310
|
|
|
271
311
|
[](https://ko-fi.com/ssengendonazil)
|
|
272
|
-
|
package/dist/index.cjs
CHANGED
|
@@ -159,8 +159,10 @@ function getBearerToken() {
|
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
// src/StoreManager/pomStateManagement.js
|
|
162
|
-
function createPomStore(piniaStore = "7286204094", callBack = null) {
|
|
162
|
+
function createPomStore(piniaStore = "7286204094", callBack = null, ds = { StateClean: 0 }) {
|
|
163
163
|
const storeId = "POM" + piniaStore;
|
|
164
|
+
const StateNameUsedSoferList = "septor-store-collection";
|
|
165
|
+
;
|
|
164
166
|
const piniaData = (0, import_pinia.defineStore)(storeId, {
|
|
165
167
|
state: () => {
|
|
166
168
|
const StateObjectsContainer = {
|
|
@@ -228,21 +230,36 @@ function createPomStore(piniaStore = "7286204094", callBack = null) {
|
|
|
228
230
|
sessionStorage.removeItem(dataResponseName);
|
|
229
231
|
}
|
|
230
232
|
if (mStore == null ? void 0 : mStore.mUse) {
|
|
231
|
-
const thisData = JSON.parse(
|
|
232
|
-
JSON.parse(sessionStorage.getItem(dataResponseName) || {})
|
|
233
|
-
);
|
|
233
|
+
const thisData = JSON.parse(JSON.parse(sessionStorage.getItem(dataResponseName) || {}));
|
|
234
234
|
return thisData;
|
|
235
235
|
}
|
|
236
236
|
} catch (error) {
|
|
237
237
|
}
|
|
238
238
|
return this[dataResponseName];
|
|
239
239
|
},
|
|
240
|
-
|
|
240
|
+
WipeStates(storeKeyToRemove = null) {
|
|
241
|
+
const sptStateData = localStorage.getItem(StateNameUsedSoferList) ?? "{}";
|
|
242
|
+
let previousState = JSON.parse(sptStateData);
|
|
243
|
+
if (storeKeyToRemove)
|
|
244
|
+
delete previousState[storeKeyToRemove];
|
|
245
|
+
else
|
|
246
|
+
previousState = {};
|
|
247
|
+
const regroup = JSON.stringify(previousState);
|
|
248
|
+
localStorage.setItem(StateNameUsedSoferList, regroup);
|
|
249
|
+
},
|
|
250
|
+
async stateGenaratorApi(dd = { reload: true, StateStore: "", reqs: {}, time: 0, pagnated: false, mStore: { mUse: 0, reset: 0 } }, fasterDataCollection = null) {
|
|
241
251
|
this.Loading = true;
|
|
242
252
|
const { reload, StateStore, reqs, time, pagnated, mStore } = dd;
|
|
243
253
|
const callApi = JSON.stringify(reqs);
|
|
244
254
|
const StateVariable = await this.parseData(StateStore, mStore);
|
|
245
255
|
this[StateStore] = StateVariable ?? [];
|
|
256
|
+
if (ds == null ? void 0 : ds.StateClean) {
|
|
257
|
+
const sptStateData = localStorage.getItem(StateNameUsedSoferList) ?? "{}";
|
|
258
|
+
const previousState = JSON.parse(sptStateData);
|
|
259
|
+
const stateKey = typeof StateStore === "string" ? StateStore : "septore-store-";
|
|
260
|
+
const regroup = JSON.stringify({ ...previousState, [storeId + "(-_+_-)" + stateKey]: StateStore });
|
|
261
|
+
localStorage.setItem(StateNameUsedSoferList, regroup);
|
|
262
|
+
}
|
|
246
263
|
if (this.StateValue[StateStore]) {
|
|
247
264
|
this.StateValue[StateStore] = false;
|
|
248
265
|
this[StateStore] = false;
|
package/dist/index.d.cts
CHANGED
|
@@ -118,9 +118,9 @@ function getBearerToken() {
|
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
function createPomStore( piniaStore = "7286204094", callBack=null) {
|
|
121
|
+
function createPomStore( piniaStore = "7286204094", callBack=null,ds={StateClean:0}) {
|
|
122
122
|
const storeId = "POM" + piniaStore;
|
|
123
|
-
const piniaData = defineStore(storeId, {
|
|
123
|
+
const StateNameUsedSoferList = "septor-store-collection"; const piniaData = defineStore(storeId, {
|
|
124
124
|
state: () => {
|
|
125
125
|
const StateObjectsContainer = {
|
|
126
126
|
CheckQueriesInQue: {},
|
|
@@ -137,8 +137,7 @@ function createPomStore( piniaStore = "7286204094", callBack=null) {
|
|
|
137
137
|
/**
|
|
138
138
|
make data basing on state TagetState this acts as a clusure in ()() read about it
|
|
139
139
|
store.stateItems(key1) usage to ge the ge
|
|
140
|
-
|
|
141
|
-
*/
|
|
140
|
+
**/
|
|
142
141
|
return (state[TagetState] = state[TagetState]);
|
|
143
142
|
},
|
|
144
143
|
|
|
@@ -173,13 +172,7 @@ function createPomStore( piniaStore = "7286204094", callBack=null) {
|
|
|
173
172
|
return new Promise((r) => setTimeout(r, timer));
|
|
174
173
|
},
|
|
175
174
|
|
|
176
|
-
async CallApiData(
|
|
177
|
-
StateStore,
|
|
178
|
-
callApi,
|
|
179
|
-
dataParams,
|
|
180
|
-
pagnated ,
|
|
181
|
-
mStore={}
|
|
182
|
-
) {
|
|
175
|
+
async CallApiData( StateStore, callApi, dataParams, pagnated , mStore={} ) {
|
|
183
176
|
if (!this.CheckQueriesInQue[callApi]) {
|
|
184
177
|
this.CheckQueriesInQue[callApi] = callApi;
|
|
185
178
|
let [res] = await Promise.all([
|
|
@@ -214,23 +207,37 @@ function createPomStore( piniaStore = "7286204094", callBack=null) {
|
|
|
214
207
|
}
|
|
215
208
|
|
|
216
209
|
if (mStore?.mUse) {
|
|
217
|
-
const thisData = JSON.parse(
|
|
218
|
-
JSON.parse(sessionStorage.getItem(dataResponseName) || {})
|
|
219
|
-
);
|
|
220
|
-
|
|
210
|
+
const thisData = JSON.parse(JSON.parse(sessionStorage.getItem(dataResponseName) || {}));
|
|
221
211
|
return thisData;
|
|
222
212
|
}
|
|
223
213
|
} catch (error) {}
|
|
224
214
|
|
|
225
215
|
return this[dataResponseName];
|
|
226
216
|
},
|
|
227
|
-
|
|
217
|
+
WipeStates(storeKeyToRemove=null){
|
|
218
|
+
const sptStateData = localStorage.getItem(StateNameUsedSoferList) ?? "{}";
|
|
219
|
+
let previousState = JSON.parse(sptStateData);
|
|
220
|
+
if (storeKeyToRemove)
|
|
221
|
+
delete previousState[storeKeyToRemove];
|
|
222
|
+
else
|
|
223
|
+
previousState={};
|
|
224
|
+
|
|
225
|
+
const regroup = JSON.stringify(previousState);
|
|
226
|
+
localStorage.setItem(StateNameUsedSoferList, regroup);
|
|
227
|
+
},
|
|
228
|
+
async stateGenaratorApi(dd = { reload: true, StateStore: "", reqs: {}, time: 0, pagnated: false, mStore: { mUse: 0,reset:0 },},fasterDataCollection=null) {
|
|
228
229
|
this.Loading = true;
|
|
229
230
|
const { reload, StateStore, reqs, time, pagnated, mStore } = dd;
|
|
230
231
|
const callApi = JSON.stringify(reqs);
|
|
231
232
|
const StateVariable = await this.parseData(StateStore, mStore);
|
|
232
233
|
this[StateStore] = StateVariable ?? [];
|
|
233
|
-
|
|
234
|
+
if (ds?.StateClean) {
|
|
235
|
+
const sptStateData =localStorage.getItem(StateNameUsedSoferList) ?? "{}";
|
|
236
|
+
const previousState = JSON.parse(sptStateData);
|
|
237
|
+
const stateKey = typeof StateStore === "string" ? StateStore : "septore-store-";
|
|
238
|
+
const regroup = JSON.stringify({...previousState,[storeId + "(-_+_-)" + stateKey]: StateStore,});
|
|
239
|
+
localStorage.setItem(StateNameUsedSoferList, regroup);
|
|
240
|
+
}
|
|
234
241
|
if (this.StateValue[StateStore]) {
|
|
235
242
|
/**
|
|
236
243
|
* dynamically lets create the state store
|
package/dist/index.d.ts
CHANGED
|
@@ -118,9 +118,9 @@ function getBearerToken() {
|
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
function createPomStore( piniaStore = "7286204094", callBack=null) {
|
|
121
|
+
function createPomStore( piniaStore = "7286204094", callBack=null,ds={StateClean:0}) {
|
|
122
122
|
const storeId = "POM" + piniaStore;
|
|
123
|
-
const piniaData = defineStore(storeId, {
|
|
123
|
+
const StateNameUsedSoferList = "septor-store-collection"; const piniaData = defineStore(storeId, {
|
|
124
124
|
state: () => {
|
|
125
125
|
const StateObjectsContainer = {
|
|
126
126
|
CheckQueriesInQue: {},
|
|
@@ -137,8 +137,7 @@ function createPomStore( piniaStore = "7286204094", callBack=null) {
|
|
|
137
137
|
/**
|
|
138
138
|
make data basing on state TagetState this acts as a clusure in ()() read about it
|
|
139
139
|
store.stateItems(key1) usage to ge the ge
|
|
140
|
-
|
|
141
|
-
*/
|
|
140
|
+
**/
|
|
142
141
|
return (state[TagetState] = state[TagetState]);
|
|
143
142
|
},
|
|
144
143
|
|
|
@@ -173,13 +172,7 @@ function createPomStore( piniaStore = "7286204094", callBack=null) {
|
|
|
173
172
|
return new Promise((r) => setTimeout(r, timer));
|
|
174
173
|
},
|
|
175
174
|
|
|
176
|
-
async CallApiData(
|
|
177
|
-
StateStore,
|
|
178
|
-
callApi,
|
|
179
|
-
dataParams,
|
|
180
|
-
pagnated ,
|
|
181
|
-
mStore={}
|
|
182
|
-
) {
|
|
175
|
+
async CallApiData( StateStore, callApi, dataParams, pagnated , mStore={} ) {
|
|
183
176
|
if (!this.CheckQueriesInQue[callApi]) {
|
|
184
177
|
this.CheckQueriesInQue[callApi] = callApi;
|
|
185
178
|
let [res] = await Promise.all([
|
|
@@ -214,23 +207,37 @@ function createPomStore( piniaStore = "7286204094", callBack=null) {
|
|
|
214
207
|
}
|
|
215
208
|
|
|
216
209
|
if (mStore?.mUse) {
|
|
217
|
-
const thisData = JSON.parse(
|
|
218
|
-
JSON.parse(sessionStorage.getItem(dataResponseName) || {})
|
|
219
|
-
);
|
|
220
|
-
|
|
210
|
+
const thisData = JSON.parse(JSON.parse(sessionStorage.getItem(dataResponseName) || {}));
|
|
221
211
|
return thisData;
|
|
222
212
|
}
|
|
223
213
|
} catch (error) {}
|
|
224
214
|
|
|
225
215
|
return this[dataResponseName];
|
|
226
216
|
},
|
|
227
|
-
|
|
217
|
+
WipeStates(storeKeyToRemove=null){
|
|
218
|
+
const sptStateData = localStorage.getItem(StateNameUsedSoferList) ?? "{}";
|
|
219
|
+
let previousState = JSON.parse(sptStateData);
|
|
220
|
+
if (storeKeyToRemove)
|
|
221
|
+
delete previousState[storeKeyToRemove];
|
|
222
|
+
else
|
|
223
|
+
previousState={};
|
|
224
|
+
|
|
225
|
+
const regroup = JSON.stringify(previousState);
|
|
226
|
+
localStorage.setItem(StateNameUsedSoferList, regroup);
|
|
227
|
+
},
|
|
228
|
+
async stateGenaratorApi(dd = { reload: true, StateStore: "", reqs: {}, time: 0, pagnated: false, mStore: { mUse: 0,reset:0 },},fasterDataCollection=null) {
|
|
228
229
|
this.Loading = true;
|
|
229
230
|
const { reload, StateStore, reqs, time, pagnated, mStore } = dd;
|
|
230
231
|
const callApi = JSON.stringify(reqs);
|
|
231
232
|
const StateVariable = await this.parseData(StateStore, mStore);
|
|
232
233
|
this[StateStore] = StateVariable ?? [];
|
|
233
|
-
|
|
234
|
+
if (ds?.StateClean) {
|
|
235
|
+
const sptStateData =localStorage.getItem(StateNameUsedSoferList) ?? "{}";
|
|
236
|
+
const previousState = JSON.parse(sptStateData);
|
|
237
|
+
const stateKey = typeof StateStore === "string" ? StateStore : "septore-store-";
|
|
238
|
+
const regroup = JSON.stringify({...previousState,[storeId + "(-_+_-)" + stateKey]: StateStore,});
|
|
239
|
+
localStorage.setItem(StateNameUsedSoferList, regroup);
|
|
240
|
+
}
|
|
234
241
|
if (this.StateValue[StateStore]) {
|
|
235
242
|
/**
|
|
236
243
|
* dynamically lets create the state store
|
package/dist/index.js
CHANGED
|
@@ -119,8 +119,10 @@ function getBearerToken() {
|
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
// src/StoreManager/pomStateManagement.js
|
|
122
|
-
function createPomStore(piniaStore = "7286204094", callBack = null) {
|
|
122
|
+
function createPomStore(piniaStore = "7286204094", callBack = null, ds = { StateClean: 0 }) {
|
|
123
123
|
const storeId = "POM" + piniaStore;
|
|
124
|
+
const StateNameUsedSoferList = "septor-store-collection";
|
|
125
|
+
;
|
|
124
126
|
const piniaData = defineStore(storeId, {
|
|
125
127
|
state: () => {
|
|
126
128
|
const StateObjectsContainer = {
|
|
@@ -188,21 +190,36 @@ function createPomStore(piniaStore = "7286204094", callBack = null) {
|
|
|
188
190
|
sessionStorage.removeItem(dataResponseName);
|
|
189
191
|
}
|
|
190
192
|
if (mStore == null ? void 0 : mStore.mUse) {
|
|
191
|
-
const thisData = JSON.parse(
|
|
192
|
-
JSON.parse(sessionStorage.getItem(dataResponseName) || {})
|
|
193
|
-
);
|
|
193
|
+
const thisData = JSON.parse(JSON.parse(sessionStorage.getItem(dataResponseName) || {}));
|
|
194
194
|
return thisData;
|
|
195
195
|
}
|
|
196
196
|
} catch (error) {
|
|
197
197
|
}
|
|
198
198
|
return this[dataResponseName];
|
|
199
199
|
},
|
|
200
|
-
|
|
200
|
+
WipeStates(storeKeyToRemove = null) {
|
|
201
|
+
const sptStateData = localStorage.getItem(StateNameUsedSoferList) ?? "{}";
|
|
202
|
+
let previousState = JSON.parse(sptStateData);
|
|
203
|
+
if (storeKeyToRemove)
|
|
204
|
+
delete previousState[storeKeyToRemove];
|
|
205
|
+
else
|
|
206
|
+
previousState = {};
|
|
207
|
+
const regroup = JSON.stringify(previousState);
|
|
208
|
+
localStorage.setItem(StateNameUsedSoferList, regroup);
|
|
209
|
+
},
|
|
210
|
+
async stateGenaratorApi(dd = { reload: true, StateStore: "", reqs: {}, time: 0, pagnated: false, mStore: { mUse: 0, reset: 0 } }, fasterDataCollection = null) {
|
|
201
211
|
this.Loading = true;
|
|
202
212
|
const { reload, StateStore, reqs, time, pagnated, mStore } = dd;
|
|
203
213
|
const callApi = JSON.stringify(reqs);
|
|
204
214
|
const StateVariable = await this.parseData(StateStore, mStore);
|
|
205
215
|
this[StateStore] = StateVariable ?? [];
|
|
216
|
+
if (ds == null ? void 0 : ds.StateClean) {
|
|
217
|
+
const sptStateData = localStorage.getItem(StateNameUsedSoferList) ?? "{}";
|
|
218
|
+
const previousState = JSON.parse(sptStateData);
|
|
219
|
+
const stateKey = typeof StateStore === "string" ? StateStore : "septore-store-";
|
|
220
|
+
const regroup = JSON.stringify({ ...previousState, [storeId + "(-_+_-)" + stateKey]: StateStore });
|
|
221
|
+
localStorage.setItem(StateNameUsedSoferList, regroup);
|
|
222
|
+
}
|
|
206
223
|
if (this.StateValue[StateStore]) {
|
|
207
224
|
this.StateValue[StateStore] = false;
|
|
208
225
|
this[StateStore] = false;
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "septor-store",
|
|
3
|
-
"description": "
|
|
3
|
+
"description": "A powerful, modular state management solution for Vue 3 applications, built on top of Pinia. Septor Store leverages the Plain Old Module (POM) pattern to provide dynamic store generation, intelligent API request handling, smart caching, and clean separation of concerns—making it ideal for scalable, maintainable, and high-performance frontend development.",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "
|
|
6
|
+
"version": "1.0.1",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "dist/index.cjs",
|
|
9
9
|
"module": "dist/index.js",
|
|
@@ -25,53 +25,49 @@
|
|
|
25
25
|
"vue": "^3.5.13"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@types/axios": "^0.14.4",
|
|
28
|
+
"@types/axios": "^0.14.4",
|
|
29
29
|
"tsup": "^8.4.0",
|
|
30
30
|
"typescript": "~5.8.3"
|
|
31
31
|
},
|
|
32
32
|
"keywords": [
|
|
33
|
-
"pinia",
|
|
34
33
|
"vue",
|
|
34
|
+
"vue3",
|
|
35
|
+
"pinia",
|
|
36
|
+
"pinia store",
|
|
37
|
+
"vue pinia plugin",
|
|
35
38
|
"state management",
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"pom-pattern",
|
|
45
|
-
"vue-pinia",
|
|
46
|
-
"vue-store",
|
|
47
|
-
"pinia-store",
|
|
48
|
-
"modular-state",
|
|
49
|
-
"api-cache",
|
|
50
|
-
"api-state-manager",
|
|
51
|
-
"typescript",
|
|
52
|
-
"vue-typescript",
|
|
53
|
-
"pinia-plugin",
|
|
54
|
-
"state-library",
|
|
39
|
+
"vue state management",
|
|
40
|
+
"api caching",
|
|
41
|
+
"vue ssr",
|
|
42
|
+
"vue spa",
|
|
43
|
+
"store plugin",
|
|
44
|
+
"modular state",
|
|
45
|
+
"dynamic store",
|
|
46
|
+
"state persistence",
|
|
55
47
|
"frontend tools",
|
|
56
|
-
"
|
|
57
|
-
"session
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"vue
|
|
61
|
-
"
|
|
48
|
+
"api queue",
|
|
49
|
+
"session storage",
|
|
50
|
+
"pom pattern",
|
|
51
|
+
"plain old module",
|
|
52
|
+
"vue typescript",
|
|
53
|
+
"typescript",
|
|
54
|
+
"reactive state",
|
|
55
|
+
"data fetching",
|
|
62
56
|
"vuex alternative",
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
57
|
+
"state library",
|
|
58
|
+
"state sync",
|
|
59
|
+
"loading state",
|
|
60
|
+
"vue plugin",
|
|
61
|
+
"pinia plugin",
|
|
62
|
+
"septor store",
|
|
63
|
+
"septor-store-vue"
|
|
68
64
|
],
|
|
69
65
|
"funding": [
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
],
|
|
66
|
+
{
|
|
67
|
+
"type": "ko-fi",
|
|
68
|
+
"url": "https://ko-fi.com/ssengedonazil"
|
|
69
|
+
}
|
|
70
|
+
],
|
|
75
71
|
"author": "Ssengendo Nazil",
|
|
76
72
|
"repository": {
|
|
77
73
|
"type": "git",
|