@cocreate/api 1.22.0 → 1.22.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.
Files changed (3) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/package.json +1 -1
  3. package/src/index.js +264 -222
package/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ ## [1.22.2](https://github.com/CoCreate-app/CoCreate-api/compare/v1.22.1...v1.22.2) (2025-04-11)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * dispatch end event on action element rather than document ([805bb62](https://github.com/CoCreate-app/CoCreate-api/commit/805bb627f7de7dc918ca41ea57bfde1e82407e4e))
7
+ * update observer observe param to type and and attributeName to attributeFilter ([ea6ab8d](https://github.com/CoCreate-app/CoCreate-api/commit/ea6ab8d8408696fdcc8959ea7fc199d706a5c05b))
8
+
9
+ ## [1.22.1](https://github.com/CoCreate-app/CoCreate-api/compare/v1.22.0...v1.22.1) (2025-01-18)
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * Call the function and assign its return value ([5102f60](https://github.com/CoCreate-app/CoCreate-api/commit/5102f60e13b07f4bcb6d84be18ae629489656cc7))
15
+ * moved data in to object ([168bb0a](https://github.com/CoCreate-app/CoCreate-api/commit/168bb0a5694dec3feb5d14b67e4ff911cfd88c9c))
16
+
1
17
  # [1.22.0](https://github.com/CoCreate-app/CoCreate-api/compare/v1.21.3...v1.22.0) (2024-11-04)
2
18
 
3
19
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/api",
3
- "version": "1.22.0",
3
+ "version": "1.22.2",
4
4
  "description": "A simple api helper component in vanilla javascript used by JavaScript developers to create thirdparty api intergrations. CoCreate-api includes the client component and server side for api processing. Thirdparty apis can be accessible using HTML5 attributes and/or JavaScript API. ",
5
5
  "keywords": [
6
6
  "thirdparty-api-intergration",
package/src/index.js CHANGED
@@ -2,233 +2,275 @@
2
2
  import { getValueFromObject, dotNotationToObject } from "@cocreate/utils";
3
3
  import Observer from "@cocreate/observer";
4
4
  import Socket from "@cocreate/socket-client";
5
- import Actions from '@cocreate/actions';
6
- import { render } from '@cocreate/render';
7
- import '@cocreate/element-prototype';
5
+ import Actions from "@cocreate/actions";
6
+ import { render } from "@cocreate/render";
7
+ import "@cocreate/element-prototype";
8
8
 
9
9
  const CoCreateApi = {
10
- modules: {},
11
-
12
- init: function (moduleConfig) {
13
- if (!moduleConfig) {
14
- let elements = document.querySelectorAll('[api], [module]')
15
- for (let i = 0; i < elements.length; i++) {
16
- let name = elements[i].getAttribute('api') || elements[i].getAttribute('module')
17
- this.register({ name, endPoints: {} });
18
- }
19
- } else {
20
- let { name, endPoints, options } = moduleConfig
21
- this.register({ name, endPoints, options });
22
- if (options && options.socket !== false && !Socket.sockets.size)
23
- Socket.create({ prefix: 'api' });
24
- }
25
- },
26
-
27
- register: function ({ name, endPoints, options }) {
28
- const self = this;
29
- if (typeof this.modules[name] === 'undefined') {
30
- this.modules[name] = { name, endPoints, options };
31
-
32
- Actions.init({
33
- name,
34
- callback: (action) => {
35
- action.form = action.form || document
36
- self.request({ ...action, type: 'action' })
37
- }
38
- });
39
-
40
- const inputEvent = (element) => {
41
- element.addEventListener('input', (e) => {
42
- if (!e.detail || e.detail && e.detail.skip != true) {
43
- self.request({ name, element, type: 'input' })
44
- }
45
- });
46
- }
47
-
48
- let elements = document.querySelectorAll(`[${name}]`)
49
- for (let i = 0; i < elements.length; i++) {
50
- inputEvent(elements[i])
51
- this.request({ name, element: elements[i], type: 'onload' })
52
- }
53
-
54
- Observer.init({
55
- name: `${name}NodeObserver`,
56
- observe: ['addedNodes'],
57
- selector: `[${name}]`,
58
- callback: function (mutation) {
59
- inputEvent(mutation.target)
60
- self.request({ name, element: mutation.target, type: 'nodeObserver' })
61
- }
62
- });
63
-
64
- Observer.init({
65
- name: `${name}AttributeObserver`,
66
- observe: ['attributes'],
67
- attributeName: [name],
68
- callback: function (mutation) {
69
- self.request({ name, element: mutation.target, type: 'attributeObserver' })
70
- }
71
- });
72
- }
73
- },
74
-
75
-
76
- request: async function (object) {
77
- if (object.element) {
78
- if (!object.method)
79
- object.method = object.element.getAttribute(object.name)
80
- if (!object.key)
81
- object.key = object.element.getAttribute(`${object.name}-key`)
82
- if (!object.event)
83
- object.event = object.element.getAttribute(`${object.name}-event`)
84
- }
85
-
86
- if (this.modules[object.name][object.method] && this.modules[object.name][object.method].request)
87
- this.modules[object.name][object.method].request(object)
88
- else if (!object.event && object.type === 'action' || object.event && object.event.includes(object.type)) {
89
- let data = await CoCreateApi.getData(object);
90
- CoCreateApi.send(object, data);
91
- }
92
- },
93
-
94
- response: function (object, data) {
95
- const name = object.name
96
- const method = object.method;
97
- if (this.modules[name][method] && this.modules[name][method].response)
98
- this.modules[name][method].response(data[name])
99
- else if (data.error) {
100
- render({
101
- selector: `[template*='${name}']`,
102
- data: [{
103
- type: name,
104
- method,
105
- status: 'failed',
106
- message: data.error
107
- }]
108
- });
109
- } else {
110
- CoCreateApi.setData(object, data)
111
-
112
- document.dispatchEvent(new CustomEvent(object.endEvent, {
113
- detail: {
114
- data: data[name]
115
- }
116
- }));
117
- }
118
- },
119
-
120
- send: async function (object, data) {
121
- data = await Socket.send({ method: object.name + '.' + object.method, [object.name]: data, broadcast: false, broadcastBrowser: false, status: 'await' });
122
- this.response(object, data);
123
- },
124
-
125
- getData: async function ({ name, method, element, form }) {
126
- let data = {}
127
-
128
- if (!form && element)
129
- form = element.closest('form');
130
-
131
- let elements
132
- if (form)
133
- elements = form.querySelectorAll(`[${name}="${method}"]:not([${name}-request="false"])`);
134
- if (!elements || elements.length == 0)
135
- elements = [element]
136
-
137
- for (let i = 0; i < elements.length; i++) {
138
- if (!elements[i] || elements[i].closest('[template]'))
139
- continue
140
- let key = elements[i].getAttribute(`${name}-key`)
141
- if (key) {
142
- let value = await elements[i].getValue()
143
- if (key.endsWith('[]')) {
144
- if (!data[key])
145
- data[key] = [];
146
-
147
- if (Array.isArray(value))
148
- data[key].push(...value);
149
- else
150
- data[key].push(value);
151
- } else
152
- data[key] = await elements[i].getValue()
153
-
154
- }
155
-
156
- let endpoint = elements[i].getAttribute('endpoint')
157
- if (endpoint) {
158
- data.endpoint = endpoint
159
- }
160
-
161
- if (elements[i].getAttribute('query') && elements[i].getAttribute('query') !== 'false') {
162
- data.query = true
163
- }
164
- }
165
-
166
- let params = {}, hasParams = false
167
- for (let i = 0; true; i++) {
168
- if (`$param[${i}]` in data) {
169
- params[`$param[${i}]`] = data[`$param[${i}]`]
170
- delete data[`$param[${i}]`]
171
- hasParams = true
172
- } else {
173
- break;
174
- }
175
- }
176
- data = dotNotationToObject(data);
177
- if (hasParams)
178
- data = { ...params, ...data }
179
-
180
- return data
181
- },
182
-
183
- setData: function (object, data) {
184
- const name = object.name
185
- let form = object.form
186
- if (!form)
187
- form = document;
188
-
189
- let elements = form.querySelectorAll(`[${name}="${object.method}"]`);
190
- if (!elements || elements.length == 0)
191
- return
192
-
193
- for (let i = 0; i < elements.length; i++) {
194
- let attribute = elements[i].getAttribute(name)
195
- if (attribute) {
196
- if (elements[i].hasAttribute('actions')) continue;
197
- let templateid = elements[i].getAttribute('template_id')
198
- if (templateid) {
199
- let items = document.querySelectorAll(`[templateid="${templateid}"]`)
200
- for (let item of items)
201
- item.remove()
202
- render({
203
- selector: `[template="${templateid}"]`,
204
- data
205
- });
206
- } else {
207
- let key = elements[i].getAttribute(`${name}-key`)
208
- if (key === '{}')
209
- elements[i].setValue(data[name])
210
- else {
211
- let value = getValueFromObject(data[name], key);
212
- elements[i].setValue(value);
213
- }
214
- }
215
- }
216
- }
217
-
218
- }
219
-
10
+ modules: {},
11
+
12
+ init: function (moduleConfig) {
13
+ if (!moduleConfig) {
14
+ let elements = document.querySelectorAll("[api], [module]");
15
+ for (let i = 0; i < elements.length; i++) {
16
+ let name =
17
+ elements[i].getAttribute("api") ||
18
+ elements[i].getAttribute("module");
19
+ this.register({ name, endPoints: {} });
20
+ }
21
+ } else {
22
+ let { name, endPoints, options } = moduleConfig;
23
+ this.register({ name, endPoints, options });
24
+ if (options && options.socket !== false && !Socket.sockets.size)
25
+ Socket.create({ prefix: "api" });
26
+ }
27
+ },
28
+
29
+ register: function ({ name, endPoints, options }) {
30
+ const self = this;
31
+ if (typeof this.modules[name] === "undefined") {
32
+ this.modules[name] = { name, endPoints, options };
33
+
34
+ Actions.init({
35
+ name,
36
+ callback: (action) => {
37
+ action.form = action.form || document;
38
+ self.request({ ...action, type: "action" });
39
+ }
40
+ });
41
+
42
+ const inputEvent = (element) => {
43
+ element.addEventListener("input", (e) => {
44
+ if (!e.detail || (e.detail && e.detail.skip != true)) {
45
+ self.request({ name, element, type: "input" });
46
+ }
47
+ });
48
+ };
49
+
50
+ let elements = document.querySelectorAll(`[${name}]`);
51
+ for (let i = 0; i < elements.length; i++) {
52
+ inputEvent(elements[i]);
53
+ this.request({ name, element: elements[i], type: "onload" });
54
+ }
55
+
56
+ Observer.init({
57
+ name: `${name}NodeObserver`,
58
+ types: ["addedNodes"],
59
+ selector: `[${name}]`,
60
+ callback: function (mutation) {
61
+ inputEvent(mutation.target);
62
+ self.request({
63
+ name,
64
+ element: mutation.target,
65
+ type: "nodeObserver"
66
+ });
67
+ }
68
+ });
69
+
70
+ Observer.init({
71
+ name: `${name}AttributeObserver`,
72
+ types: ["attributes"],
73
+ attributeFilter: [name],
74
+ callback: function (mutation) {
75
+ self.request({
76
+ name,
77
+ element: mutation.target,
78
+ type: "attributeObserver"
79
+ });
80
+ }
81
+ });
82
+ }
83
+ },
84
+
85
+ request: async function (object) {
86
+ if (object.element) {
87
+ if (!object.method)
88
+ object.method = object.element.getAttribute(object.name);
89
+ if (!object.key)
90
+ object.key = object.element.getAttribute(`${object.name}-key`);
91
+ if (!object.event)
92
+ object.event = object.element.getAttribute(
93
+ `${object.name}-event`
94
+ );
95
+ }
96
+
97
+ if (
98
+ this.modules[object.name][object.method] &&
99
+ this.modules[object.name][object.method].request
100
+ )
101
+ this.modules[object.name][object.method].request(object);
102
+ else if (
103
+ (!object.event && object.type === "action") ||
104
+ (object.event && object.event.includes(object.type))
105
+ ) {
106
+ object.data = await CoCreateApi.getData(object);
107
+ if (Object.keys(object.data).length) CoCreateApi.send(object);
108
+ }
109
+ },
110
+
111
+ response: function (object) {
112
+ const name = object.name;
113
+ const method = object.method;
114
+ const data = object.data;
115
+ if (this.modules[name][method] && this.modules[name][method].response)
116
+ this.modules[name][method].response(data[name]);
117
+ else if (data.error) {
118
+ render({
119
+ selector: `[template*='${name}']`,
120
+ data: [
121
+ {
122
+ type: name,
123
+ method,
124
+ status: "failed",
125
+ message: data.error
126
+ }
127
+ ]
128
+ });
129
+ } else {
130
+ CoCreateApi.setData(object);
131
+
132
+ object.element.dispatchEvent(
133
+ new CustomEvent(object.endEvent, {
134
+ detail: {
135
+ data: object
136
+ }
137
+ })
138
+ );
139
+ }
140
+ },
141
+
142
+ send: async function (object) {
143
+ object.data = await Socket.send({
144
+ method: object.name + "." + object.method,
145
+ [object.name]: object.data,
146
+ broadcast: false,
147
+ broadcastBrowser: false,
148
+ status: "await"
149
+ });
150
+ this.response(object);
151
+ },
152
+
153
+ getData: async function ({ name, method, element, form }) {
154
+ let data = {};
155
+
156
+ if (!form && element) form = element.closest("form");
157
+ if (!form) form = document;
158
+
159
+ let elements;
160
+ if (form)
161
+ elements = form.querySelectorAll(
162
+ `[${name}="${method}"]:not([${name}-request="false"])`
163
+ );
164
+ if (!elements || elements.length == 0) elements = [element];
165
+
166
+ for (let i = 0; i < elements.length; i++) {
167
+ if (!elements[i] || elements[i].closest("[template]")) continue;
168
+ let key = elements[i].getAttribute(`${name}-key`);
169
+ if (key) {
170
+ let value =
171
+ elements[i].stripeElement || (await elements[i].getValue());
172
+ if (key.endsWith("[]")) {
173
+ if (!data[key]) data[key] = [];
174
+
175
+ if (Array.isArray(value)) data[key].push(...value);
176
+ else data[key].push(value);
177
+ } else data[key] = value;
178
+ }
179
+
180
+ let endpoint = elements[i].getAttribute("endpoint");
181
+ if (endpoint) {
182
+ data.endpoint = endpoint;
183
+ }
184
+
185
+ if (
186
+ elements[i].getAttribute("query") &&
187
+ elements[i].getAttribute("query") !== "false"
188
+ ) {
189
+ data.query = true;
190
+ }
191
+ }
192
+
193
+ let params = {},
194
+ hasParams = false;
195
+ for (let i = 0; true; i++) {
196
+ if (`$param[${i}]` in data) {
197
+ params[`$param[${i}]`] = data[`$param[${i}]`];
198
+ delete data[`$param[${i}]`];
199
+ hasParams = true;
200
+ } else {
201
+ break;
202
+ }
203
+ }
204
+ data = dotNotationToObject(data);
205
+ if (hasParams) data = { ...params, ...data };
206
+
207
+ return data;
208
+ },
209
+
210
+ setData: function (object) {
211
+ const name = object.name;
212
+ const data = object.data;
213
+ let form = object.form;
214
+ if (!form) form = document;
215
+
216
+ let elements = form.querySelectorAll(
217
+ `[${name}="${object.method}"]:not([${name}-response="false"])`
218
+ );
219
+ if (!elements || elements.length == 0) return;
220
+
221
+ for (let i = 0; i < elements.length; i++) {
222
+ let attribute = elements[i].getAttribute(name);
223
+ if (attribute) {
224
+ if (elements[i].hasAttribute("actions")) continue;
225
+ let templateid = elements[i].getAttribute("template_id");
226
+ if (templateid) {
227
+ let items = document.querySelectorAll(
228
+ `[templateid="${templateid}"]`
229
+ );
230
+ for (let item of items) item.remove();
231
+ render({
232
+ selector: `[template="${templateid}"]`,
233
+ data
234
+ });
235
+ } else if (elements[i].renderValue) {
236
+ let key = elements[i].getAttribute(`${name}-key`);
237
+ if (key === "{}") {
238
+ elements[i].renderValue(data[name]);
239
+ } else {
240
+ let value = getValueFromObject(data[name], key);
241
+ if (typeof value === "function") {
242
+ value = value(); // Call the function and assign its return value.
243
+ }
244
+ elements[i].renderValue(value);
245
+ }
246
+ } else {
247
+ let key = elements[i].getAttribute(`${name}-key`);
248
+ if (key === "{}") elements[i].setValue(data[name]);
249
+ else {
250
+ let value = getValueFromObject(data[name], key);
251
+ if (typeof value === "function") {
252
+ value = value(); // Call the function and assign its return value.
253
+ }
254
+ elements[i].setValue(value);
255
+ }
256
+ }
257
+ }
258
+ }
259
+ }
220
260
  };
221
261
 
222
262
  Observer.init({
223
- name: `apiNodeObserver`,
224
- observe: ['addedNodes'],
225
- selector: '[module], [api]',
226
- callback: function (mutation) {
227
- let name = mutation.target.getAttribute('api') || mutation.target.getAttribute('module')
228
- CoCreateApi.register({ name, endPoints: {} });
229
- }
263
+ name: `apiNodeObserver`,
264
+ types: ["addedNodes"],
265
+ selector: "[module], [api]",
266
+ callback: function (mutation) {
267
+ let name =
268
+ mutation.target.getAttribute("api") ||
269
+ mutation.target.getAttribute("module");
270
+ CoCreateApi.register({ name, endPoints: {} });
271
+ }
230
272
  });
231
273
 
232
- CoCreateApi.init()
274
+ CoCreateApi.init();
233
275
 
234
- export default CoCreateApi;
276
+ export default CoCreateApi;