oneentry 1.0.175 → 1.0.177

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 (197) hide show
  1. package/README.md +12 -5
  2. package/changelog.md +140 -0
  3. package/dist/admins/adminsApi.js +2 -9
  4. package/dist/admins/adminsInterfaces.d.ts +5 -5
  5. package/dist/admins/adminsSchemas.d.ts +4 -4
  6. package/dist/admins/adminsSchemas.js +2 -2
  7. package/dist/attribute-sets/attributeSetsApi.d.ts +1 -1
  8. package/dist/attribute-sets/attributeSetsApi.js +4 -4
  9. package/dist/attribute-sets/attributeSetsInterfaces.d.ts +65 -14
  10. package/dist/attribute-sets/attributeSetsSchemas.d.ts +8 -6
  11. package/dist/attribute-sets/attributeSetsSchemas.js +6 -9
  12. package/dist/auth-provider/authProviderApi.d.ts +4 -4
  13. package/dist/auth-provider/authProviderApi.js +96 -29
  14. package/dist/auth-provider/authProviderSchemas.d.ts +1 -0
  15. package/dist/auth-provider/authProviderSchemas.js +1 -0
  16. package/dist/auth-provider/authProvidersInterfaces.d.ts +8 -6
  17. package/dist/base/asyncModules.d.ts +73 -1
  18. package/dist/base/asyncModules.js +233 -37
  19. package/dist/base/stateModule.d.ts +2 -0
  20. package/dist/base/stateModule.js +22 -12
  21. package/dist/base/syncModules.d.ts +18 -10
  22. package/dist/base/syncModules.js +100 -29
  23. package/dist/base/utils.d.ts +26 -21
  24. package/dist/base/validation.d.ts +3 -3
  25. package/dist/base/validation.js +6 -7
  26. package/dist/blocks/blocksApi.d.ts +20 -17
  27. package/dist/blocks/blocksApi.js +101 -74
  28. package/dist/blocks/blocksInterfaces.d.ts +8 -8
  29. package/dist/discounts/discountsApi.d.ts +9 -7
  30. package/dist/discounts/discountsApi.js +18 -14
  31. package/dist/discounts/discountsInterfaces.d.ts +14 -10
  32. package/dist/events/eventsApi.d.ts +3 -3
  33. package/dist/events/eventsApi.js +7 -7
  34. package/dist/events/eventsInterfaces.d.ts +10 -14
  35. package/dist/file-uploading/fileUploadingApi.d.ts +4 -4
  36. package/dist/file-uploading/fileUploadingApi.js +13 -5
  37. package/dist/file-uploading/fileUploadingInterfaces.d.ts +5 -6
  38. package/dist/filters/filtersApi.js +2 -2
  39. package/dist/forms/formsApi.js +2 -2
  40. package/dist/forms/formsInterfaces.d.ts +1 -3
  41. package/dist/forms/formsSchemas.d.ts +3 -6
  42. package/dist/forms/formsSchemas.js +2 -4
  43. package/dist/forms-data/formsDataApi.d.ts +26 -8
  44. package/dist/forms-data/formsDataApi.js +45 -14
  45. package/dist/forms-data/formsDataInterfaces.d.ts +91 -66
  46. package/dist/general-types/generalTypesInterfaces.d.ts +1 -1
  47. package/dist/index.d.ts +7 -6
  48. package/dist/index.js +50 -7
  49. package/dist/integration-collections/integrationCollectionsApi.d.ts +15 -4
  50. package/dist/integration-collections/integrationCollectionsApi.js +42 -14
  51. package/dist/integration-collections/integrationCollectionsInterfaces.d.ts +8 -9
  52. package/dist/integration-collections/integrationCollectionsSchemas.d.ts +0 -2
  53. package/dist/integration-collections/integrationCollectionsSchemas.js +0 -1
  54. package/dist/menus/menusApi.js +1 -1
  55. package/dist/orders/ordersApi.d.ts +1 -13
  56. package/dist/orders/ordersApi.js +24 -44
  57. package/dist/orders/ordersInterfaces.d.ts +21 -14
  58. package/dist/pages/pagesApi.d.ts +6 -5
  59. package/dist/pages/pagesApi.js +44 -31
  60. package/dist/pages/pagesInterfaces.d.ts +18 -15
  61. package/dist/pages/pagesSchemas.d.ts +0 -3
  62. package/dist/pages/pagesSchemas.js +0 -1
  63. package/dist/payments/paymentsApi.d.ts +10 -11
  64. package/dist/payments/paymentsApi.js +22 -18
  65. package/dist/payments/paymentsInterfaces.d.ts +12 -14
  66. package/dist/payments/paymentsSchemas.d.ts +21 -20
  67. package/dist/payments/paymentsSchemas.js +5 -8
  68. package/dist/product-statuses/productStatusesApi.d.ts +1 -1
  69. package/dist/product-statuses/productStatusesApi.js +4 -4
  70. package/dist/product-statuses/productStatusesInterfaces.d.ts +1 -4
  71. package/dist/products/productsApi.d.ts +38 -58
  72. package/dist/products/productsApi.js +59 -72
  73. package/dist/products/productsInterfaces.d.ts +48 -85
  74. package/dist/search/searchApi.d.ts +1 -1
  75. package/dist/search/searchApi.js +4 -3
  76. package/dist/sitemap/sitemapInterfaces.d.ts +10 -6
  77. package/dist/subscriptions/subscriptionsApi.d.ts +1 -1
  78. package/dist/subscriptions/subscriptionsApi.js +1 -1
  79. package/dist/subscriptions/subscriptionsInterfaces.d.ts +1 -1
  80. package/dist/system/systemApi.d.ts +2 -0
  81. package/dist/system/systemApi.js +2 -0
  82. package/dist/system/systemInterfaces.d.ts +2 -0
  83. package/dist/templates/templatesApi.d.ts +2 -2
  84. package/dist/templates/templatesApi.js +12 -11
  85. package/dist/templates/templatesInterfaces.d.ts +2 -2
  86. package/dist/templates-preview/templatesPreviewApi.js +2 -2
  87. package/dist/templates-preview/templatesPreviewInterfaces.d.ts +23 -13
  88. package/dist/templates-preview/templatesPreviewSchemas.d.ts +7 -0
  89. package/dist/templates-preview/templatesPreviewSchemas.js +2 -0
  90. package/dist/user-groups/userGroupsApi.js +5 -5
  91. package/dist/user-groups/userGroupsSchemas.d.ts +4 -4
  92. package/dist/users/usersApi.d.ts +1 -1
  93. package/dist/users/usersApi.js +28 -15
  94. package/dist/users/usersInterfaces.d.ts +2 -9
  95. package/dist/web-socket/lazySocket.d.ts +6 -5
  96. package/dist/web-socket/lazySocket.js +212 -15
  97. package/dist/web-socket/wsApi.d.ts +7 -4
  98. package/dist/web-socket/wsApi.js +49 -12
  99. package/dist/web-socket/wsInterfaces.d.ts +41 -4
  100. package/esm/admins/adminsApi.js +2 -9
  101. package/esm/admins/adminsInterfaces.d.ts +5 -5
  102. package/esm/admins/adminsSchemas.d.ts +4 -4
  103. package/esm/admins/adminsSchemas.js +2 -2
  104. package/esm/attribute-sets/attributeSetsApi.d.ts +1 -1
  105. package/esm/attribute-sets/attributeSetsApi.js +4 -4
  106. package/esm/attribute-sets/attributeSetsInterfaces.d.ts +65 -14
  107. package/esm/attribute-sets/attributeSetsSchemas.d.ts +8 -6
  108. package/esm/attribute-sets/attributeSetsSchemas.js +6 -9
  109. package/esm/auth-provider/authProviderApi.d.ts +4 -4
  110. package/esm/auth-provider/authProviderApi.js +96 -29
  111. package/esm/auth-provider/authProviderSchemas.d.ts +1 -0
  112. package/esm/auth-provider/authProviderSchemas.js +1 -0
  113. package/esm/auth-provider/authProvidersInterfaces.d.ts +8 -6
  114. package/esm/base/asyncModules.d.ts +73 -1
  115. package/esm/base/asyncModules.js +233 -37
  116. package/esm/base/stateModule.d.ts +2 -0
  117. package/esm/base/stateModule.js +22 -12
  118. package/esm/base/syncModules.d.ts +18 -10
  119. package/esm/base/syncModules.js +99 -29
  120. package/esm/base/utils.d.ts +26 -21
  121. package/esm/base/validation.d.ts +3 -3
  122. package/esm/base/validation.js +6 -7
  123. package/esm/blocks/blocksApi.d.ts +20 -17
  124. package/esm/blocks/blocksApi.js +101 -74
  125. package/esm/blocks/blocksInterfaces.d.ts +8 -8
  126. package/esm/discounts/discountsApi.d.ts +9 -7
  127. package/esm/discounts/discountsApi.js +18 -14
  128. package/esm/discounts/discountsInterfaces.d.ts +14 -10
  129. package/esm/events/eventsApi.d.ts +3 -3
  130. package/esm/events/eventsApi.js +7 -7
  131. package/esm/events/eventsInterfaces.d.ts +10 -14
  132. package/esm/file-uploading/fileUploadingApi.d.ts +4 -4
  133. package/esm/file-uploading/fileUploadingApi.js +13 -5
  134. package/esm/file-uploading/fileUploadingInterfaces.d.ts +5 -6
  135. package/esm/filters/filtersApi.js +2 -2
  136. package/esm/forms/formsApi.js +2 -2
  137. package/esm/forms/formsInterfaces.d.ts +1 -3
  138. package/esm/forms/formsSchemas.d.ts +3 -6
  139. package/esm/forms/formsSchemas.js +2 -4
  140. package/esm/forms-data/formsDataApi.d.ts +26 -8
  141. package/esm/forms-data/formsDataApi.js +45 -14
  142. package/esm/forms-data/formsDataInterfaces.d.ts +91 -66
  143. package/esm/general-types/generalTypesInterfaces.d.ts +1 -1
  144. package/esm/index.d.ts +7 -6
  145. package/esm/index.js +50 -7
  146. package/esm/integration-collections/integrationCollectionsApi.d.ts +15 -4
  147. package/esm/integration-collections/integrationCollectionsApi.js +42 -14
  148. package/esm/integration-collections/integrationCollectionsInterfaces.d.ts +8 -9
  149. package/esm/integration-collections/integrationCollectionsSchemas.d.ts +0 -2
  150. package/esm/integration-collections/integrationCollectionsSchemas.js +0 -1
  151. package/esm/menus/menusApi.js +1 -1
  152. package/esm/orders/ordersApi.d.ts +1 -13
  153. package/esm/orders/ordersApi.js +24 -44
  154. package/esm/orders/ordersInterfaces.d.ts +21 -14
  155. package/esm/pages/pagesApi.d.ts +6 -5
  156. package/esm/pages/pagesApi.js +44 -31
  157. package/esm/pages/pagesInterfaces.d.ts +18 -15
  158. package/esm/pages/pagesSchemas.d.ts +0 -3
  159. package/esm/pages/pagesSchemas.js +0 -1
  160. package/esm/payments/paymentsApi.d.ts +10 -11
  161. package/esm/payments/paymentsApi.js +22 -18
  162. package/esm/payments/paymentsInterfaces.d.ts +12 -14
  163. package/esm/payments/paymentsSchemas.d.ts +21 -20
  164. package/esm/payments/paymentsSchemas.js +5 -8
  165. package/esm/product-statuses/productStatusesApi.d.ts +1 -1
  166. package/esm/product-statuses/productStatusesApi.js +4 -4
  167. package/esm/product-statuses/productStatusesInterfaces.d.ts +1 -4
  168. package/esm/products/productsApi.d.ts +38 -58
  169. package/esm/products/productsApi.js +59 -72
  170. package/esm/products/productsInterfaces.d.ts +48 -85
  171. package/esm/search/searchApi.d.ts +1 -1
  172. package/esm/search/searchApi.js +4 -3
  173. package/esm/sitemap/sitemapInterfaces.d.ts +10 -6
  174. package/esm/subscriptions/subscriptionsApi.d.ts +1 -1
  175. package/esm/subscriptions/subscriptionsApi.js +1 -1
  176. package/esm/subscriptions/subscriptionsInterfaces.d.ts +1 -1
  177. package/esm/system/systemApi.d.ts +2 -0
  178. package/esm/system/systemApi.js +2 -0
  179. package/esm/system/systemInterfaces.d.ts +2 -0
  180. package/esm/templates/templatesApi.d.ts +2 -2
  181. package/esm/templates/templatesApi.js +11 -10
  182. package/esm/templates/templatesInterfaces.d.ts +2 -2
  183. package/esm/templates-preview/templatesPreviewApi.js +2 -2
  184. package/esm/templates-preview/templatesPreviewInterfaces.d.ts +23 -13
  185. package/esm/templates-preview/templatesPreviewSchemas.d.ts +7 -0
  186. package/esm/templates-preview/templatesPreviewSchemas.js +2 -0
  187. package/esm/user-groups/userGroupsApi.js +5 -5
  188. package/esm/user-groups/userGroupsSchemas.d.ts +4 -4
  189. package/esm/users/usersApi.d.ts +1 -1
  190. package/esm/users/usersApi.js +28 -15
  191. package/esm/users/usersInterfaces.d.ts +2 -9
  192. package/esm/web-socket/lazySocket.d.ts +6 -5
  193. package/esm/web-socket/lazySocket.js +212 -15
  194. package/esm/web-socket/wsApi.d.ts +7 -4
  195. package/esm/web-socket/wsApi.js +49 -12
  196. package/esm/web-socket/wsInterfaces.d.ts +41 -4
  197. package/package.json +2 -2
@@ -8,11 +8,12 @@ import type { Socket } from 'socket.io-client';
8
8
  * queued and replayed onto the real socket as soon as the chunk resolves, and every later
9
9
  * call passes straight through.
10
10
  * @param {() => Promise<Socket>} createSocket - Loads Socket.io and creates the socket.
11
- * @returns {Socket} Stand-in usable exactly like the socket it will become.
11
+ * @returns {Socket} Stand-in usable like the socket it will become.
12
12
  * @description Listener registration is what matters for ordering, and it is safe: the queue is
13
13
  * replayed in the same tick the socket is created, before the connection can deliver anything.
14
- * The one visible difference is that methods returning a value (e.g. `listeners()`) cannot answer
15
- * before the chunk arrives — they return the proxy instead. Reading state (`id`, `connected`, …)
16
- * is accurate, and awaiting `socket.io` or other nested objects is only possible once loaded.
14
+ * Before the chunk arrives: `emitWithAck` returns a Promise settled by the real socket,
15
+ * `hasListeners`/`listeners` answer from the queued listeners, `socket.io.on(…)` and `volatile` are
16
+ * queued, assignments (e.g. `socket.auth = …`) are applied to the real socket, and other properties
17
+ * read `undefined`. A failed chunk load is reported to the `connect_error` listeners.
17
18
  */
18
- export default function createLazySocket(createSocket: () => Promise<Socket>): Socket;
19
+ export default function createLazySocket<S extends Socket = Socket>(createSocket: () => Promise<S>): S;
@@ -10,9 +10,41 @@ const PENDING_STATE = {
10
10
  id: undefined,
11
11
  connected: false,
12
12
  disconnected: true,
13
- active: false,
13
+ // A socket created with `autoConnect` is active from the start
14
+ active: true,
14
15
  recovered: false,
15
16
  };
17
+ /**
18
+ * Socket methods that may be called before the real socket exists: they are queued and replayed.
19
+ * @description Any other property read early answers `undefined`. Queuing every name used to put
20
+ * `toJSON` (read by `JSON.stringify`) into the queue, and its replay threw and lost every listener.
21
+ */
22
+ const QUEUEABLE = new Set([
23
+ 'on',
24
+ 'once',
25
+ 'off',
26
+ 'addListener',
27
+ 'removeListener',
28
+ 'removeAllListeners',
29
+ 'onAny',
30
+ 'prependAny',
31
+ 'offAny',
32
+ 'onAnyOutgoing',
33
+ 'prependAnyOutgoing',
34
+ 'offAnyOutgoing',
35
+ 'emit',
36
+ 'send',
37
+ 'connect',
38
+ 'open',
39
+ 'disconnect',
40
+ 'close',
41
+ 'compress',
42
+ 'timeout',
43
+ ]);
44
+ /**
45
+ * Methods of `socket.io` (the Manager) that may be called before the real socket exists.
46
+ */
47
+ const IO_QUEUEABLE = new Set(['on', 'once', 'off', 'reconnection']);
16
48
  /**
17
49
  * Wraps a not-yet-loaded Socket.io socket in a synchronous stand-in.
18
50
  *
@@ -22,30 +54,108 @@ const PENDING_STATE = {
22
54
  * queued and replayed onto the real socket as soon as the chunk resolves, and every later
23
55
  * call passes straight through.
24
56
  * @param {() => Promise<Socket>} createSocket - Loads Socket.io and creates the socket.
25
- * @returns {Socket} Stand-in usable exactly like the socket it will become.
57
+ * @returns {Socket} Stand-in usable like the socket it will become.
26
58
  * @description Listener registration is what matters for ordering, and it is safe: the queue is
27
59
  * replayed in the same tick the socket is created, before the connection can deliver anything.
28
- * The one visible difference is that methods returning a value (e.g. `listeners()`) cannot answer
29
- * before the chunk arrives — they return the proxy instead. Reading state (`id`, `connected`, …)
30
- * is accurate, and awaiting `socket.io` or other nested objects is only possible once loaded.
60
+ * Before the chunk arrives: `emitWithAck` returns a Promise settled by the real socket,
61
+ * `hasListeners`/`listeners` answer from the queued listeners, `socket.io.on(…)` and `volatile` are
62
+ * queued, assignments (e.g. `socket.auth = …`) are applied to the real socket, and other properties
63
+ * read `undefined`. A failed chunk load is reported to the `connect_error` listeners.
31
64
  */
32
65
  function createLazySocket(createSocket) {
33
66
  let socket;
67
+ let loadError;
34
68
  const queued = [];
69
+ const pendingProps = new Map();
70
+ // The listeners the queue leaves registered, `off`/`removeAllListeners` applied in order
71
+ const queuedListeners = (event) => {
72
+ let listeners = [];
73
+ for (const { target, method, args } of queued) {
74
+ if (target !== 'socket')
75
+ continue;
76
+ if (method === 'on' || method === 'once' || method === 'addListener') {
77
+ listeners.push({
78
+ event: args[0],
79
+ fn: args[1],
80
+ });
81
+ }
82
+ else if (method === 'off' || method === 'removeListener') {
83
+ // `off()` without arguments removes every listener, as in Socket.io
84
+ listeners = listeners.filter((l) => (args.length > 0 && l.event !== args[0]) ||
85
+ (args.length > 1 && l.fn !== args[1]));
86
+ }
87
+ else if (method === 'removeAllListeners') {
88
+ listeners = listeners.filter((l) => args.length > 0 && l.event !== args[0]);
89
+ }
90
+ }
91
+ return listeners
92
+ .filter((l) => event === undefined || l.event === event)
93
+ .map((l) => l.fn);
94
+ };
35
95
  const loading = createSocket().then((created) => {
96
+ // Assigned first: a listener running during the replay already reaches the real socket
97
+ socket = created;
98
+ for (const [property, value] of pendingProps) {
99
+ created[property] = value;
100
+ }
101
+ pendingProps.clear();
36
102
  // Replay before returning: the connection cannot emit anything until this tick ends,
37
- // so no event registered through the proxy can be missed.
38
- for (const { method, args } of queued) {
39
- created[method](...args);
103
+ // so no event registered through the proxy can be missed. One failing call must not
104
+ // drop the rest of the queue.
105
+ for (const { target, method, args } of queued) {
106
+ try {
107
+ const owner = target === 'io' ? created.io : created;
108
+ if (method === 'volatile') {
109
+ void owner.volatile;
110
+ }
111
+ else if (method === 'emitWithAck') {
112
+ // Replayed in its place in the queue: a `timeout()` queued before it is its own flag
113
+ const { resolve, reject } = args.pop();
114
+ owner.emitWithAck(...args).then(resolve, reject);
115
+ }
116
+ else {
117
+ owner[method](...args);
118
+ }
119
+ }
120
+ catch (error) {
121
+ // eslint-disable-next-line no-undef, no-console
122
+ console.error(`OneEntry SDK: socket.${method}() failed`, error);
123
+ }
40
124
  }
41
125
  queued.length = 0;
42
- socket = created;
43
126
  return created;
44
127
  });
45
- // A failed chunk load must not surface as an unhandled rejection
128
+ // A failed chunk load must not surface as an unhandled rejection: it goes to the
129
+ // `connect_error` listeners, the place Socket.io reports a connection that cannot open
46
130
  loading.catch((error) => {
47
- // eslint-disable-next-line no-undef, no-console
48
- console.error('OneEntry SDK: failed to load socket.io-client', error);
131
+ loadError = error;
132
+ const listeners = queuedListeners('connect_error');
133
+ for (const { method, args } of queued) {
134
+ if (method === 'emitWithAck') {
135
+ args[args.length - 1].reject(error);
136
+ }
137
+ }
138
+ queued.length = 0;
139
+ if (listeners.length === 0) {
140
+ // eslint-disable-next-line no-undef, no-console
141
+ console.error('OneEntry SDK: could not create the socket', error);
142
+ }
143
+ for (const listener of listeners) {
144
+ listener(error);
145
+ }
146
+ });
147
+ const ioProxy = new Proxy({}, {
148
+ get(_target, property) {
149
+ if (typeof property === 'string' && IO_QUEUEABLE.has(property)) {
150
+ return (...args) => {
151
+ if (!loadError) {
152
+ queued.push({ target: 'io', method: property, args });
153
+ }
154
+ return ioProxy;
155
+ };
156
+ }
157
+ return undefined;
158
+ },
49
159
  });
50
160
  const proxy = new Proxy({}, {
51
161
  get(_target, property) {
@@ -57,13 +167,100 @@ function createLazySocket(createSocket) {
57
167
  if (property === 'then' || typeof property === 'symbol') {
58
168
  return undefined;
59
169
  }
170
+ if (pendingProps.has(property)) {
171
+ return pendingProps.get(property);
172
+ }
173
+ if (property === 'active') {
174
+ // Active until a queued disconnect or a failed load, as the real socket would be
175
+ // The last queued connect/disconnect decides, as on the real socket
176
+ const last = [...queued]
177
+ .reverse()
178
+ .find(({ target, method }) => target === 'socket' &&
179
+ ['disconnect', 'close', 'connect', 'open'].includes(method));
180
+ return (!loadError &&
181
+ !(last && (last.method === 'disconnect' || last.method === 'close')));
182
+ }
60
183
  if (property in PENDING_STATE) {
61
184
  return PENDING_STATE[property];
62
185
  }
63
- return (...args) => {
64
- queued.push({ method: property, args });
186
+ if (property === 'io') {
187
+ return ioProxy;
188
+ }
189
+ if (property === 'volatile') {
190
+ if (!loadError) {
191
+ queued.push({ target: 'socket', method: 'volatile', args: [] });
192
+ }
65
193
  return proxy;
66
- };
194
+ }
195
+ if (property === 'emitWithAck') {
196
+ return (...args) => loadError
197
+ ? Promise.reject(loadError)
198
+ : new Promise((resolve, reject) => {
199
+ queued.push({
200
+ target: 'socket',
201
+ method: 'emitWithAck',
202
+ args: [...args, { resolve, reject }],
203
+ });
204
+ });
205
+ }
206
+ if (property === 'hasListeners') {
207
+ return (event) => queuedListeners(event).length > 0;
208
+ }
209
+ if (property === 'listeners') {
210
+ return (event) => queuedListeners(event);
211
+ }
212
+ if (typeof property === 'string' && QUEUEABLE.has(property)) {
213
+ return (...args) => {
214
+ if (loadError &&
215
+ (property === 'on' || property === 'once') &&
216
+ args[0] === 'connect_error') {
217
+ // Registered after the load already failed: report it straight away
218
+ args[1](loadError);
219
+ }
220
+ else if (!loadError) {
221
+ queued.push({ target: 'socket', method: property, args });
222
+ }
223
+ return proxy;
224
+ };
225
+ }
226
+ return undefined;
227
+ },
228
+ set(_target, property, value) {
229
+ if (socket) {
230
+ return Reflect.set(socket, property, value);
231
+ }
232
+ pendingProps.set(property, value);
233
+ return true;
234
+ },
235
+ has(_target, property) {
236
+ if (socket) {
237
+ return property in socket;
238
+ }
239
+ return (typeof property === 'string' &&
240
+ (property in PENDING_STATE ||
241
+ QUEUEABLE.has(property) ||
242
+ [
243
+ 'io',
244
+ 'volatile',
245
+ 'emitWithAck',
246
+ 'hasListeners',
247
+ 'listeners',
248
+ ].includes(property) ||
249
+ pendingProps.has(property)));
250
+ },
251
+ ownKeys() {
252
+ return socket ? Reflect.ownKeys(socket) : [];
253
+ },
254
+ getOwnPropertyDescriptor(_target, property) {
255
+ if (!socket) {
256
+ return undefined;
257
+ }
258
+ const descriptor = Reflect.getOwnPropertyDescriptor(socket, property);
259
+ // The proxy target holds none of these keys, so they must be reported configurable
260
+ return descriptor ? { ...descriptor, configurable: true } : undefined;
261
+ },
262
+ getPrototypeOf() {
263
+ return socket ? Reflect.getPrototypeOf(socket) : Object.prototype;
67
264
  },
68
265
  });
69
266
  return proxy;
@@ -1,7 +1,7 @@
1
1
  import type { Socket } from 'socket.io-client';
2
2
  import AsyncModules from '../base/asyncModules';
3
3
  import type StateModule from '../base/stateModule';
4
- import type { IWS } from './wsInterfaces';
4
+ import type { IWS, IWsServerEvents } from './wsInterfaces';
5
5
  /**
6
6
  * Controllers for working with users
7
7
  * @handle /api/content/ws
@@ -17,11 +17,14 @@ export default class WsApi extends AsyncModules implements IWS {
17
17
  /**
18
18
  * Creates an instance of an object Socket.io with a connection.
19
19
  * @handleName connect
20
- * @returns {Socket} Returns a Socket instance.
21
- * @description Creates an instance of an object Socket.io with a connection. This method requires user authorization.
20
+ * @returns {Socket<IWsServerEvents>} Returns a Socket instance.
21
+ * @description Opens a Socket.io connection. Without a signed-in user the socket is a guest and
22
+ * receives only notifications sent to everyone; personal ones need `AuthProvider.auth` first.
23
+ * The current access token is sent on every (re)connection, so a refreshed token is picked up.
24
+ * Every call opens a separate connection.
22
25
  * Socket.io is imported on demand, so projects that never open a socket do not bundle it; the returned
23
26
  * value is usable immediately either way (see `createLazySocket`).
24
27
  * @see {@link https://js-sdk.oneentry.cloud/docs/web-socket/connect connect} documentation.
25
28
  */
26
- connect(): Socket;
29
+ connect(): Socket<IWsServerEvents>;
27
30
  }
@@ -54,28 +54,65 @@ class WsApi extends asyncModules_1.default {
54
54
  /**
55
55
  * Creates an instance of an object Socket.io with a connection.
56
56
  * @handleName connect
57
- * @returns {Socket} Returns a Socket instance.
58
- * @description Creates an instance of an object Socket.io with a connection. This method requires user authorization.
57
+ * @returns {Socket<IWsServerEvents>} Returns a Socket instance.
58
+ * @description Opens a Socket.io connection. Without a signed-in user the socket is a guest and
59
+ * receives only notifications sent to everyone; personal ones need `AuthProvider.auth` first.
60
+ * The current access token is sent on every (re)connection, so a refreshed token is picked up.
61
+ * Every call opens a separate connection.
59
62
  * Socket.io is imported on demand, so projects that never open a socket do not bundle it; the returned
60
63
  * value is usable immediately either way (see `createLazySocket`).
61
64
  * @see {@link https://js-sdk.oneentry.cloud/docs/web-socket/connect connect} documentation.
62
65
  */
63
66
  connect() {
64
- if (!this.state.accessToken) {
65
- // eslint-disable-next-line no-undef, no-console
66
- console.error('User is unauthorized');
67
- }
68
67
  return (0, lazySocket_1.default)(async () => {
68
+ var _a;
69
69
  const { io } = await Promise.resolve().then(() => __importStar(require('socket.io-client')));
70
- return io(this.state.url, {
70
+ // A session restored from a refresh token has no access token until its first
71
+ // request: the socket went out as a guest. Obtain it first, as REST calls do.
72
+ if (!this.state.accessToken &&
73
+ this._canRefresh() &&
74
+ !this.state.customAuth) {
75
+ await this.refreshToken();
76
+ }
77
+ // A path in the project URL (a reverse proxy prefix) belongs to the socket path:
78
+ // passed in the URL, Socket.io read it as a namespace and answered "Invalid namespace"
79
+ // A proxy path (`/oneentry`) resolves against the page
80
+ // `''` (the site root proxy) must not resolve to the current page's path
81
+ const base = new URL(this.state.url || '/', (_a = globalThis.location) === null || _a === void 0 ? void 0 : _a.href);
82
+ const path = base.pathname.replace(/\/+$/, '') + '/api/content/ws';
83
+ // The platform registers a user only with both the bearer and `x-device-metadata`;
84
+ // without the latter every SDK socket was a guest. Read on each (re)connection so a
85
+ // refreshed token is used, and no `Bearer undefined` for a guest.
86
+ const headers = () => ({
87
+ ...(this.state.accessToken
88
+ ? { Authorization: 'Bearer ' + this.state.accessToken }
89
+ : {}),
90
+ 'x-app-token': this.state.token,
91
+ 'x-device-metadata': this._getDeviceMetadata(),
92
+ });
93
+ const socket = io(base.origin, {
71
94
  autoConnect: true,
72
- path: '/api/content/ws',
95
+ path,
73
96
  transports: ['websocket'],
74
- extraHeaders: {
75
- Authorization: 'Bearer ' + this.state.accessToken,
76
- 'x-app-token': this.state.token,
77
- },
97
+ // Browsers drop `extraHeaders` on a WebSocket: the same data goes in the
98
+ // handshake `auth` payload as well
99
+ extraHeaders: headers(),
100
+ auth: (cb) => cb({
101
+ token: this.state.accessToken,
102
+ appToken: this.state.token,
103
+ deviceMetadata: this._getDeviceMetadata(),
104
+ }),
78
105
  });
106
+ // Every connection — automatic reconnection or a manual `socket.connect()` after
107
+ // `disconnect()` — goes through `Manager.open`, which builds the transport from
108
+ // `opts`: refresh the headers there, or a sign-in after the first connect never reached it
109
+ const manager = socket.io;
110
+ const open = manager.open.bind(manager);
111
+ manager.open = (...args) => {
112
+ manager.opts.extraHeaders = headers();
113
+ return open(...args);
114
+ };
115
+ return socket;
79
116
  });
80
117
  }
81
118
  }
@@ -1,4 +1,39 @@
1
1
  import type { Socket } from 'socket.io-client';
2
+ /**
3
+ * @interface IWsNotificationAttribute
4
+ * @property {string} identifier - Attribute marker. Example: "title".
5
+ * @property {string} type - Attribute type. Example: "string".
6
+ * @property {unknown} value - Attribute value as the platform sent it.
7
+ * @description An attribute carried by a notification.
8
+ */
9
+ interface IWsNotificationAttribute {
10
+ identifier: string;
11
+ type: string;
12
+ value: unknown;
13
+ }
14
+ /**
15
+ * @interface IWsNotification
16
+ * @property {string} message - Notification text; an empty string when the event has none.
17
+ * @property {string} [type] - What the notification is about. Example: "product", "order", "user", "form", "refund".
18
+ * @property {IWsNotificationAttribute[]} [attributes] - Attributes selected for the notification in the event settings.
19
+ * @description Payload of the `notification` event. Fields beyond `message` depend on the event
20
+ * (`product`, `order`, `user`, `formData`, …) and are typed `unknown` until checked.
21
+ */
22
+ interface IWsNotification {
23
+ message: string;
24
+ type?: string;
25
+ attributes?: IWsNotificationAttribute[];
26
+ [key: string]: unknown;
27
+ }
28
+ /**
29
+ * @interface IWsServerEvents
30
+ * @property {function(IWsNotification): void} notification - Event notification sent by the platform.
31
+ * @description Events the platform sends over the socket. Other event names stay untyped.
32
+ */
33
+ interface IWsServerEvents {
34
+ notification: (payload: IWsNotification) => void;
35
+ [event: string]: (...args: any[]) => void;
36
+ }
2
37
  /**
3
38
  * @interface IWS
4
39
  * @description This interface defines a method for establishing a WebSocket connection.
@@ -7,10 +42,12 @@ interface IWS {
7
42
  /**
8
43
  * Creates an instance of an object Socket.io with a connection.
9
44
  * @handleName connect
10
- * @returns {Socket} Returns a Socket instance.
11
- * @description Creates an instance of an object Socket.io with a connection. This method requires user authorization.
45
+ * @returns {Socket<IWsServerEvents>} Returns a Socket instance.
46
+ * @description Opens a Socket.io connection. Without a signed-in user the socket is a guest and
47
+ * receives only notifications sent to everyone; personal ones need `AuthProvider.auth` first.
48
+ * Every call opens a separate connection.
12
49
  * @see For more information about configuring the {@link https://js-sdk.oneentry.cloud/docs/category/authprovider authorization module}, see the documentation in the {@link https://js-sdk.oneentry.cloud/docs/category/authprovider configuration settings section of the SDK}.
13
50
  */
14
- connect(): Socket;
51
+ connect(): Socket<IWsServerEvents>;
15
52
  }
16
- export type { IWS };
53
+ export type { IWS, IWsNotification, IWsNotificationAttribute, IWsServerEvents };
@@ -77,14 +77,7 @@ export default class AdminsApi extends AsyncModules {
77
77
  offset,
78
78
  limit,
79
79
  };
80
- const savedUrl = this._url;
81
- this._url = this._adminsUrl;
82
- try {
83
- const response = await this._fetchPost(`/vector/search?` + this._queryParamsToString(query), body);
84
- return this._normalizeData(response, langCode);
85
- }
86
- finally {
87
- this._url = savedUrl;
88
- }
80
+ const response = await this._withBaseUrl(this._adminsUrl)._fetchPost(`/vector/search?` + this._queryParamsToString(query), body);
81
+ return this._normalizeData(response, langCode);
89
82
  }
90
83
  }
@@ -94,10 +94,10 @@ interface IPosition {
94
94
  * @interface IAdminEntity
95
95
  * @property {number} id - Object ID. Example: 1764.
96
96
  * @property {number | null} attributeSetId - ID of the attribute set in use. Example: 120.
97
- * @property {string} identifier - Text identifier (marker) of the object. Example: "admin1".
97
+ * @property {string} [identifier] - Not returned by the Content API: it was the admin's sign-in login, and the platform no longer sends it. Kept optional for compatibility.
98
98
  * @property {string | null} attributeSetIdentifier - Marker of the attribute set. Example: "admins".
99
99
  * @property {number | null} position - Position used for sorting. Example: 1.
100
- * @property {boolean} isSync - Whether the page is indexed. Example: true.
100
+ * @property {boolean} isSync - Whether the admin has attribute data in the requested language (`false` with empty `attributeValues` otherwise). Example: true.
101
101
  * @property {IAttributeValues} attributeValues - Attribute values keyed by attribute marker.
102
102
  * @example
103
103
  [
@@ -108,19 +108,19 @@ interface IPosition {
108
108
  }
109
109
  }
110
110
  ]
111
- * @property {IFormConfig[]} [moduleFormConfigs] - Form configurations of the module associated with the admin.
111
+ * @property {IFormConfig[]} [formModuleConfigs] - Form configurations of the module associated with the admin (the API key is `formModuleConfigs`). Example: [].
112
112
  * @property {number} [distance] - Cosine distance to the query. Returned only by the semantic (vector) search endpoint when `debug: true` is passed in the search body. Example: 0.12.
113
113
  * @description This interface captures the essential details and additional attributes of an admin entity.
114
114
  */
115
115
  interface IAdminEntity {
116
116
  id: number;
117
117
  attributeSetId: number | null;
118
- identifier: string;
118
+ identifier?: string;
119
119
  attributeSetIdentifier: string | null;
120
120
  position: number | null;
121
121
  isSync: boolean;
122
122
  attributeValues: IAttributeValues;
123
- moduleFormConfigs?: IFormConfig[];
123
+ formModuleConfigs?: IFormConfig[];
124
124
  distance?: number;
125
125
  }
126
126
  /**
@@ -10,12 +10,12 @@ import { z } from 'zod';
10
10
  export declare const AdminEntitySchema: z.ZodObject<{
11
11
  id: z.ZodNumber;
12
12
  attributeSetId: z.ZodNullable<z.ZodNumber>;
13
- identifier: z.ZodString;
13
+ identifier: z.ZodOptional<z.ZodString>;
14
14
  attributeSetIdentifier: z.ZodNullable<z.ZodString>;
15
15
  position: z.ZodNullable<z.ZodNumber>;
16
16
  isSync: z.ZodBoolean;
17
17
  attributeValues: z.ZodRecord<z.ZodString, z.ZodUnknown>;
18
- moduleFormConfigs: z.ZodOptional<z.ZodArray<z.ZodAny>>;
18
+ formModuleConfigs: z.ZodOptional<z.ZodArray<z.ZodAny>>;
19
19
  distance: z.ZodOptional<z.ZodNumber>;
20
20
  }, z.core.$strip>;
21
21
  /**
@@ -24,11 +24,11 @@ export declare const AdminEntitySchema: z.ZodObject<{
24
24
  export declare const AdminsResponseSchema: z.ZodArray<z.ZodObject<{
25
25
  id: z.ZodNumber;
26
26
  attributeSetId: z.ZodNullable<z.ZodNumber>;
27
- identifier: z.ZodString;
27
+ identifier: z.ZodOptional<z.ZodString>;
28
28
  attributeSetIdentifier: z.ZodNullable<z.ZodString>;
29
29
  position: z.ZodNullable<z.ZodNumber>;
30
30
  isSync: z.ZodBoolean;
31
31
  attributeValues: z.ZodRecord<z.ZodString, z.ZodUnknown>;
32
- moduleFormConfigs: z.ZodOptional<z.ZodArray<z.ZodAny>>;
32
+ formModuleConfigs: z.ZodOptional<z.ZodArray<z.ZodAny>>;
33
33
  distance: z.ZodOptional<z.ZodNumber>;
34
34
  }, z.core.$strip>>;
@@ -11,12 +11,12 @@ import { AttributeValuesSchema } from '../base/validation.js';
11
11
  export const AdminEntitySchema = z.object({
12
12
  id: z.number(),
13
13
  attributeSetId: z.number().nullable(),
14
- identifier: z.string(),
14
+ identifier: z.string().optional(),
15
15
  attributeSetIdentifier: z.string().nullable(),
16
16
  position: z.number().nullable(),
17
17
  isSync: z.boolean(),
18
18
  attributeValues: AttributeValuesSchema,
19
- moduleFormConfigs: z.array(z.any()).optional(),
19
+ formModuleConfigs: z.array(z.any()).optional(),
20
20
  distance: z.number().optional(),
21
21
  });
22
22
  /**
@@ -27,7 +27,7 @@ export default class AttributesSetsApi extends AsyncModules implements IAttribut
27
27
  * @param {number} [offset] - Number of records to skip. Default: 0.
28
28
  * @param {number} [limit] - Maximum number of records to return. Default: 30.
29
29
  * @param {number} [typeId] - ID of the attribute set type to filter by. Default: null.
30
- * @param {string} [sortBy] - Field to sort by: `id` or `position`. Default: "id".
30
+ * @param {string} [sortBy] - Field to sort by: `id` (descending) or `position`. Default: "id".
31
31
  * @returns {Promise<IAttributesSetsResponse | IError>} Returns object with array of IAttributeSetsEntity and total items count.
32
32
  * @throws {IError} When isShell=false and an error occurs during the fetch
33
33
  * @see {@link https://js-sdk.oneentry.cloud/docs/attribute-sets/getAttributes getAttributes} documentation.
@@ -27,7 +27,7 @@ export default class AttributesSetsApi extends AsyncModules {
27
27
  * @param {number} [offset] - Number of records to skip. Default: 0.
28
28
  * @param {number} [limit] - Maximum number of records to return. Default: 30.
29
29
  * @param {number} [typeId] - ID of the attribute set type to filter by. Default: null.
30
- * @param {string} [sortBy] - Field to sort by: `id` or `position`. Default: "id".
30
+ * @param {string} [sortBy] - Field to sort by: `id` (descending) or `position`. Default: "id".
31
31
  * @returns {Promise<IAttributesSetsResponse | IError>} Returns object with array of IAttributeSetsEntity and total items count.
32
32
  * @throws {IError} When isShell=false and an error occurs during the fetch
33
33
  * @see {@link https://js-sdk.oneentry.cloud/docs/attribute-sets/getAttributes getAttributes} documentation.
@@ -58,7 +58,7 @@ export default class AttributesSetsApi extends AsyncModules {
58
58
  * @see {@link https://js-sdk.oneentry.cloud/docs/attribute-sets/getAttributesByMarker getAttributesByMarker} documentation.
59
59
  */
60
60
  async getAttributesByMarker(marker, langCode = this.state.lang) {
61
- const result = await this._fetchGet(`/${marker}/attributes?langCode=${langCode}`);
61
+ const result = await this._fetchGet(`/${this._pathSegment(marker)}/attributes?langCode=${encodeURIComponent(langCode)}`);
62
62
  // Validate response if validation is enabled
63
63
  const validated = await this._validateResponse(result, schema('AttributesArrayResponseSchema'));
64
64
  return this._normalizeData(validated, langCode);
@@ -74,7 +74,7 @@ export default class AttributesSetsApi extends AsyncModules {
74
74
  * @see {@link https://js-sdk.oneentry.cloud/docs/attribute-sets/getSingleAttributeByMarkerSet getSingleAttributeByMarkerSet} documentation.
75
75
  */
76
76
  async getSingleAttributeByMarkerSet(setMarker, attributeMarker, langCode = this.state.lang) {
77
- const result = await this._fetchGet(`/${setMarker}/attributes/${attributeMarker}?langCode=${langCode}`);
77
+ const result = await this._fetchGet(`/${this._pathSegment(setMarker)}/attributes/${this._pathSegment(attributeMarker)}?langCode=${encodeURIComponent(langCode)}`);
78
78
  // Validate response if validation is enabled
79
79
  const validated = await this._validateResponse(result, schema('AttributeEntitySchema'));
80
80
  return this._normalizeData(validated, langCode);
@@ -89,7 +89,7 @@ export default class AttributesSetsApi extends AsyncModules {
89
89
  * @see {@link https://js-sdk.oneentry.cloud/docs/attribute-sets/getAttributeSetByMarker getAttributeSetByMarker} documentation.
90
90
  */
91
91
  async getAttributeSetByMarker(marker, langCode = this.state.lang) {
92
- const result = await this._fetchGet(`/marker/${marker}?langCode=${langCode}`);
92
+ const result = await this._fetchGet(`/marker/${this._pathSegment(marker)}?langCode=${encodeURIComponent(langCode)}`);
93
93
  // Validate response if validation is enabled
94
94
  const validated = await this._validateResponse(result, schema('AttributeSetEntitySchema'));
95
95
  return this._normalizeData(validated, langCode);