@retailcrm/embed-ui 0.4.3 → 0.4.4

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/CHANGELOG.md CHANGED
@@ -1,6 +1,17 @@
1
1
  # Changelog
2
2
 
3
3
 
4
+ ## [0.4.4](https://github.com/retailcrm/embed-ui/compare/v0.4.3...v0.4.4) (2024-12-06)
5
+
6
+ ### Features
7
+
8
+ * **v1-contexts:** Reactive contexts logic moved to a separated package ([025c68b](https://github.com/retailcrm/embed-ui/commit/025c68bad92c33fb2ef9c84ea41fc0b76a77b041))
9
+ * **v1-testing:** Package for testing utils ([2670e5a](https://github.com/retailcrm/embed-ui/commit/2670e5a2a8d67e4538c0005c271a663aa881ba07))
10
+ * **v1-types:** Package for basic types ([a80bf8f](https://github.com/retailcrm/embed-ui/commit/a80bf8f3046ec93cb130e0e247a56d0eae3b4902))
11
+
12
+ ### Bug Fixes
13
+
14
+ * **v1-components:** Updated @omnicajs/vue-remote to v0.2.3 with fixed logic of TouchEvent serialization ([09d447f](https://github.com/retailcrm/embed-ui/commit/09d447f3f82f554fb3b5bb1ad7eeac7b55abe49e))
4
15
  ## [0.4.3](https://github.com/retailcrm/embed-ui/compare/v0.4.2...v0.4.3) (2024-12-03)
5
16
  ## [0.4.2](https://github.com/retailcrm/embed-ui/compare/v0.4.1...v0.4.2) (2024-12-02)
6
17
 
package/Makefile CHANGED
@@ -14,8 +14,7 @@ node_modules: package.json yarn.lock ## Installs dependencies
14
14
  .PHONY: build
15
15
  build: ## Builds the package
16
16
  $(TARGET_HEADER)
17
- $(YARN) build
18
- $(YARN) generate:meta
17
+ $(YARN) workspaces foreach -A --topological-dev run build
19
18
 
20
19
  .PHONY: release
21
20
  release: ## Bumps version and creates tag
package/dist/index.cjs CHANGED
@@ -2,305 +2,23 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const rpc = require("@remote-ui/rpc");
4
4
  const pinia = require("pinia");
5
- const remote = require("@omnicajs/vue-remote/remote");
5
+ const remote$1 = require("@omnicajs/vue-remote/remote");
6
+ const remote = require("@retailcrm/embed-ui-v1-contexts/remote");
7
+ const card = require("@retailcrm/embed-ui-v1-contexts/remote/customer/card");
8
+ const cardPhone = require("@retailcrm/embed-ui-v1-contexts/remote/customer/card-phone");
9
+ const card$1 = require("@retailcrm/embed-ui-v1-contexts/remote/order/card");
10
+ const current = require("@retailcrm/embed-ui-v1-contexts/remote/user/current");
11
+ const settings = require("@retailcrm/embed-ui-v1-contexts/remote/settings");
6
12
  const vue = require("vue");
7
- const injectEndpoint = (endpoint) => {
8
- return (context) => {
9
- context.store.endpoint = endpoint;
10
- };
11
- };
12
- const keysOf = (o) => Object.keys(o);
13
- const defineContext = (id, schema2) => {
14
- return pinia.defineStore(id, {
15
- state() {
16
- return {
17
- ...keysOf(schema2).reduce((state, field) => ({
18
- ...state,
19
- [field]: schema2[field].defaults()
20
- }), {})
21
- };
22
- },
23
- getters: {
24
- schema: () => schema2
25
- },
26
- actions: {
27
- async initialize() {
28
- const context = this;
29
- const endpoint = this.endpoint;
30
- const state = await endpoint.call.get(id, "~");
31
- keysOf(schema2).forEach((field) => {
32
- context[field] = state[field];
33
- endpoint.call.on(id, `change:${field}`, (value) => {
34
- context[field] = value;
35
- });
36
- });
37
- },
38
- set(field, value) {
39
- if (!(field in schema2)) {
40
- throw new Error(`[crm:embed:remote] Field ${String(field)} is not present in context ${id}`);
41
- }
42
- if (schema2[field].readonly) {
43
- throw new Error(`[crm:embed:remote] Field ${String(field)} is readonly in context ${id}`);
44
- }
45
- if (!schema2[field].accepts(value)) {
46
- throw new Error(`[crm:embed:remote] Invalid value for field ${String(field)} in context ${id}`);
47
- }
48
- const context = this;
49
- const endpoint = this.endpoint;
50
- context[field] = value;
51
- endpoint.call.set(id, field, value);
52
- }
53
- }
54
- });
55
- };
56
- const withMeta = (predicate, type) => {
57
- return Object.assign(predicate, { type });
58
- };
59
- const isExactly = (expected) => {
60
- return withMeta((value) => value === expected, JSON.stringify(expected));
61
- };
62
- const isNull = withMeta((value) => value === null, "null");
63
- const isNumber = withMeta((value) => typeof value === "number", "number");
64
- const isString = withMeta((value) => typeof value === "string", "string");
65
- const arrayOf = (predicate) => withMeta(
66
- (value) => {
67
- return Array.isArray(value) && value.every(predicate);
68
- },
69
- `Array<${predicate.type}>`
70
- );
71
- const oneOf = (...predicates) => withMeta(
72
- (value) => {
73
- return predicates.some((predicate) => predicate(value));
74
- },
75
- predicates.map((p) => p.type).join(" | ")
76
- );
77
- const schema$4 = {
78
- "id": {
79
- accepts: oneOf(isNumber, isNull),
80
- defaults: () => null,
81
- readonly: true
82
- },
83
- "email": {
84
- accepts: isString,
85
- defaults: () => "",
86
- readonly: true
87
- },
88
- "firstName": {
89
- accepts: oneOf(isString, isNull),
90
- defaults: () => null,
91
- readonly: true
92
- },
93
- "lastName": {
94
- accepts: oneOf(isString, isNull),
95
- defaults: () => null,
96
- readonly: true
97
- },
98
- "patronymic": {
99
- accepts: oneOf(isString, isNull),
100
- defaults: () => null,
101
- readonly: true
102
- },
103
- "photo": {
104
- accepts: oneOf(isString, isNull),
105
- defaults: () => null,
106
- readonly: true
107
- },
108
- "groups": {
109
- accepts: arrayOf(isString),
110
- defaults: () => [],
111
- readonly: true
112
- },
113
- "permissions": {
114
- accepts: arrayOf(isString),
115
- defaults: () => [],
116
- readonly: true
117
- }
118
- };
119
- const useContext$4 = defineContext("user/current", schema$4);
120
- const schema$3 = {
121
- "id": {
122
- accepts: oneOf(isNumber, isNull),
123
- defaults: () => null,
124
- readonly: true
125
- },
126
- "externalId": {
127
- accepts: isString,
128
- defaults: () => null,
129
- readonly: true
130
- },
131
- "email": {
132
- accepts: isString,
133
- defaults: () => "",
134
- readonly: true
135
- },
136
- "phones": {
137
- accepts: arrayOf(isString),
138
- defaults: () => [],
139
- readonly: true
140
- }
141
- };
142
- const useContext$3 = defineContext("customer/card", schema$3);
143
- const schema$2 = {
144
- value: {
145
- accepts: isString,
146
- defaults: () => "",
147
- readonly: true
148
- },
149
- index: {
150
- accepts: isNumber,
151
- defaults: () => 0,
152
- readonly: true
153
- }
154
- };
155
- const useContext$2 = defineContext("customer/card:phone", schema$2);
156
- const schema$1 = {
157
- "id": {
158
- accepts: oneOf(isNumber, isNull),
159
- defaults: () => null,
160
- readonly: true
161
- },
162
- "externalId": {
163
- accepts: oneOf(isString, isNull),
164
- defaults: () => null,
165
- readonly: true
166
- },
167
- "type": {
168
- accepts: oneOf(isString, isNull),
169
- defaults: () => null,
170
- readonly: true
171
- },
172
- "site": {
173
- accepts: oneOf(isString, isNull),
174
- defaults: () => null,
175
- readonly: true
176
- },
177
- "number": {
178
- accepts: oneOf(isString, isNull),
179
- defaults: () => null,
180
- readonly: true
181
- },
182
- "customer.type": {
183
- accepts: oneOf(
184
- isExactly("customer"),
185
- isExactly("customer_corporate")
186
- ),
187
- defaults: () => "customer",
188
- readonly: true
189
- },
190
- "customer.lastName": {
191
- accepts: oneOf(isString, isNull),
192
- defaults: () => null,
193
- readonly: false
194
- },
195
- "customer.firstName": {
196
- accepts: oneOf(isString, isNull),
197
- defaults: () => null,
198
- readonly: false
199
- },
200
- "customer.patronymic": {
201
- accepts: oneOf(isString, isNull),
202
- defaults: () => null,
203
- readonly: false
204
- },
205
- "customer.phone": {
206
- accepts: oneOf(isString, isNull),
207
- defaults: () => null,
208
- readonly: false
209
- },
210
- "customer.email": {
211
- accepts: oneOf(isString, isNull),
212
- defaults: () => null,
213
- readonly: false
214
- },
215
- "country": {
216
- accepts: oneOf(isString, isNull),
217
- defaults: () => null,
218
- readonly: true
219
- },
220
- "currency": {
221
- accepts: isString,
222
- defaults: () => "",
223
- readonly: true
224
- },
225
- "status": {
226
- accepts: isString,
227
- defaults: () => "",
228
- readonly: true
229
- },
230
- "company.name": {
231
- accepts: oneOf(isString, isNull),
232
- defaults: () => null,
233
- readonly: false
234
- },
235
- "company.legalName": {
236
- accepts: oneOf(isString, isNull),
237
- defaults: () => null,
238
- readonly: false
239
- },
240
- "company.legalAddress": {
241
- accepts: oneOf(isString, isNull),
242
- defaults: () => null,
243
- readonly: false
244
- },
245
- "company.INN": {
246
- accepts: oneOf(isString, isNull),
247
- defaults: () => null,
248
- readonly: false
249
- },
250
- "company.OKPO": {
251
- accepts: oneOf(isString, isNull),
252
- defaults: () => null,
253
- readonly: false
254
- },
255
- "company.BIK": {
256
- accepts: oneOf(isString, isNull),
257
- defaults: () => null,
258
- readonly: false
259
- },
260
- "company.bank": {
261
- accepts: oneOf(isString, isNull),
262
- defaults: () => null,
263
- readonly: false
264
- },
265
- "company.bankAddress": {
266
- accepts: oneOf(isString, isNull),
267
- defaults: () => null,
268
- readonly: false
269
- },
270
- "company.corrAccount": {
271
- accepts: oneOf(isString, isNull),
272
- defaults: () => null,
273
- readonly: false
274
- },
275
- "company.bankAccount": {
276
- accepts: oneOf(isString, isNull),
277
- defaults: () => null,
278
- readonly: false
279
- },
280
- "delivery.address": {
281
- accepts: oneOf(isString, isNull),
282
- defaults: () => null,
283
- readonly: false
284
- }
285
- };
286
- const useContext$1 = defineContext("order/card", schema$1);
287
- const locales = ["en-GB", "es-ES", "ru-RU"];
288
- const schema = {
289
- "system.locale": {
290
- accepts: oneOf(...locales.map(isExactly)),
291
- defaults: () => "en-GB",
292
- readonly: true
293
- }
294
- };
295
- const useContext = defineContext("settings", schema);
296
- const useField = (store, field) => {
13
+ const useField = (store, field, onReject = null) => {
297
14
  if (store.schema[field].readonly) {
298
15
  return vue.computed(() => store[field]);
299
16
  }
300
17
  const set = store.set;
18
+ const _onReject = (rejection) => console.error(rejection);
301
19
  return vue.computed({
302
20
  get: () => store[field],
303
- set: (value) => set(field, value)
21
+ set: (value) => set(field, value, onReject ?? _onReject)
304
22
  });
305
23
  };
306
24
  const useInternal = pinia.defineStore("@retailcrm/embed-ui/_internal", {});
@@ -308,12 +26,13 @@ const useHost = () => {
308
26
  const store = useInternal();
309
27
  return {
310
28
  httpCall(action, payload = void 0) {
311
- return payload ? store.endpoint.call.httpCall(action, payload) : store.endpoint.call.httpCall(action);
29
+ const endpoint = store.endpoint;
30
+ return payload ? endpoint.call.httpCall(action, payload) : endpoint.call.httpCall(action);
312
31
  }
313
32
  };
314
33
  };
315
34
  const createRoot = async (channel) => {
316
- const root = remote.createRemoteRoot(channel, {
35
+ const root = remote$1.createRemoteRoot(channel, {
317
36
  components: [
318
37
  "UiButton",
319
38
  "UiError",
@@ -336,7 +55,7 @@ const createRoot = async (channel) => {
336
55
  const createWidgetEndpoint = (widget, messenger) => {
337
56
  const endpoint = rpc.createEndpoint(messenger);
338
57
  const pinia$1 = pinia.createPinia();
339
- pinia$1.use(injectEndpoint(endpoint));
58
+ pinia$1.use(remote.injectEndpoint(endpoint));
340
59
  let onRelease = () => {
341
60
  };
342
61
  endpoint.expose({
@@ -344,7 +63,7 @@ const createWidgetEndpoint = (widget, messenger) => {
344
63
  rpc.retain(channel);
345
64
  const root = await createRoot(channel);
346
65
  await root.mount();
347
- const { createApp } = remote.createRemoteRenderer(root);
66
+ const { createApp } = remote$1.createRemoteRenderer(root);
348
67
  const destroy = await widget.run(createApp, root, pinia$1, target);
349
68
  onRelease = () => {
350
69
  destroy();
@@ -359,16 +78,46 @@ const createWidgetEndpoint = (widget, messenger) => {
359
78
  });
360
79
  return endpoint;
361
80
  };
81
+ Object.defineProperty(exports, "customerCardSchema", {
82
+ enumerable: true,
83
+ get: () => card.schema
84
+ });
85
+ Object.defineProperty(exports, "useCustomerCardContext", {
86
+ enumerable: true,
87
+ get: () => card.useContext
88
+ });
89
+ Object.defineProperty(exports, "customerCardPhoneSchema", {
90
+ enumerable: true,
91
+ get: () => cardPhone.schema
92
+ });
93
+ Object.defineProperty(exports, "useCustomerCardPhoneContext", {
94
+ enumerable: true,
95
+ get: () => cardPhone.useContext
96
+ });
97
+ Object.defineProperty(exports, "orderCardSchema", {
98
+ enumerable: true,
99
+ get: () => card$1.schema
100
+ });
101
+ Object.defineProperty(exports, "useOrderCardContext", {
102
+ enumerable: true,
103
+ get: () => card$1.useContext
104
+ });
105
+ Object.defineProperty(exports, "currentUserSchema", {
106
+ enumerable: true,
107
+ get: () => current.schema
108
+ });
109
+ Object.defineProperty(exports, "useCurrentUserContext", {
110
+ enumerable: true,
111
+ get: () => current.useContext
112
+ });
113
+ Object.defineProperty(exports, "settingsSchema", {
114
+ enumerable: true,
115
+ get: () => settings.schema
116
+ });
117
+ Object.defineProperty(exports, "useSettingsContext", {
118
+ enumerable: true,
119
+ get: () => settings.useContext
120
+ });
362
121
  exports.createWidgetEndpoint = createWidgetEndpoint;
363
- exports.currentUserSchema = schema$4;
364
- exports.customerCardPhoneSchema = schema$2;
365
- exports.customerCardSchema = schema$3;
366
- exports.orderCardSchema = schema$1;
367
- exports.settingsSchema = schema;
368
- exports.useCurrentUserContext = useContext$4;
369
- exports.useCustomerCardContext = useContext$3;
370
- exports.useCustomerCardPhoneContext = useContext$2;
371
122
  exports.useField = useField;
372
123
  exports.useHost = useHost;
373
- exports.useOrderCardContext = useContext$1;
374
- exports.useSettingsContext = useContext;
package/dist/index.mjs CHANGED
@@ -1,304 +1,22 @@
1
1
  import { createEndpoint, retain, release } from "@remote-ui/rpc";
2
2
  import { defineStore, createPinia } from "pinia";
3
3
  import { createRemoteRenderer, createRemoteRoot } from "@omnicajs/vue-remote/remote";
4
+ import { injectEndpoint } from "@retailcrm/embed-ui-v1-contexts/remote";
5
+ import { schema, useContext } from "@retailcrm/embed-ui-v1-contexts/remote/customer/card";
6
+ import { schema as schema2, useContext as useContext2 } from "@retailcrm/embed-ui-v1-contexts/remote/customer/card-phone";
7
+ import { schema as schema3, useContext as useContext3 } from "@retailcrm/embed-ui-v1-contexts/remote/order/card";
8
+ import { schema as schema4, useContext as useContext4 } from "@retailcrm/embed-ui-v1-contexts/remote/user/current";
9
+ import { schema as schema5, useContext as useContext5 } from "@retailcrm/embed-ui-v1-contexts/remote/settings";
4
10
  import { computed } from "vue";
5
- const injectEndpoint = (endpoint) => {
6
- return (context) => {
7
- context.store.endpoint = endpoint;
8
- };
9
- };
10
- const keysOf = (o) => Object.keys(o);
11
- const defineContext = (id, schema2) => {
12
- return defineStore(id, {
13
- state() {
14
- return {
15
- ...keysOf(schema2).reduce((state, field) => ({
16
- ...state,
17
- [field]: schema2[field].defaults()
18
- }), {})
19
- };
20
- },
21
- getters: {
22
- schema: () => schema2
23
- },
24
- actions: {
25
- async initialize() {
26
- const context = this;
27
- const endpoint = this.endpoint;
28
- const state = await endpoint.call.get(id, "~");
29
- keysOf(schema2).forEach((field) => {
30
- context[field] = state[field];
31
- endpoint.call.on(id, `change:${field}`, (value) => {
32
- context[field] = value;
33
- });
34
- });
35
- },
36
- set(field, value) {
37
- if (!(field in schema2)) {
38
- throw new Error(`[crm:embed:remote] Field ${String(field)} is not present in context ${id}`);
39
- }
40
- if (schema2[field].readonly) {
41
- throw new Error(`[crm:embed:remote] Field ${String(field)} is readonly in context ${id}`);
42
- }
43
- if (!schema2[field].accepts(value)) {
44
- throw new Error(`[crm:embed:remote] Invalid value for field ${String(field)} in context ${id}`);
45
- }
46
- const context = this;
47
- const endpoint = this.endpoint;
48
- context[field] = value;
49
- endpoint.call.set(id, field, value);
50
- }
51
- }
52
- });
53
- };
54
- const withMeta = (predicate, type) => {
55
- return Object.assign(predicate, { type });
56
- };
57
- const isExactly = (expected) => {
58
- return withMeta((value) => value === expected, JSON.stringify(expected));
59
- };
60
- const isNull = withMeta((value) => value === null, "null");
61
- const isNumber = withMeta((value) => typeof value === "number", "number");
62
- const isString = withMeta((value) => typeof value === "string", "string");
63
- const arrayOf = (predicate) => withMeta(
64
- (value) => {
65
- return Array.isArray(value) && value.every(predicate);
66
- },
67
- `Array<${predicate.type}>`
68
- );
69
- const oneOf = (...predicates) => withMeta(
70
- (value) => {
71
- return predicates.some((predicate) => predicate(value));
72
- },
73
- predicates.map((p) => p.type).join(" | ")
74
- );
75
- const schema$4 = {
76
- "id": {
77
- accepts: oneOf(isNumber, isNull),
78
- defaults: () => null,
79
- readonly: true
80
- },
81
- "email": {
82
- accepts: isString,
83
- defaults: () => "",
84
- readonly: true
85
- },
86
- "firstName": {
87
- accepts: oneOf(isString, isNull),
88
- defaults: () => null,
89
- readonly: true
90
- },
91
- "lastName": {
92
- accepts: oneOf(isString, isNull),
93
- defaults: () => null,
94
- readonly: true
95
- },
96
- "patronymic": {
97
- accepts: oneOf(isString, isNull),
98
- defaults: () => null,
99
- readonly: true
100
- },
101
- "photo": {
102
- accepts: oneOf(isString, isNull),
103
- defaults: () => null,
104
- readonly: true
105
- },
106
- "groups": {
107
- accepts: arrayOf(isString),
108
- defaults: () => [],
109
- readonly: true
110
- },
111
- "permissions": {
112
- accepts: arrayOf(isString),
113
- defaults: () => [],
114
- readonly: true
115
- }
116
- };
117
- const useContext$4 = defineContext("user/current", schema$4);
118
- const schema$3 = {
119
- "id": {
120
- accepts: oneOf(isNumber, isNull),
121
- defaults: () => null,
122
- readonly: true
123
- },
124
- "externalId": {
125
- accepts: isString,
126
- defaults: () => null,
127
- readonly: true
128
- },
129
- "email": {
130
- accepts: isString,
131
- defaults: () => "",
132
- readonly: true
133
- },
134
- "phones": {
135
- accepts: arrayOf(isString),
136
- defaults: () => [],
137
- readonly: true
138
- }
139
- };
140
- const useContext$3 = defineContext("customer/card", schema$3);
141
- const schema$2 = {
142
- value: {
143
- accepts: isString,
144
- defaults: () => "",
145
- readonly: true
146
- },
147
- index: {
148
- accepts: isNumber,
149
- defaults: () => 0,
150
- readonly: true
151
- }
152
- };
153
- const useContext$2 = defineContext("customer/card:phone", schema$2);
154
- const schema$1 = {
155
- "id": {
156
- accepts: oneOf(isNumber, isNull),
157
- defaults: () => null,
158
- readonly: true
159
- },
160
- "externalId": {
161
- accepts: oneOf(isString, isNull),
162
- defaults: () => null,
163
- readonly: true
164
- },
165
- "type": {
166
- accepts: oneOf(isString, isNull),
167
- defaults: () => null,
168
- readonly: true
169
- },
170
- "site": {
171
- accepts: oneOf(isString, isNull),
172
- defaults: () => null,
173
- readonly: true
174
- },
175
- "number": {
176
- accepts: oneOf(isString, isNull),
177
- defaults: () => null,
178
- readonly: true
179
- },
180
- "customer.type": {
181
- accepts: oneOf(
182
- isExactly("customer"),
183
- isExactly("customer_corporate")
184
- ),
185
- defaults: () => "customer",
186
- readonly: true
187
- },
188
- "customer.lastName": {
189
- accepts: oneOf(isString, isNull),
190
- defaults: () => null,
191
- readonly: false
192
- },
193
- "customer.firstName": {
194
- accepts: oneOf(isString, isNull),
195
- defaults: () => null,
196
- readonly: false
197
- },
198
- "customer.patronymic": {
199
- accepts: oneOf(isString, isNull),
200
- defaults: () => null,
201
- readonly: false
202
- },
203
- "customer.phone": {
204
- accepts: oneOf(isString, isNull),
205
- defaults: () => null,
206
- readonly: false
207
- },
208
- "customer.email": {
209
- accepts: oneOf(isString, isNull),
210
- defaults: () => null,
211
- readonly: false
212
- },
213
- "country": {
214
- accepts: oneOf(isString, isNull),
215
- defaults: () => null,
216
- readonly: true
217
- },
218
- "currency": {
219
- accepts: isString,
220
- defaults: () => "",
221
- readonly: true
222
- },
223
- "status": {
224
- accepts: isString,
225
- defaults: () => "",
226
- readonly: true
227
- },
228
- "company.name": {
229
- accepts: oneOf(isString, isNull),
230
- defaults: () => null,
231
- readonly: false
232
- },
233
- "company.legalName": {
234
- accepts: oneOf(isString, isNull),
235
- defaults: () => null,
236
- readonly: false
237
- },
238
- "company.legalAddress": {
239
- accepts: oneOf(isString, isNull),
240
- defaults: () => null,
241
- readonly: false
242
- },
243
- "company.INN": {
244
- accepts: oneOf(isString, isNull),
245
- defaults: () => null,
246
- readonly: false
247
- },
248
- "company.OKPO": {
249
- accepts: oneOf(isString, isNull),
250
- defaults: () => null,
251
- readonly: false
252
- },
253
- "company.BIK": {
254
- accepts: oneOf(isString, isNull),
255
- defaults: () => null,
256
- readonly: false
257
- },
258
- "company.bank": {
259
- accepts: oneOf(isString, isNull),
260
- defaults: () => null,
261
- readonly: false
262
- },
263
- "company.bankAddress": {
264
- accepts: oneOf(isString, isNull),
265
- defaults: () => null,
266
- readonly: false
267
- },
268
- "company.corrAccount": {
269
- accepts: oneOf(isString, isNull),
270
- defaults: () => null,
271
- readonly: false
272
- },
273
- "company.bankAccount": {
274
- accepts: oneOf(isString, isNull),
275
- defaults: () => null,
276
- readonly: false
277
- },
278
- "delivery.address": {
279
- accepts: oneOf(isString, isNull),
280
- defaults: () => null,
281
- readonly: false
282
- }
283
- };
284
- const useContext$1 = defineContext("order/card", schema$1);
285
- const locales = ["en-GB", "es-ES", "ru-RU"];
286
- const schema = {
287
- "system.locale": {
288
- accepts: oneOf(...locales.map(isExactly)),
289
- defaults: () => "en-GB",
290
- readonly: true
291
- }
292
- };
293
- const useContext = defineContext("settings", schema);
294
- const useField = (store, field) => {
11
+ const useField = (store, field, onReject = null) => {
295
12
  if (store.schema[field].readonly) {
296
13
  return computed(() => store[field]);
297
14
  }
298
15
  const set = store.set;
16
+ const _onReject = (rejection) => console.error(rejection);
299
17
  return computed({
300
18
  get: () => store[field],
301
- set: (value) => set(field, value)
19
+ set: (value) => set(field, value, onReject ?? _onReject)
302
20
  });
303
21
  };
304
22
  const useInternal = defineStore("@retailcrm/embed-ui/_internal", {});
@@ -306,7 +24,8 @@ const useHost = () => {
306
24
  const store = useInternal();
307
25
  return {
308
26
  httpCall(action, payload = void 0) {
309
- return payload ? store.endpoint.call.httpCall(action, payload) : store.endpoint.call.httpCall(action);
27
+ const endpoint = store.endpoint;
28
+ return payload ? endpoint.call.httpCall(action, payload) : endpoint.call.httpCall(action);
310
29
  }
311
30
  };
312
31
  };
@@ -359,16 +78,16 @@ const createWidgetEndpoint = (widget, messenger) => {
359
78
  };
360
79
  export {
361
80
  createWidgetEndpoint,
362
- schema$4 as currentUserSchema,
363
- schema$2 as customerCardPhoneSchema,
364
- schema$3 as customerCardSchema,
365
- schema$1 as orderCardSchema,
366
- schema as settingsSchema,
367
- useContext$4 as useCurrentUserContext,
368
- useContext$3 as useCustomerCardContext,
369
- useContext$2 as useCustomerCardPhoneContext,
81
+ schema4 as currentUserSchema,
82
+ schema2 as customerCardPhoneSchema,
83
+ schema as customerCardSchema,
84
+ schema3 as orderCardSchema,
85
+ schema5 as settingsSchema,
86
+ useContext4 as useCurrentUserContext,
87
+ useContext as useCustomerCardContext,
88
+ useContext2 as useCustomerCardPhoneContext,
370
89
  useField,
371
90
  useHost,
372
- useContext$1 as useOrderCardContext,
373
- useContext as useSettingsContext
91
+ useContext3 as useOrderCardContext,
92
+ useContext5 as useSettingsContext
374
93
  };
package/dist/meta.json CHANGED
@@ -723,24 +723,24 @@
723
723
  ],
724
724
  "contextsUsage": {
725
725
  "customer/card": {
726
- "import": "import { useCustomerCardContext } from '@retailcrm/embed-ui'",
727
- "call": "const customer = useCustomerCardContext()"
726
+ "import": "import { useContext } from '@retailcrm/embed-ui-v1-contexts/remote/customer/card'",
727
+ "call": "const customer = useContext()"
728
728
  },
729
729
  "customer/card:phone": {
730
- "import": "import { useCustomerCardPhoneContext } from '@retailcrm/embed-ui'",
731
- "call": "const phone = useCustomerCardPhoneContext()"
730
+ "import": "import { useContext } from '@retailcrm/embed-ui-v1-contexts/remote/customer/card-phone'",
731
+ "call": "const phone = useContext()"
732
732
  },
733
733
  "order/card": {
734
- "import": "import { useOrderCardContext } from '@retailcrm/embed-ui'",
735
- "call": "const order = useOrderCardContext()"
734
+ "import": "import { useContext } from '@retailcrm/embed-ui-v1-contexts/remote/order/card'",
735
+ "call": "const order = useContext()"
736
736
  },
737
737
  "user/current": {
738
- "import": "import { useCurrentUserContext } from '@retailcrm/embed-ui'",
739
- "call": "const user = useCurrentUserContext()"
738
+ "import": "import { useContext } from '@retailcrm/embed-ui-v1-contexts/remote/user/current'",
739
+ "call": "const user = useContext()"
740
740
  },
741
741
  "settings": {
742
- "import": "import { useSettingsContext } from '@retailcrm/embed-ui'",
743
- "call": "const settings = useSettingsContext()"
742
+ "import": "import { useContext } from '@retailcrm/embed-ui-v1-contexts/remote/settings'",
743
+ "call": "const settings = useContext()"
744
744
  }
745
745
  }
746
746
  }
package/index.d.ts CHANGED
@@ -1,38 +1,41 @@
1
- import type { Callable } from './types/host/callable'
2
- import type { ComputedRef } from 'vue'
3
- import type { Context } from './types/context/schema'
4
- import type { ContextAccessor } from './types/context/schema'
5
- import type { ContextSchema } from './types/context/schema'
6
- import type { Endpoint, RemoteCallable } from '@remote-ui/rpc'
7
- import type { IsReadonly } from './types/context/schema'
8
- import type { MessageEndpoint } from '@remote-ui/rpc'
9
- import type { Schema as CustomerCardSchema } from './types/context/customer/card'
10
- import type { Schema as CustomerCardPhoneSchema } from './types/context/customer/card-phone'
11
- import type { Schema as OrderCardSchema } from './types/context/order/card'
12
- import type { Schema as CurrentUserSchema } from './types/context/user/current'
13
- import type { Schema as SettingsSchema } from './types/context/settings'
14
- import type { SchemaList } from './types/context'
1
+ import type {
2
+ ComputedRef,
3
+ WritableComputedRef,
4
+ } from 'vue'
5
+
6
+ import type {
7
+ Endpoint,
8
+ MessageEndpoint,
9
+ RemoteCallable,
10
+ } from '@remote-ui/rpc'
11
+
12
+ import type {
13
+ Context,
14
+ ContextAccessor,
15
+ ContextSchema,
16
+ IsReadonly,
17
+ RejectionHandler,
18
+ TypeOf,
19
+ } from '@retailcrm/embed-ui-v1-types/context'
20
+
21
+ import type { Schema as CustomerCardSchema } from '@retailcrm/embed-ui-v1-contexts/types/customer/card'
22
+ import type { Schema as CustomerCardPhoneSchema } from '@retailcrm/embed-ui-v1-contexts/types/customer/card-phone'
23
+ import type { Schema as OrderCardSchema } from '@retailcrm/embed-ui-v1-contexts/types/order/card'
24
+ import type { Schema as CurrentUserSchema } from '@retailcrm/embed-ui-v1-contexts/types/user/current'
25
+ import type { Schema as SettingsSchema } from '@retailcrm/embed-ui-v1-contexts/types/settings'
26
+
27
+ import type { SchemaList } from '@retailcrm/embed-ui-v1-contexts/types'
28
+
15
29
  import type { Store } from 'pinia'
16
30
  import type { StoreDefinition } from 'pinia'
17
- import type { TypeOf } from './types/context/schema'
18
- import type { WidgetRunner } from './types/widget'
19
- import type { WritableComputedRef } from 'vue'
20
31
 
21
- declare type Computed<
22
- S extends ContextSchema,
23
- F extends keyof S
24
- > = IsReadonly<S[F]> extends true ? ComputedRef<TypeOf<S[F]>> : WritableComputedRef<TypeOf<S[F]>>;
32
+ import type { Callable } from './types/host/callable'
33
+ import type { WidgetRunner } from './types/widget'
25
34
 
26
35
  export declare const createWidgetEndpoint: (
27
36
  widget: WidgetRunner,
28
37
  messenger: MessageEndpoint
29
- ) => Endpoint<ContextAccessor<SchemaList>>
30
-
31
- export declare const customerCardPhoneSchema: CustomerCardPhoneSchema
32
- export declare const customerCardSchema: CustomerCardSchema
33
- export declare const orderCardSchema: OrderCardSchema
34
- export declare const currentUserSchema: CurrentUserSchema
35
- export declare const settingsSchema: SettingsSchema
38
+ ) => Endpoint<ContextAccessor<SchemaList> & Callable>
36
39
 
37
40
  export type ContextStore<S extends ContextSchema> = Store<string, Context<S>, {
38
41
  schema(): S;
@@ -51,16 +54,13 @@ export type ContextStoreDefinition<
51
54
  set<F extends keyof S>(field: F, value: TypeOf<S[F]>): void;
52
55
  }>
53
56
 
54
- export declare const useCustomerCardContext: ContextStoreDefinition<'customer/card', CustomerCardSchema>
55
- export declare const useCustomerCardPhoneContext: ContextStoreDefinition<'customer/card:phone', CustomerCardPhoneSchema>
56
- export declare const useOrderCardContext: ContextStoreDefinition<'order/card', OrderCardSchema>
57
- export declare const useCurrentUserContext: ContextStoreDefinition<'user/current', CurrentUserSchema>
58
- export declare const useSettingsContext: ContextStoreDefinition<'settings', SettingsSchema>
59
-
60
57
  export declare const useField: <S extends ContextSchema, F extends keyof S>(
61
58
  store: ContextStore<S>,
62
- field: F
63
- ) => Computed<S, F>
59
+ field: F,
60
+ onReject?: RejectionHandler | null
61
+ ) => IsReadonly<S[F]> extends true
62
+ ? ComputedRef<TypeOf<S[F]>>
63
+ : WritableComputedRef<TypeOf<S[F]>>
64
64
 
65
65
  export declare const useHost = () => RemoteCallable<Callable>
66
66
 
@@ -69,3 +69,15 @@ declare module 'pinia' {
69
69
  endpoint: Endpoint<ContextAccessor & Callable>;
70
70
  }
71
71
  }
72
+
73
+ export declare const customerCardSchema: CustomerCardSchema
74
+ export declare const customerCardPhoneSchema: CustomerCardPhoneSchema
75
+ export declare const orderCardSchema: OrderCardSchema
76
+ export declare const currentUserSchema: CurrentUserSchema
77
+ export declare const settingsSchema: SettingsSchema
78
+
79
+ export declare const useCustomerCardContext: ContextStoreDefinition<'customer/card', CustomerCardSchema>
80
+ export declare const useCustomerCardPhoneContext: ContextStoreDefinition<'customer/card:phone', CustomerCardPhoneSchema>
81
+ export declare const useOrderCardContext: ContextStoreDefinition<'order/card', OrderCardSchema>
82
+ export declare const useCurrentUserContext: ContextStoreDefinition<'user/current', CurrentUserSchema>
83
+ export declare const useSettingsContext: ContextStoreDefinition<'settings', SettingsSchema>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@retailcrm/embed-ui",
3
3
  "type": "module",
4
- "version": "0.4.3",
4
+ "version": "0.4.4",
5
5
  "description": "API and components for creating RetailCRM UI extensions",
6
6
  "repository": "git@github.com:retailcrm/embed-ui.git",
7
7
  "author": "RetailDriverLLC <integration@retailcrm.ru>",
@@ -24,18 +24,17 @@
24
24
  "packages/*"
25
25
  ],
26
26
  "scripts": {
27
- "build": "vite build",
27
+ "build": "yarn build:code && yarn build:meta",
28
+ "build:code": "vite build",
29
+ "build:meta": "npx tsx scripts/build.meta.ts",
28
30
  "eslint": "eslint .",
29
- "generate:meta": "tsx scripts/generate-meta.ts",
30
- "release": "yes | npx standard-version",
31
- "release:major": "yes | npx standard-version --release-as major",
32
- "release:minor": "yes | npx standard-version --release-as minor",
33
- "release:patch": "yes | npx standard-version --release-as patch",
34
31
  "test": "vitest --run"
35
32
  },
36
33
  "dependencies": {
37
- "@omnicajs/vue-remote": "^0.2.1",
38
- "@remote-ui/rpc": "^1.4.5"
34
+ "@omnicajs/vue-remote": "^0.2.3",
35
+ "@remote-ui/rpc": "^1.4.5",
36
+ "@retailcrm/embed-ui-v1-contexts": "^0.4.4",
37
+ "@retailcrm/embed-ui-v1-types": "^0.4.4"
39
38
  },
40
39
  "peerDependencies": {
41
40
  "pinia": "^2.2",
@@ -44,6 +43,7 @@
44
43
  "devDependencies": {
45
44
  "@eslint/eslintrc": "^3.0.2",
46
45
  "@eslint/js": "^9.13.0",
46
+ "@retailcrm/embed-ui-v1-testing": "^0.4.4",
47
47
  "@types/git-semver-tags": "^7.0.0",
48
48
  "@types/node": "^22.7.9",
49
49
  "@types/semver": "^7.5.8",
@@ -67,15 +67,15 @@
67
67
  "glob": "^11.0.0",
68
68
  "globals": "^15.11.0",
69
69
  "jsdom": "^25.0.1",
70
- "pinia": "^2.2.4",
70
+ "pinia": "^2.2.8",
71
71
  "semver": "^7.6.3",
72
72
  "stringify-package": "^1.0.1",
73
73
  "tsx": "^4.19.2",
74
74
  "typescript": "^5.6.3",
75
75
  "typescript-eslint": "^8.11.0",
76
- "vite": "^5.4.8",
76
+ "vite": "^5.4.11",
77
77
  "vite-plugin-dts": "^4.3.0",
78
- "vitest": "^2.1.2",
78
+ "vitest": "^2.1.8",
79
79
  "vue": "^3.5.12",
80
80
  "yargs": "^17.7.2"
81
81
  },
@@ -1,6 +1 @@
1
- import type { ReadonlyField } from '../schema'
2
-
3
- export type Schema = {
4
- 'value': ReadonlyField<string>;
5
- 'index': ReadonlyField<number>;
6
- }
1
+ export type { Schema } from '@retailcrm/embed-ui-v1-contexts/types/customer/card-phone'
@@ -1,8 +1 @@
1
- import type { ReadonlyField } from '../schema'
2
-
3
- export type Schema = {
4
- 'id': ReadonlyField<number | null>;
5
- 'externalId': ReadonlyField<string | null>;
6
- 'email': ReadonlyField<string>;
7
- 'phones': ReadonlyField<string[]>;
8
- }
1
+ export type { Schema } from '@retailcrm/embed-ui-v1-contexts/types/customer/card'
@@ -1,13 +1 @@
1
- import type { Schema as CustomerCardSchema } from './customer/card'
2
- import type { Schema as CustomerCardPhoneSchema } from './customer/card-phone'
3
- import type { Schema as OrderCardSchema } from './order/card'
4
- import type { Schema as CurrentUserSchema } from './user/current'
5
- import type { Schema as SettingsSchema } from './settings'
6
-
7
- export type SchemaList = {
8
- 'customer/card': CustomerCardSchema;
9
- 'customer/card:phone': CustomerCardPhoneSchema;
10
- 'order/card': OrderCardSchema;
11
- 'user/current': CurrentUserSchema;
12
- 'settings': SettingsSchema;
13
- }
1
+ export type { SchemaList } from '@retailcrm/embed-ui-v1-contexts/types/index'
@@ -1,29 +1 @@
1
- import type { Field, ReadonlyField } from '../schema'
2
-
3
- export type Schema = {
4
- 'id': ReadonlyField<number | null>;
5
- 'externalId': ReadonlyField<string | null>;
6
- 'type': ReadonlyField<string | null>;
7
- 'site': ReadonlyField<string | null>;
8
- 'number': ReadonlyField<string | null>;
9
- 'customer.type': ReadonlyField<'customer' | 'customer_corporate'>;
10
- 'customer.lastName': Field<string | null>;
11
- 'customer.firstName': Field<string | null>;
12
- 'customer.patronymic': Field<string | null>;
13
- 'customer.email': Field<string | null>;
14
- 'customer.phone': Field<string | null>;
15
- 'country': ReadonlyField<string | null>;
16
- 'currency': ReadonlyField<string>;
17
- 'status': ReadonlyField<string>;
18
- 'company.name': Field<string | null>;
19
- 'company.legalName': Field<string | null>;
20
- 'company.legalAddress': Field<string | null>;
21
- 'company.INN': Field<string | null>;
22
- 'company.OKPO': Field<string | null>;
23
- 'company.BIK': Field<string | null>;
24
- 'company.bank': Field<string | null>;
25
- 'company.bankAddress': Field<string | null>;
26
- 'company.corrAccount': Field<string | null>;
27
- 'company.bankAccount': Field<string | null>;
28
- 'delivery.address': Field<string | null>;
29
- }
1
+ export type { Schema } from '@retailcrm/embed-ui-v1-contexts/types/order/card'
@@ -1,89 +1 @@
1
- import type { IsTilda, If } from '../scaffolding'
2
-
3
- export type Field<Type, Readonly extends boolean = false> = {
4
- accepts (value: Type): boolean;
5
- defaults (): Type;
6
- readonly: Readonly;
7
- }
8
-
9
- export type ReadonlyField<Type = unknown> = Field<Type, true>
10
-
11
- export type TypeOf<F> = F extends Field<infer T>
12
- ? T
13
- : F extends ReadonlyField<infer T>
14
- ? T
15
- : never;
16
-
17
- export type IsReadonly<F> = F extends Field<unknown, infer R>
18
- ? R
19
- : F extends ReadonlyField
20
- ? true
21
- : false;
22
-
23
- export type ContextSchema = {
24
- [key: string]: Field<unknown, boolean>;
25
- }
26
-
27
- export type ContextSchemaMap = {
28
- [key: string]: ContextSchema;
29
- }
30
-
31
- export type Context<S extends ContextSchema> = {
32
- [F in keyof S]: TypeOf<S[F]>;
33
- }
34
-
35
- export type Writable<S extends ContextSchema> = {
36
- [F in keyof S as IsReadonly<S[F]> extends true ? never : F]: S[F];
37
- }
38
-
39
- export type EventMap<S extends ContextSchema> = {
40
- [K in keyof S as K extends string ? `change:${K}` : never]: K;
41
- }
42
-
43
- export type EventPayloadMap<S extends ContextSchema> = {
44
- [K in keyof S as K extends string ? `change:${K}` : never]: TypeOf<S[K]>;
45
- }
46
-
47
- export type EventHandler<
48
- S extends ContextSchema,
49
- E extends keyof EventPayloadMap<S>
50
- > = (payload: EventPayloadMap<S>[E]) => void
51
-
52
- export type ContextAccessor<M extends ContextSchemaMap = ContextSchemaMap> = {
53
- get <
54
- C extends keyof M,
55
- F extends keyof M[C]
56
- >(context: C, field: F | '~'): If<
57
- IsTilda<typeof field>,
58
- Context<M[C]>,
59
- Context<M[C]>[F]
60
- >;
61
-
62
- set <
63
- C extends keyof M,
64
- F extends keyof Writable<M[C]>
65
- >(context: C, field: F, value: Context<M[C]>[F]): void;
66
-
67
- on<
68
- C extends keyof M,
69
- E extends keyof EventMap<M[C]>
70
- >(context: C, event: E, handler: EventHandler<M[C], E>): void;
71
- }
72
-
73
- export type FieldAccessor<S extends ContextSchema> = {
74
- get <F extends keyof S>(field: F | '~'): If<
75
- IsTilda<typeof field>,
76
- Context<S>,
77
- Context<S>[F]
78
- >;
79
-
80
- set <F extends keyof Writable<S>>(
81
- field: F,
82
- value: Context<S>[F]
83
- ): void;
84
-
85
- on<E extends keyof EventMap<S>>(
86
- event: E,
87
- handler: EventHandler<S, E>
88
- ): void;
89
- }
1
+ export type * from '@retailcrm/embed-ui-v1-types/context'
@@ -1,6 +1 @@
1
- import type { ReadonlyField } from './schema'
2
-
3
- export type Locale = 'en-GB' | 'es-ES' | 'ru-RU'
4
- export type Schema = {
5
- 'system.locale': ReadonlyField<Locale>;
6
- }
1
+ export type * from '@retailcrm/embed-ui-v1-contexts/types/settings'
@@ -1,12 +1 @@
1
- import type { ReadonlyField } from '../schema'
2
-
3
- export type Schema = {
4
- 'id': ReadonlyField<number | null>;
5
- 'email': ReadonlyField<string>;
6
- 'firstName': ReadonlyField<string | null>;
7
- 'lastName': ReadonlyField<string | null>;
8
- 'patronymic': ReadonlyField<string | null>;
9
- 'photo': ReadonlyField<string | null>;
10
- 'groups': ReadonlyField<string[]>;
11
- 'permissions': ReadonlyField<string[]>;
12
- }
1
+ export type { Schema } from '@retailcrm/embed-ui-v1-contexts/types/user/current'
@@ -1,8 +1,5 @@
1
+ export type * from '@retailcrm/embed-ui-v1-types/scaffolding'
2
+
1
3
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
4
  export type AnyFunction = (...payload: any[]) => unknown
3
5
  export type None = Record<string, never>
4
-
5
- export type IsExact<A, B> = A extends B ? (B extends A ? true : false) : false;
6
- export type IsTilda<A> = IsExact<A, '~'>;
7
-
8
- export type If<Condition, Then, Else> = Condition extends true ? Then : Else;
@@ -0,0 +1,6 @@
1
+ import { defineWorkspace } from 'vitest/config'
2
+
3
+ export default defineWorkspace([
4
+ '.',
5
+ 'packages/v1-contexts',
6
+ ])
@@ -1,26 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "allowJs": true,
4
- "allowSyntheticDefaultImports": true,
5
- "baseUrl": "./",
6
- "esModuleInterop": true,
7
- "forceConsistentCasingInFileNames": true,
8
- "importHelpers": true,
9
- "isolatedModules": true,
10
- "jsx": "preserve",
11
- "lib": [
12
- "esnext",
13
- "dom",
14
- "dom.iterable",
15
- "scripthost"
16
- ],
17
- "module": "ES2022",
18
- "moduleResolution": "node",
19
- "resolveJsonModule": true,
20
- "skipLibCheck": true,
21
- "sourceMap": false,
22
- "strict": true,
23
- "target": "es2017",
24
- "useDefineForClassFields": true
25
- }
26
- }