@vxrn/utils 2.0.0-beta.82.1 → 2.0.0-beta.97.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -55,6 +55,11 @@ function validateNativeApp(manifest, platform) {
55
55
  if (manifest.imagePicker?.camera !== void 0 && (typeof manifest.imagePicker.camera !== "string" || manifest.imagePicker.camera.trim() === "")) {
56
56
  fail("imagePicker.camera must be a non-empty string");
57
57
  }
58
+ if (manifest.notifications !== void 0) {
59
+ if (typeof manifest.notifications !== "object" || manifest.notifications.push !== void 0 && typeof manifest.notifications.push !== "boolean") {
60
+ fail("notifications.push must be a boolean");
61
+ }
62
+ }
58
63
  if (!platform || platform === "ios") {
59
64
  if (!manifest.ios?.bundleId || !REVERSE_DNS.test(manifest.ios.bundleId)) {
60
65
  fail(`ios.bundleId "${manifest.ios?.bundleId}" must be reverse-dns`);
@@ -65,6 +70,24 @@ function validateNativeApp(manifest, platform) {
65
70
  if (manifest.ios.buildNumber !== void 0 && !BUILD_NUMBER.test(manifest.ios.buildNumber)) {
66
71
  fail(`ios.buildNumber "${manifest.ios.buildNumber}" must contain only letters, digits, and dots`);
67
72
  }
73
+ const widgets = manifest.ios.widgets;
74
+ if (widgets) {
75
+ if (!manifest.ios.deploymentTarget || Number(manifest.ios.deploymentTarget) < 17) {
76
+ fail("ios.widgets requires ios.deploymentTarget of 17.0 or newer");
77
+ }
78
+ if (!/^group\.[A-Za-z][A-Za-z0-9-]*(\.[A-Za-z][A-Za-z0-9-]*)+$/.test(widgets.appGroup)) {
79
+ fail("ios.widgets.appGroup must be a reverse-dns App Group beginning with group.");
80
+ }
81
+ if (!/^[A-Za-z][A-Za-z0-9._-]*$/.test(widgets.kind)) {
82
+ fail("ios.widgets.kind must be a non-empty WidgetKit kind");
83
+ }
84
+ if (!widgets.displayName?.trim() || !widgets.description?.trim()) {
85
+ fail("ios.widgets.displayName and description must be non-empty strings");
86
+ }
87
+ if (widgets.pushNotifications !== void 0 && typeof widgets.pushNotifications !== "boolean") {
88
+ fail("ios.widgets.pushNotifications must be a boolean");
89
+ }
90
+ }
68
91
  }
69
92
  if (!platform || platform === "android") {
70
93
  if (!manifest.android?.applicationId || !REVERSE_DNS.test(manifest.android.applicationId)) {
@@ -75,6 +75,11 @@ function validateNativeApp(manifest, platform) {
75
75
  if (((_manifest_imagePicker = manifest.imagePicker) === null || _manifest_imagePicker === void 0 ? void 0 : _manifest_imagePicker.camera) !== void 0 && (typeof manifest.imagePicker.camera !== "string" || manifest.imagePicker.camera.trim() === "")) {
76
76
  fail("imagePicker.camera must be a non-empty string");
77
77
  }
78
+ if (manifest.notifications !== void 0) {
79
+ if (typeof manifest.notifications !== "object" || manifest.notifications.push !== void 0 && typeof manifest.notifications.push !== "boolean") {
80
+ fail("notifications.push must be a boolean");
81
+ }
82
+ }
78
83
  if (!platform || platform === "ios") {
79
84
  var _manifest_ios;
80
85
  if (!((_manifest_ios = manifest.ios) === null || _manifest_ios === void 0 ? void 0 : _manifest_ios.bundleId) || !REVERSE_DNS.test(manifest.ios.bundleId)) {
@@ -87,6 +92,25 @@ function validateNativeApp(manifest, platform) {
87
92
  if (manifest.ios.buildNumber !== void 0 && !BUILD_NUMBER.test(manifest.ios.buildNumber)) {
88
93
  fail(`ios.buildNumber "${manifest.ios.buildNumber}" must contain only letters, digits, and dots`);
89
94
  }
95
+ var widgets = manifest.ios.widgets;
96
+ if (widgets) {
97
+ var _widgets_displayName, _widgets_description;
98
+ if (!manifest.ios.deploymentTarget || Number(manifest.ios.deploymentTarget) < 17) {
99
+ fail("ios.widgets requires ios.deploymentTarget of 17.0 or newer");
100
+ }
101
+ if (!/^group\.[A-Za-z][A-Za-z0-9-]*(\.[A-Za-z][A-Za-z0-9-]*)+$/.test(widgets.appGroup)) {
102
+ fail("ios.widgets.appGroup must be a reverse-dns App Group beginning with group.");
103
+ }
104
+ if (!/^[A-Za-z][A-Za-z0-9._-]*$/.test(widgets.kind)) {
105
+ fail("ios.widgets.kind must be a non-empty WidgetKit kind");
106
+ }
107
+ if (!((_widgets_displayName = widgets.displayName) === null || _widgets_displayName === void 0 ? void 0 : _widgets_displayName.trim()) || !((_widgets_description = widgets.description) === null || _widgets_description === void 0 ? void 0 : _widgets_description.trim())) {
108
+ fail("ios.widgets.displayName and description must be non-empty strings");
109
+ }
110
+ if (widgets.pushNotifications !== void 0 && typeof widgets.pushNotifications !== "boolean") {
111
+ fail("ios.widgets.pushNotifications must be a boolean");
112
+ }
113
+ }
90
114
  }
91
115
  if (!platform || platform === "android") {
92
116
  var _manifest_android;
@@ -75,6 +75,11 @@ function validateNativeApp(manifest, platform) {
75
75
  if (((_manifest_imagePicker = manifest.imagePicker) === null || _manifest_imagePicker === void 0 ? void 0 : _manifest_imagePicker.camera) !== void 0 && (typeof manifest.imagePicker.camera !== "string" || manifest.imagePicker.camera.trim() === "")) {
76
76
  fail("imagePicker.camera must be a non-empty string");
77
77
  }
78
+ if (manifest.notifications !== void 0) {
79
+ if (typeof manifest.notifications !== "object" || manifest.notifications.push !== void 0 && typeof manifest.notifications.push !== "boolean") {
80
+ fail("notifications.push must be a boolean");
81
+ }
82
+ }
78
83
  if (!platform || platform === "ios") {
79
84
  var _manifest_ios;
80
85
  if (!((_manifest_ios = manifest.ios) === null || _manifest_ios === void 0 ? void 0 : _manifest_ios.bundleId) || !REVERSE_DNS.test(manifest.ios.bundleId)) {
@@ -87,6 +92,25 @@ function validateNativeApp(manifest, platform) {
87
92
  if (manifest.ios.buildNumber !== void 0 && !BUILD_NUMBER.test(manifest.ios.buildNumber)) {
88
93
  fail(`ios.buildNumber "${manifest.ios.buildNumber}" must contain only letters, digits, and dots`);
89
94
  }
95
+ var widgets = manifest.ios.widgets;
96
+ if (widgets) {
97
+ var _widgets_displayName, _widgets_description;
98
+ if (!manifest.ios.deploymentTarget || Number(manifest.ios.deploymentTarget) < 17) {
99
+ fail("ios.widgets requires ios.deploymentTarget of 17.0 or newer");
100
+ }
101
+ if (!/^group\.[A-Za-z][A-Za-z0-9-]*(\.[A-Za-z][A-Za-z0-9-]*)+$/.test(widgets.appGroup)) {
102
+ fail("ios.widgets.appGroup must be a reverse-dns App Group beginning with group.");
103
+ }
104
+ if (!/^[A-Za-z][A-Za-z0-9._-]*$/.test(widgets.kind)) {
105
+ fail("ios.widgets.kind must be a non-empty WidgetKit kind");
106
+ }
107
+ if (!((_widgets_displayName = widgets.displayName) === null || _widgets_displayName === void 0 ? void 0 : _widgets_displayName.trim()) || !((_widgets_description = widgets.description) === null || _widgets_description === void 0 ? void 0 : _widgets_description.trim())) {
108
+ fail("ios.widgets.displayName and description must be non-empty strings");
109
+ }
110
+ if (widgets.pushNotifications !== void 0 && typeof widgets.pushNotifications !== "boolean") {
111
+ fail("ios.widgets.pushNotifications must be a boolean");
112
+ }
113
+ }
90
114
  }
91
115
  if (!platform || platform === "android") {
92
116
  var _manifest_android;
@@ -1 +1 @@
1
- {"version":3,"file":"nativeAppManifest.native.js","names":[],"sources":["cjs/nativeAppManifest.native.js"],"sourcesContent":["\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\nvar nativeAppManifest_exports = {};\n__export(nativeAppManifest_exports, {\n validateNativeApp: () => validateNativeApp\n});\nmodule.exports = __toCommonJS(nativeAppManifest_exports);\nvar TARGET_NAME = /^[A-Za-z][A-Za-z0-9_]*$/;\nvar SCHEME = /^[a-z][a-z0-9+.-]*$/i;\nvar VERSION = /^\\d+\\.\\d+\\.\\d+/;\nvar BUILD_NUMBER = /^[A-Za-z0-9.]+$/;\nvar REVERSE_DNS = /^[A-Za-z][A-Za-z0-9-]*(\\.[A-Za-z][A-Za-z0-9-]*)+$/;\nvar DEPLOYMENT_TARGET = /^\\d+\\.\\d+$/;\nvar HEX_COLOR = /^#[\\da-f]{6}$/i;\nfunction fail(message) {\n throw new Error(`[one] invalid native.app: ${message}`);\n}\nfunction validateNativeApp(manifest, platform) {\n var _manifest_imagePicker;\n if (!manifest || typeof manifest !== \"object\") fail(\"manifest must be an object\");\n if (!manifest.name || typeof manifest.name !== \"string\") fail(\"name is required\");\n if (!TARGET_NAME.test(manifest.name)) {\n fail(`name \"${manifest.name}\" must start with a letter and contain only letters, digits, and underscore`);\n }\n var schemes = manifest.scheme === void 0 ? [] : Array.isArray(manifest.scheme) ? manifest.scheme : [\n manifest.scheme\n ];\n var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;\n try {\n for (var _iterator = schemes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var scheme = _step.value;\n if (typeof scheme !== \"string\" || !SCHEME.test(scheme)) {\n fail(`scheme \"${scheme}\" must be a valid uri scheme`);\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n if (manifest.version !== void 0 && !VERSION.test(manifest.version)) {\n fail(`version \"${manifest.version}\" must start with major.minor.patch`);\n }\n if (manifest.icon !== void 0 && (!manifest.icon.source || !HEX_COLOR.test(manifest.icon.backgroundColor))) {\n fail(\"icon requires source and a six-digit hex backgroundColor\");\n }\n if (manifest.splash !== void 0 && (!manifest.splash.source || !HEX_COLOR.test(manifest.splash.backgroundColor) || manifest.splash.width !== void 0 && (!Number.isFinite(manifest.splash.width) || manifest.splash.width < 1 || manifest.splash.width > 288))) {\n fail(\"splash requires source, a six-digit hex backgroundColor, and width from 1 to 288\");\n }\n if (((_manifest_imagePicker = manifest.imagePicker) === null || _manifest_imagePicker === void 0 ? void 0 : _manifest_imagePicker.camera) !== void 0 && (typeof manifest.imagePicker.camera !== \"string\" || manifest.imagePicker.camera.trim() === \"\")) {\n fail(\"imagePicker.camera must be a non-empty string\");\n }\n if (!platform || platform === \"ios\") {\n var _manifest_ios;\n if (!((_manifest_ios = manifest.ios) === null || _manifest_ios === void 0 ? void 0 : _manifest_ios.bundleId) || !REVERSE_DNS.test(manifest.ios.bundleId)) {\n var _manifest_ios1;\n fail(`ios.bundleId \"${(_manifest_ios1 = manifest.ios) === null || _manifest_ios1 === void 0 ? void 0 : _manifest_ios1.bundleId}\" must be reverse-dns`);\n }\n if (manifest.ios.deploymentTarget !== void 0 && !DEPLOYMENT_TARGET.test(manifest.ios.deploymentTarget)) {\n fail(`ios.deploymentTarget \"${manifest.ios.deploymentTarget}\" must look like \"17.0\"`);\n }\n if (manifest.ios.buildNumber !== void 0 && !BUILD_NUMBER.test(manifest.ios.buildNumber)) {\n fail(`ios.buildNumber \"${manifest.ios.buildNumber}\" must contain only letters, digits, and dots`);\n }\n }\n if (!platform || platform === \"android\") {\n var _manifest_android;\n if (!((_manifest_android = manifest.android) === null || _manifest_android === void 0 ? void 0 : _manifest_android.applicationId) || !REVERSE_DNS.test(manifest.android.applicationId)) {\n var _manifest_android1;\n fail(`android.applicationId \"${(_manifest_android1 = manifest.android) === null || _manifest_android1 === void 0 ? void 0 : _manifest_android1.applicationId}\" must be reverse-dns`);\n }\n if (manifest.android.minSdk !== void 0 && (!Number.isInteger(manifest.android.minSdk) || manifest.android.minSdk < 21 || manifest.android.minSdk > 36)) {\n fail(`android.minSdk \"${manifest.android.minSdk}\" must be an integer from 21 to 36`);\n }\n if (manifest.android.versionCode !== void 0 && (!Number.isInteger(manifest.android.versionCode) || manifest.android.versionCode < 1)) {\n fail(`android.versionCode \"${manifest.android.versionCode}\" must be a positive integer`);\n }\n if (manifest.android.googleMapsApiKey !== void 0 && (typeof manifest.android.googleMapsApiKey !== \"string\" || manifest.android.googleMapsApiKey.trim() === \"\")) {\n fail(\"android.googleMapsApiKey must be a non-empty string\");\n }\n }\n return manifest;\n}\n//# sourceMappingURL=nativeAppManifest.js.map\n"],"mappings":"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"}
1
+ {"version":3,"file":"nativeAppManifest.native.js","names":[],"sources":["cjs/nativeAppManifest.native.js"],"sourcesContent":["\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\nvar nativeAppManifest_exports = {};\n__export(nativeAppManifest_exports, {\n validateNativeApp: () => validateNativeApp\n});\nmodule.exports = __toCommonJS(nativeAppManifest_exports);\nvar TARGET_NAME = /^[A-Za-z][A-Za-z0-9_]*$/;\nvar SCHEME = /^[a-z][a-z0-9+.-]*$/i;\nvar VERSION = /^\\d+\\.\\d+\\.\\d+/;\nvar BUILD_NUMBER = /^[A-Za-z0-9.]+$/;\nvar REVERSE_DNS = /^[A-Za-z][A-Za-z0-9-]*(\\.[A-Za-z][A-Za-z0-9-]*)+$/;\nvar DEPLOYMENT_TARGET = /^\\d+\\.\\d+$/;\nvar HEX_COLOR = /^#[\\da-f]{6}$/i;\nfunction fail(message) {\n throw new Error(`[one] invalid native.app: ${message}`);\n}\nfunction validateNativeApp(manifest, platform) {\n var _manifest_imagePicker;\n if (!manifest || typeof manifest !== \"object\") fail(\"manifest must be an object\");\n if (!manifest.name || typeof manifest.name !== \"string\") fail(\"name is required\");\n if (!TARGET_NAME.test(manifest.name)) {\n fail(`name \"${manifest.name}\" must start with a letter and contain only letters, digits, and underscore`);\n }\n var schemes = manifest.scheme === void 0 ? [] : Array.isArray(manifest.scheme) ? manifest.scheme : [\n manifest.scheme\n ];\n var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;\n try {\n for (var _iterator = schemes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var scheme = _step.value;\n if (typeof scheme !== \"string\" || !SCHEME.test(scheme)) {\n fail(`scheme \"${scheme}\" must be a valid uri scheme`);\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n if (manifest.version !== void 0 && !VERSION.test(manifest.version)) {\n fail(`version \"${manifest.version}\" must start with major.minor.patch`);\n }\n if (manifest.icon !== void 0 && (!manifest.icon.source || !HEX_COLOR.test(manifest.icon.backgroundColor))) {\n fail(\"icon requires source and a six-digit hex backgroundColor\");\n }\n if (manifest.splash !== void 0 && (!manifest.splash.source || !HEX_COLOR.test(manifest.splash.backgroundColor) || manifest.splash.width !== void 0 && (!Number.isFinite(manifest.splash.width) || manifest.splash.width < 1 || manifest.splash.width > 288))) {\n fail(\"splash requires source, a six-digit hex backgroundColor, and width from 1 to 288\");\n }\n if (((_manifest_imagePicker = manifest.imagePicker) === null || _manifest_imagePicker === void 0 ? void 0 : _manifest_imagePicker.camera) !== void 0 && (typeof manifest.imagePicker.camera !== \"string\" || manifest.imagePicker.camera.trim() === \"\")) {\n fail(\"imagePicker.camera must be a non-empty string\");\n }\n if (manifest.notifications !== void 0) {\n if (typeof manifest.notifications !== \"object\" || manifest.notifications.push !== void 0 && typeof manifest.notifications.push !== \"boolean\") {\n fail(\"notifications.push must be a boolean\");\n }\n }\n if (!platform || platform === \"ios\") {\n var _manifest_ios;\n if (!((_manifest_ios = manifest.ios) === null || _manifest_ios === void 0 ? void 0 : _manifest_ios.bundleId) || !REVERSE_DNS.test(manifest.ios.bundleId)) {\n var _manifest_ios1;\n fail(`ios.bundleId \"${(_manifest_ios1 = manifest.ios) === null || _manifest_ios1 === void 0 ? void 0 : _manifest_ios1.bundleId}\" must be reverse-dns`);\n }\n if (manifest.ios.deploymentTarget !== void 0 && !DEPLOYMENT_TARGET.test(manifest.ios.deploymentTarget)) {\n fail(`ios.deploymentTarget \"${manifest.ios.deploymentTarget}\" must look like \"17.0\"`);\n }\n if (manifest.ios.buildNumber !== void 0 && !BUILD_NUMBER.test(manifest.ios.buildNumber)) {\n fail(`ios.buildNumber \"${manifest.ios.buildNumber}\" must contain only letters, digits, and dots`);\n }\n var widgets = manifest.ios.widgets;\n if (widgets) {\n var _widgets_displayName, _widgets_description;\n if (!manifest.ios.deploymentTarget || Number(manifest.ios.deploymentTarget) < 17) {\n fail(\"ios.widgets requires ios.deploymentTarget of 17.0 or newer\");\n }\n if (!/^group\\.[A-Za-z][A-Za-z0-9-]*(\\.[A-Za-z][A-Za-z0-9-]*)+$/.test(widgets.appGroup)) {\n fail(\"ios.widgets.appGroup must be a reverse-dns App Group beginning with group.\");\n }\n if (!/^[A-Za-z][A-Za-z0-9._-]*$/.test(widgets.kind)) {\n fail(\"ios.widgets.kind must be a non-empty WidgetKit kind\");\n }\n if (!((_widgets_displayName = widgets.displayName) === null || _widgets_displayName === void 0 ? void 0 : _widgets_displayName.trim()) || !((_widgets_description = widgets.description) === null || _widgets_description === void 0 ? void 0 : _widgets_description.trim())) {\n fail(\"ios.widgets.displayName and description must be non-empty strings\");\n }\n if (widgets.pushNotifications !== void 0 && typeof widgets.pushNotifications !== \"boolean\") {\n fail(\"ios.widgets.pushNotifications must be a boolean\");\n }\n }\n }\n if (!platform || platform === \"android\") {\n var _manifest_android;\n if (!((_manifest_android = manifest.android) === null || _manifest_android === void 0 ? void 0 : _manifest_android.applicationId) || !REVERSE_DNS.test(manifest.android.applicationId)) {\n var _manifest_android1;\n fail(`android.applicationId \"${(_manifest_android1 = manifest.android) === null || _manifest_android1 === void 0 ? void 0 : _manifest_android1.applicationId}\" must be reverse-dns`);\n }\n if (manifest.android.minSdk !== void 0 && (!Number.isInteger(manifest.android.minSdk) || manifest.android.minSdk < 21 || manifest.android.minSdk > 36)) {\n fail(`android.minSdk \"${manifest.android.minSdk}\" must be an integer from 21 to 36`);\n }\n if (manifest.android.versionCode !== void 0 && (!Number.isInteger(manifest.android.versionCode) || manifest.android.versionCode < 1)) {\n fail(`android.versionCode \"${manifest.android.versionCode}\" must be a positive integer`);\n }\n if (manifest.android.googleMapsApiKey !== void 0 && (typeof manifest.android.googleMapsApiKey !== \"string\" || manifest.android.googleMapsApiKey.trim() === \"\")) {\n fail(\"android.googleMapsApiKey must be a non-empty string\");\n }\n }\n return manifest;\n}\n//# sourceMappingURL=nativeAppManifest.js.map\n"],"mappings":"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"}
@@ -32,6 +32,11 @@ function validateNativeApp(manifest, platform) {
32
32
  if (manifest.imagePicker?.camera !== void 0 && (typeof manifest.imagePicker.camera !== "string" || manifest.imagePicker.camera.trim() === "")) {
33
33
  fail("imagePicker.camera must be a non-empty string");
34
34
  }
35
+ if (manifest.notifications !== void 0) {
36
+ if (typeof manifest.notifications !== "object" || manifest.notifications.push !== void 0 && typeof manifest.notifications.push !== "boolean") {
37
+ fail("notifications.push must be a boolean");
38
+ }
39
+ }
35
40
  if (!platform || platform === "ios") {
36
41
  if (!manifest.ios?.bundleId || !REVERSE_DNS.test(manifest.ios.bundleId)) {
37
42
  fail(`ios.bundleId "${manifest.ios?.bundleId}" must be reverse-dns`);
@@ -42,6 +47,24 @@ function validateNativeApp(manifest, platform) {
42
47
  if (manifest.ios.buildNumber !== void 0 && !BUILD_NUMBER.test(manifest.ios.buildNumber)) {
43
48
  fail(`ios.buildNumber "${manifest.ios.buildNumber}" must contain only letters, digits, and dots`);
44
49
  }
50
+ const widgets = manifest.ios.widgets;
51
+ if (widgets) {
52
+ if (!manifest.ios.deploymentTarget || Number(manifest.ios.deploymentTarget) < 17) {
53
+ fail("ios.widgets requires ios.deploymentTarget of 17.0 or newer");
54
+ }
55
+ if (!/^group\.[A-Za-z][A-Za-z0-9-]*(\.[A-Za-z][A-Za-z0-9-]*)+$/.test(widgets.appGroup)) {
56
+ fail("ios.widgets.appGroup must be a reverse-dns App Group beginning with group.");
57
+ }
58
+ if (!/^[A-Za-z][A-Za-z0-9._-]*$/.test(widgets.kind)) {
59
+ fail("ios.widgets.kind must be a non-empty WidgetKit kind");
60
+ }
61
+ if (!widgets.displayName?.trim() || !widgets.description?.trim()) {
62
+ fail("ios.widgets.displayName and description must be non-empty strings");
63
+ }
64
+ if (widgets.pushNotifications !== void 0 && typeof widgets.pushNotifications !== "boolean") {
65
+ fail("ios.widgets.pushNotifications must be a boolean");
66
+ }
67
+ }
45
68
  }
46
69
  if (!platform || platform === "android") {
47
70
  if (!manifest.android?.applicationId || !REVERSE_DNS.test(manifest.android.applicationId)) {
@@ -1 +1 @@
1
- {"version":3,"file":"nativeAppManifest.js","names":[],"sources":["esm/nativeAppManifest.js"],"sourcesContent":["const TARGET_NAME = /^[A-Za-z][A-Za-z0-9_]*$/;\nconst SCHEME = /^[a-z][a-z0-9+.-]*$/i;\nconst VERSION = /^\\d+\\.\\d+\\.\\d+/;\nconst BUILD_NUMBER = /^[A-Za-z0-9.]+$/;\nconst REVERSE_DNS = /^[A-Za-z][A-Za-z0-9-]*(\\.[A-Za-z][A-Za-z0-9-]*)+$/;\nconst DEPLOYMENT_TARGET = /^\\d+\\.\\d+$/;\nconst HEX_COLOR = /^#[\\da-f]{6}$/i;\nfunction fail(message) {\n throw new Error(`[one] invalid native.app: ${message}`);\n}\nfunction validateNativeApp(manifest, platform) {\n if (!manifest || typeof manifest !== \"object\") fail(\"manifest must be an object\");\n if (!manifest.name || typeof manifest.name !== \"string\") fail(\"name is required\");\n if (!TARGET_NAME.test(manifest.name)) {\n fail(\n `name \"${manifest.name}\" must start with a letter and contain only letters, digits, and underscore`\n );\n }\n const schemes = manifest.scheme === void 0 ? [] : Array.isArray(manifest.scheme) ? manifest.scheme : [manifest.scheme];\n for (const scheme of schemes) {\n if (typeof scheme !== \"string\" || !SCHEME.test(scheme)) {\n fail(`scheme \"${scheme}\" must be a valid uri scheme`);\n }\n }\n if (manifest.version !== void 0 && !VERSION.test(manifest.version)) {\n fail(`version \"${manifest.version}\" must start with major.minor.patch`);\n }\n if (manifest.icon !== void 0 && (!manifest.icon.source || !HEX_COLOR.test(manifest.icon.backgroundColor))) {\n fail(\"icon requires source and a six-digit hex backgroundColor\");\n }\n if (manifest.splash !== void 0 && (!manifest.splash.source || !HEX_COLOR.test(manifest.splash.backgroundColor) || manifest.splash.width !== void 0 && (!Number.isFinite(manifest.splash.width) || manifest.splash.width < 1 || manifest.splash.width > 288))) {\n fail(\n \"splash requires source, a six-digit hex backgroundColor, and width from 1 to 288\"\n );\n }\n if (manifest.imagePicker?.camera !== void 0 && (typeof manifest.imagePicker.camera !== \"string\" || manifest.imagePicker.camera.trim() === \"\")) {\n fail(\"imagePicker.camera must be a non-empty string\");\n }\n if (!platform || platform === \"ios\") {\n if (!manifest.ios?.bundleId || !REVERSE_DNS.test(manifest.ios.bundleId)) {\n fail(`ios.bundleId \"${manifest.ios?.bundleId}\" must be reverse-dns`);\n }\n if (manifest.ios.deploymentTarget !== void 0 && !DEPLOYMENT_TARGET.test(manifest.ios.deploymentTarget)) {\n fail(\n `ios.deploymentTarget \"${manifest.ios.deploymentTarget}\" must look like \"17.0\"`\n );\n }\n if (manifest.ios.buildNumber !== void 0 && !BUILD_NUMBER.test(manifest.ios.buildNumber)) {\n fail(\n `ios.buildNumber \"${manifest.ios.buildNumber}\" must contain only letters, digits, and dots`\n );\n }\n }\n if (!platform || platform === \"android\") {\n if (!manifest.android?.applicationId || !REVERSE_DNS.test(manifest.android.applicationId)) {\n fail(\n `android.applicationId \"${manifest.android?.applicationId}\" must be reverse-dns`\n );\n }\n if (manifest.android.minSdk !== void 0 && (!Number.isInteger(manifest.android.minSdk) || manifest.android.minSdk < 21 || manifest.android.minSdk > 36)) {\n fail(`android.minSdk \"${manifest.android.minSdk}\" must be an integer from 21 to 36`);\n }\n if (manifest.android.versionCode !== void 0 && (!Number.isInteger(manifest.android.versionCode) || manifest.android.versionCode < 1)) {\n fail(\n `android.versionCode \"${manifest.android.versionCode}\" must be a positive integer`\n );\n }\n if (manifest.android.googleMapsApiKey !== void 0 && (typeof manifest.android.googleMapsApiKey !== \"string\" || manifest.android.googleMapsApiKey.trim() === \"\")) {\n fail(\"android.googleMapsApiKey must be a non-empty string\");\n }\n }\n return manifest;\n}\nexport {\n validateNativeApp\n};\n//# sourceMappingURL=nativeAppManifest.js.map\n"],"mappings":"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"}
1
+ {"version":3,"file":"nativeAppManifest.js","names":[],"sources":["esm/nativeAppManifest.js"],"sourcesContent":["const TARGET_NAME = /^[A-Za-z][A-Za-z0-9_]*$/;\nconst SCHEME = /^[a-z][a-z0-9+.-]*$/i;\nconst VERSION = /^\\d+\\.\\d+\\.\\d+/;\nconst BUILD_NUMBER = /^[A-Za-z0-9.]+$/;\nconst REVERSE_DNS = /^[A-Za-z][A-Za-z0-9-]*(\\.[A-Za-z][A-Za-z0-9-]*)+$/;\nconst DEPLOYMENT_TARGET = /^\\d+\\.\\d+$/;\nconst HEX_COLOR = /^#[\\da-f]{6}$/i;\nfunction fail(message) {\n throw new Error(`[one] invalid native.app: ${message}`);\n}\nfunction validateNativeApp(manifest, platform) {\n if (!manifest || typeof manifest !== \"object\") fail(\"manifest must be an object\");\n if (!manifest.name || typeof manifest.name !== \"string\") fail(\"name is required\");\n if (!TARGET_NAME.test(manifest.name)) {\n fail(\n `name \"${manifest.name}\" must start with a letter and contain only letters, digits, and underscore`\n );\n }\n const schemes = manifest.scheme === void 0 ? [] : Array.isArray(manifest.scheme) ? manifest.scheme : [manifest.scheme];\n for (const scheme of schemes) {\n if (typeof scheme !== \"string\" || !SCHEME.test(scheme)) {\n fail(`scheme \"${scheme}\" must be a valid uri scheme`);\n }\n }\n if (manifest.version !== void 0 && !VERSION.test(manifest.version)) {\n fail(`version \"${manifest.version}\" must start with major.minor.patch`);\n }\n if (manifest.icon !== void 0 && (!manifest.icon.source || !HEX_COLOR.test(manifest.icon.backgroundColor))) {\n fail(\"icon requires source and a six-digit hex backgroundColor\");\n }\n if (manifest.splash !== void 0 && (!manifest.splash.source || !HEX_COLOR.test(manifest.splash.backgroundColor) || manifest.splash.width !== void 0 && (!Number.isFinite(manifest.splash.width) || manifest.splash.width < 1 || manifest.splash.width > 288))) {\n fail(\n \"splash requires source, a six-digit hex backgroundColor, and width from 1 to 288\"\n );\n }\n if (manifest.imagePicker?.camera !== void 0 && (typeof manifest.imagePicker.camera !== \"string\" || manifest.imagePicker.camera.trim() === \"\")) {\n fail(\"imagePicker.camera must be a non-empty string\");\n }\n if (manifest.notifications !== void 0) {\n if (typeof manifest.notifications !== \"object\" || manifest.notifications.push !== void 0 && typeof manifest.notifications.push !== \"boolean\") {\n fail(\"notifications.push must be a boolean\");\n }\n }\n if (!platform || platform === \"ios\") {\n if (!manifest.ios?.bundleId || !REVERSE_DNS.test(manifest.ios.bundleId)) {\n fail(`ios.bundleId \"${manifest.ios?.bundleId}\" must be reverse-dns`);\n }\n if (manifest.ios.deploymentTarget !== void 0 && !DEPLOYMENT_TARGET.test(manifest.ios.deploymentTarget)) {\n fail(\n `ios.deploymentTarget \"${manifest.ios.deploymentTarget}\" must look like \"17.0\"`\n );\n }\n if (manifest.ios.buildNumber !== void 0 && !BUILD_NUMBER.test(manifest.ios.buildNumber)) {\n fail(\n `ios.buildNumber \"${manifest.ios.buildNumber}\" must contain only letters, digits, and dots`\n );\n }\n const widgets = manifest.ios.widgets;\n if (widgets) {\n if (!manifest.ios.deploymentTarget || Number(manifest.ios.deploymentTarget) < 17) {\n fail(\"ios.widgets requires ios.deploymentTarget of 17.0 or newer\");\n }\n if (!/^group\\.[A-Za-z][A-Za-z0-9-]*(\\.[A-Za-z][A-Za-z0-9-]*)+$/.test(widgets.appGroup)) {\n fail(\"ios.widgets.appGroup must be a reverse-dns App Group beginning with group.\");\n }\n if (!/^[A-Za-z][A-Za-z0-9._-]*$/.test(widgets.kind)) {\n fail(\"ios.widgets.kind must be a non-empty WidgetKit kind\");\n }\n if (!widgets.displayName?.trim() || !widgets.description?.trim()) {\n fail(\"ios.widgets.displayName and description must be non-empty strings\");\n }\n if (widgets.pushNotifications !== void 0 && typeof widgets.pushNotifications !== \"boolean\") {\n fail(\"ios.widgets.pushNotifications must be a boolean\");\n }\n }\n }\n if (!platform || platform === \"android\") {\n if (!manifest.android?.applicationId || !REVERSE_DNS.test(manifest.android.applicationId)) {\n fail(\n `android.applicationId \"${manifest.android?.applicationId}\" must be reverse-dns`\n );\n }\n if (manifest.android.minSdk !== void 0 && (!Number.isInteger(manifest.android.minSdk) || manifest.android.minSdk < 21 || manifest.android.minSdk > 36)) {\n fail(`android.minSdk \"${manifest.android.minSdk}\" must be an integer from 21 to 36`);\n }\n if (manifest.android.versionCode !== void 0 && (!Number.isInteger(manifest.android.versionCode) || manifest.android.versionCode < 1)) {\n fail(\n `android.versionCode \"${manifest.android.versionCode}\" must be a positive integer`\n );\n }\n if (manifest.android.googleMapsApiKey !== void 0 && (typeof manifest.android.googleMapsApiKey !== \"string\" || manifest.android.googleMapsApiKey.trim() === \"\")) {\n fail(\"android.googleMapsApiKey must be a non-empty string\");\n }\n }\n return manifest;\n}\nexport {\n validateNativeApp\n};\n//# sourceMappingURL=nativeAppManifest.js.map\n"],"mappings":"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"}
@@ -50,6 +50,11 @@ function validateNativeApp(manifest, platform) {
50
50
  if (((_manifest_imagePicker = manifest.imagePicker) === null || _manifest_imagePicker === void 0 ? void 0 : _manifest_imagePicker.camera) !== void 0 && (typeof manifest.imagePicker.camera !== "string" || manifest.imagePicker.camera.trim() === "")) {
51
51
  fail("imagePicker.camera must be a non-empty string");
52
52
  }
53
+ if (manifest.notifications !== void 0) {
54
+ if (typeof manifest.notifications !== "object" || manifest.notifications.push !== void 0 && typeof manifest.notifications.push !== "boolean") {
55
+ fail("notifications.push must be a boolean");
56
+ }
57
+ }
53
58
  if (!platform || platform === "ios") {
54
59
  var _manifest_ios;
55
60
  if (!((_manifest_ios = manifest.ios) === null || _manifest_ios === void 0 ? void 0 : _manifest_ios.bundleId) || !REVERSE_DNS.test(manifest.ios.bundleId)) {
@@ -62,6 +67,25 @@ function validateNativeApp(manifest, platform) {
62
67
  if (manifest.ios.buildNumber !== void 0 && !BUILD_NUMBER.test(manifest.ios.buildNumber)) {
63
68
  fail(`ios.buildNumber "${manifest.ios.buildNumber}" must contain only letters, digits, and dots`);
64
69
  }
70
+ var widgets = manifest.ios.widgets;
71
+ if (widgets) {
72
+ var _widgets_displayName, _widgets_description;
73
+ if (!manifest.ios.deploymentTarget || Number(manifest.ios.deploymentTarget) < 17) {
74
+ fail("ios.widgets requires ios.deploymentTarget of 17.0 or newer");
75
+ }
76
+ if (!/^group\.[A-Za-z][A-Za-z0-9-]*(\.[A-Za-z][A-Za-z0-9-]*)+$/.test(widgets.appGroup)) {
77
+ fail("ios.widgets.appGroup must be a reverse-dns App Group beginning with group.");
78
+ }
79
+ if (!/^[A-Za-z][A-Za-z0-9._-]*$/.test(widgets.kind)) {
80
+ fail("ios.widgets.kind must be a non-empty WidgetKit kind");
81
+ }
82
+ if (!((_widgets_displayName = widgets.displayName) === null || _widgets_displayName === void 0 ? void 0 : _widgets_displayName.trim()) || !((_widgets_description = widgets.description) === null || _widgets_description === void 0 ? void 0 : _widgets_description.trim())) {
83
+ fail("ios.widgets.displayName and description must be non-empty strings");
84
+ }
85
+ if (widgets.pushNotifications !== void 0 && typeof widgets.pushNotifications !== "boolean") {
86
+ fail("ios.widgets.pushNotifications must be a boolean");
87
+ }
88
+ }
65
89
  }
66
90
  if (!platform || platform === "android") {
67
91
  var _manifest_android;
@@ -1 +1 @@
1
- {"version":3,"file":"nativeAppManifest.native.js","names":[],"sources":["esm/nativeAppManifest.native.js"],"sourcesContent":["var TARGET_NAME = /^[A-Za-z][A-Za-z0-9_]*$/;\nvar SCHEME = /^[a-z][a-z0-9+.-]*$/i;\nvar VERSION = /^\\d+\\.\\d+\\.\\d+/;\nvar BUILD_NUMBER = /^[A-Za-z0-9.]+$/;\nvar REVERSE_DNS = /^[A-Za-z][A-Za-z0-9-]*(\\.[A-Za-z][A-Za-z0-9-]*)+$/;\nvar DEPLOYMENT_TARGET = /^\\d+\\.\\d+$/;\nvar HEX_COLOR = /^#[\\da-f]{6}$/i;\nfunction fail(message) {\n throw new Error(`[one] invalid native.app: ${message}`);\n}\nfunction validateNativeApp(manifest, platform) {\n var _manifest_imagePicker;\n if (!manifest || typeof manifest !== \"object\") fail(\"manifest must be an object\");\n if (!manifest.name || typeof manifest.name !== \"string\") fail(\"name is required\");\n if (!TARGET_NAME.test(manifest.name)) {\n fail(`name \"${manifest.name}\" must start with a letter and contain only letters, digits, and underscore`);\n }\n var schemes = manifest.scheme === void 0 ? [] : Array.isArray(manifest.scheme) ? manifest.scheme : [\n manifest.scheme\n ];\n var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;\n try {\n for (var _iterator = schemes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var scheme = _step.value;\n if (typeof scheme !== \"string\" || !SCHEME.test(scheme)) {\n fail(`scheme \"${scheme}\" must be a valid uri scheme`);\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n if (manifest.version !== void 0 && !VERSION.test(manifest.version)) {\n fail(`version \"${manifest.version}\" must start with major.minor.patch`);\n }\n if (manifest.icon !== void 0 && (!manifest.icon.source || !HEX_COLOR.test(manifest.icon.backgroundColor))) {\n fail(\"icon requires source and a six-digit hex backgroundColor\");\n }\n if (manifest.splash !== void 0 && (!manifest.splash.source || !HEX_COLOR.test(manifest.splash.backgroundColor) || manifest.splash.width !== void 0 && (!Number.isFinite(manifest.splash.width) || manifest.splash.width < 1 || manifest.splash.width > 288))) {\n fail(\"splash requires source, a six-digit hex backgroundColor, and width from 1 to 288\");\n }\n if (((_manifest_imagePicker = manifest.imagePicker) === null || _manifest_imagePicker === void 0 ? void 0 : _manifest_imagePicker.camera) !== void 0 && (typeof manifest.imagePicker.camera !== \"string\" || manifest.imagePicker.camera.trim() === \"\")) {\n fail(\"imagePicker.camera must be a non-empty string\");\n }\n if (!platform || platform === \"ios\") {\n var _manifest_ios;\n if (!((_manifest_ios = manifest.ios) === null || _manifest_ios === void 0 ? void 0 : _manifest_ios.bundleId) || !REVERSE_DNS.test(manifest.ios.bundleId)) {\n var _manifest_ios1;\n fail(`ios.bundleId \"${(_manifest_ios1 = manifest.ios) === null || _manifest_ios1 === void 0 ? void 0 : _manifest_ios1.bundleId}\" must be reverse-dns`);\n }\n if (manifest.ios.deploymentTarget !== void 0 && !DEPLOYMENT_TARGET.test(manifest.ios.deploymentTarget)) {\n fail(`ios.deploymentTarget \"${manifest.ios.deploymentTarget}\" must look like \"17.0\"`);\n }\n if (manifest.ios.buildNumber !== void 0 && !BUILD_NUMBER.test(manifest.ios.buildNumber)) {\n fail(`ios.buildNumber \"${manifest.ios.buildNumber}\" must contain only letters, digits, and dots`);\n }\n }\n if (!platform || platform === \"android\") {\n var _manifest_android;\n if (!((_manifest_android = manifest.android) === null || _manifest_android === void 0 ? void 0 : _manifest_android.applicationId) || !REVERSE_DNS.test(manifest.android.applicationId)) {\n var _manifest_android1;\n fail(`android.applicationId \"${(_manifest_android1 = manifest.android) === null || _manifest_android1 === void 0 ? void 0 : _manifest_android1.applicationId}\" must be reverse-dns`);\n }\n if (manifest.android.minSdk !== void 0 && (!Number.isInteger(manifest.android.minSdk) || manifest.android.minSdk < 21 || manifest.android.minSdk > 36)) {\n fail(`android.minSdk \"${manifest.android.minSdk}\" must be an integer from 21 to 36`);\n }\n if (manifest.android.versionCode !== void 0 && (!Number.isInteger(manifest.android.versionCode) || manifest.android.versionCode < 1)) {\n fail(`android.versionCode \"${manifest.android.versionCode}\" must be a positive integer`);\n }\n if (manifest.android.googleMapsApiKey !== void 0 && (typeof manifest.android.googleMapsApiKey !== \"string\" || manifest.android.googleMapsApiKey.trim() === \"\")) {\n fail(\"android.googleMapsApiKey must be a non-empty string\");\n }\n }\n return manifest;\n}\nexport {\n validateNativeApp\n};\n//# sourceMappingURL=nativeAppManifest.js.map\n"],"mappings":"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"}
1
+ {"version":3,"file":"nativeAppManifest.native.js","names":[],"sources":["esm/nativeAppManifest.native.js"],"sourcesContent":["var TARGET_NAME = /^[A-Za-z][A-Za-z0-9_]*$/;\nvar SCHEME = /^[a-z][a-z0-9+.-]*$/i;\nvar VERSION = /^\\d+\\.\\d+\\.\\d+/;\nvar BUILD_NUMBER = /^[A-Za-z0-9.]+$/;\nvar REVERSE_DNS = /^[A-Za-z][A-Za-z0-9-]*(\\.[A-Za-z][A-Za-z0-9-]*)+$/;\nvar DEPLOYMENT_TARGET = /^\\d+\\.\\d+$/;\nvar HEX_COLOR = /^#[\\da-f]{6}$/i;\nfunction fail(message) {\n throw new Error(`[one] invalid native.app: ${message}`);\n}\nfunction validateNativeApp(manifest, platform) {\n var _manifest_imagePicker;\n if (!manifest || typeof manifest !== \"object\") fail(\"manifest must be an object\");\n if (!manifest.name || typeof manifest.name !== \"string\") fail(\"name is required\");\n if (!TARGET_NAME.test(manifest.name)) {\n fail(`name \"${manifest.name}\" must start with a letter and contain only letters, digits, and underscore`);\n }\n var schemes = manifest.scheme === void 0 ? [] : Array.isArray(manifest.scheme) ? manifest.scheme : [\n manifest.scheme\n ];\n var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;\n try {\n for (var _iterator = schemes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var scheme = _step.value;\n if (typeof scheme !== \"string\" || !SCHEME.test(scheme)) {\n fail(`scheme \"${scheme}\" must be a valid uri scheme`);\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n if (manifest.version !== void 0 && !VERSION.test(manifest.version)) {\n fail(`version \"${manifest.version}\" must start with major.minor.patch`);\n }\n if (manifest.icon !== void 0 && (!manifest.icon.source || !HEX_COLOR.test(manifest.icon.backgroundColor))) {\n fail(\"icon requires source and a six-digit hex backgroundColor\");\n }\n if (manifest.splash !== void 0 && (!manifest.splash.source || !HEX_COLOR.test(manifest.splash.backgroundColor) || manifest.splash.width !== void 0 && (!Number.isFinite(manifest.splash.width) || manifest.splash.width < 1 || manifest.splash.width > 288))) {\n fail(\"splash requires source, a six-digit hex backgroundColor, and width from 1 to 288\");\n }\n if (((_manifest_imagePicker = manifest.imagePicker) === null || _manifest_imagePicker === void 0 ? void 0 : _manifest_imagePicker.camera) !== void 0 && (typeof manifest.imagePicker.camera !== \"string\" || manifest.imagePicker.camera.trim() === \"\")) {\n fail(\"imagePicker.camera must be a non-empty string\");\n }\n if (manifest.notifications !== void 0) {\n if (typeof manifest.notifications !== \"object\" || manifest.notifications.push !== void 0 && typeof manifest.notifications.push !== \"boolean\") {\n fail(\"notifications.push must be a boolean\");\n }\n }\n if (!platform || platform === \"ios\") {\n var _manifest_ios;\n if (!((_manifest_ios = manifest.ios) === null || _manifest_ios === void 0 ? void 0 : _manifest_ios.bundleId) || !REVERSE_DNS.test(manifest.ios.bundleId)) {\n var _manifest_ios1;\n fail(`ios.bundleId \"${(_manifest_ios1 = manifest.ios) === null || _manifest_ios1 === void 0 ? void 0 : _manifest_ios1.bundleId}\" must be reverse-dns`);\n }\n if (manifest.ios.deploymentTarget !== void 0 && !DEPLOYMENT_TARGET.test(manifest.ios.deploymentTarget)) {\n fail(`ios.deploymentTarget \"${manifest.ios.deploymentTarget}\" must look like \"17.0\"`);\n }\n if (manifest.ios.buildNumber !== void 0 && !BUILD_NUMBER.test(manifest.ios.buildNumber)) {\n fail(`ios.buildNumber \"${manifest.ios.buildNumber}\" must contain only letters, digits, and dots`);\n }\n var widgets = manifest.ios.widgets;\n if (widgets) {\n var _widgets_displayName, _widgets_description;\n if (!manifest.ios.deploymentTarget || Number(manifest.ios.deploymentTarget) < 17) {\n fail(\"ios.widgets requires ios.deploymentTarget of 17.0 or newer\");\n }\n if (!/^group\\.[A-Za-z][A-Za-z0-9-]*(\\.[A-Za-z][A-Za-z0-9-]*)+$/.test(widgets.appGroup)) {\n fail(\"ios.widgets.appGroup must be a reverse-dns App Group beginning with group.\");\n }\n if (!/^[A-Za-z][A-Za-z0-9._-]*$/.test(widgets.kind)) {\n fail(\"ios.widgets.kind must be a non-empty WidgetKit kind\");\n }\n if (!((_widgets_displayName = widgets.displayName) === null || _widgets_displayName === void 0 ? void 0 : _widgets_displayName.trim()) || !((_widgets_description = widgets.description) === null || _widgets_description === void 0 ? void 0 : _widgets_description.trim())) {\n fail(\"ios.widgets.displayName and description must be non-empty strings\");\n }\n if (widgets.pushNotifications !== void 0 && typeof widgets.pushNotifications !== \"boolean\") {\n fail(\"ios.widgets.pushNotifications must be a boolean\");\n }\n }\n }\n if (!platform || platform === \"android\") {\n var _manifest_android;\n if (!((_manifest_android = manifest.android) === null || _manifest_android === void 0 ? void 0 : _manifest_android.applicationId) || !REVERSE_DNS.test(manifest.android.applicationId)) {\n var _manifest_android1;\n fail(`android.applicationId \"${(_manifest_android1 = manifest.android) === null || _manifest_android1 === void 0 ? void 0 : _manifest_android1.applicationId}\" must be reverse-dns`);\n }\n if (manifest.android.minSdk !== void 0 && (!Number.isInteger(manifest.android.minSdk) || manifest.android.minSdk < 21 || manifest.android.minSdk > 36)) {\n fail(`android.minSdk \"${manifest.android.minSdk}\" must be an integer from 21 to 36`);\n }\n if (manifest.android.versionCode !== void 0 && (!Number.isInteger(manifest.android.versionCode) || manifest.android.versionCode < 1)) {\n fail(`android.versionCode \"${manifest.android.versionCode}\" must be a positive integer`);\n }\n if (manifest.android.googleMapsApiKey !== void 0 && (typeof manifest.android.googleMapsApiKey !== \"string\" || manifest.android.googleMapsApiKey.trim() === \"\")) {\n fail(\"android.googleMapsApiKey must be a non-empty string\");\n }\n }\n return manifest;\n}\nexport {\n validateNativeApp\n};\n//# sourceMappingURL=nativeAppManifest.js.map\n"],"mappings":";AAAA,IAAI,cAAc;AAClB,IAAI,SAAS;AACb,IAAI,UAAU;AACd,IAAI,eAAe;AACnB,IAAI,cAAc;AAClB,IAAI,oBAAoB;AACxB,IAAI,YAAY;AAChB,SAAS,KAAK,SAAS;CACrB,MAAM,IAAI,MAAM,6BAA6B,SAAS;AACxD;AACA,SAAS,kBAAkB,UAAU,UAAU;CAC7C,IAAI;CACJ,IAAI,CAAC,YAAY,OAAO,aAAa,UAAU,KAAK,4BAA4B;CAChF,IAAI,CAAC,SAAS,QAAQ,OAAO,SAAS,SAAS,UAAU,KAAK,kBAAkB;CAChF,IAAI,CAAC,YAAY,KAAK,SAAS,IAAI,GAAG;EACpC,KAAK,SAAS,SAAS,KAAK,4EAA4E;CAC1G;CACA,IAAI,UAAU,SAAS,WAAW,KAAK,IAAI,CAAC,IAAI,MAAM,QAAQ,SAAS,MAAM,IAAI,SAAS,SAAS,CACjG,SAAS,MACX;CACA,IAAI,4BAA4B,MAAM,oBAAoB,OAAO,iBAAiB,KAAK;CACvF,IAAI;EACF,KAAK,IAAI,YAAY,QAAQ,OAAO,SAAS,CAAC,GAAG,OAAO,EAAE,6BAA6B,QAAQ,UAAU,KAAK,EAAC,CAAE,OAAO,4BAA4B,MAAM;GACxJ,IAAI,SAAS,MAAM;GACnB,IAAI,OAAO,WAAW,YAAY,CAAC,OAAO,KAAK,MAAM,GAAG;IACtD,KAAK,WAAW,OAAO,6BAA6B;GACtD;EACF;CACF,SAAS,KAAK;EACZ,oBAAoB;EACpB,iBAAiB;CACnB,UAAU;EACR,IAAI;GACF,IAAI,CAAC,6BAA6B,UAAU,UAAU,MAAM;IAC1D,UAAU,OAAO;GACnB;EACF,UAAU;GACR,IAAI,mBAAmB;IACrB,MAAM;GACR;EACF;CACF;CACA,IAAI,SAAS,YAAY,KAAK,KAAK,CAAC,QAAQ,KAAK,SAAS,OAAO,GAAG;EAClE,KAAK,YAAY,SAAS,QAAQ,oCAAoC;CACxE;CACA,IAAI,SAAS,SAAS,KAAK,MAAM,CAAC,SAAS,KAAK,UAAU,CAAC,UAAU,KAAK,SAAS,KAAK,eAAe,IAAI;EACzG,KAAK,0DAA0D;CACjE;CACA,IAAI,SAAS,WAAW,KAAK,MAAM,CAAC,SAAS,OAAO,UAAU,CAAC,UAAU,KAAK,SAAS,OAAO,eAAe,KAAK,SAAS,OAAO,UAAU,KAAK,MAAM,CAAC,OAAO,SAAS,SAAS,OAAO,KAAK,KAAK,SAAS,OAAO,QAAQ,KAAK,SAAS,OAAO,QAAQ,OAAO;EAC5P,KAAK,kFAAkF;CACzF;CACA,MAAM,wBAAwB,SAAS,iBAAiB,QAAQ,0BAA0B,KAAK,IAAI,KAAK,IAAI,sBAAsB,YAAY,KAAK,MAAM,OAAO,SAAS,YAAY,WAAW,YAAY,SAAS,YAAY,OAAO,KAAK,MAAM,KAAK;EACtP,KAAK,+CAA+C;CACtD;CACA,IAAI,SAAS,kBAAkB,KAAK,GAAG;EACrC,IAAI,OAAO,SAAS,kBAAkB,YAAY,SAAS,cAAc,SAAS,KAAK,KAAK,OAAO,SAAS,cAAc,SAAS,WAAW;GAC5I,KAAK,sCAAsC;EAC7C;CACF;CACA,IAAI,CAAC,YAAY,aAAa,OAAO;EACnC,IAAI;EACJ,IAAI,GAAG,gBAAgB,SAAS,SAAS,QAAQ,kBAAkB,KAAK,IAAI,KAAK,IAAI,cAAc,aAAa,CAAC,YAAY,KAAK,SAAS,IAAI,QAAQ,GAAG;GACxJ,IAAI;GACJ,KAAK,kBAAkB,iBAAiB,SAAS,SAAS,QAAQ,mBAAmB,KAAK,IAAI,KAAK,IAAI,eAAe,SAAS,sBAAsB;EACvJ;EACA,IAAI,SAAS,IAAI,qBAAqB,KAAK,KAAK,CAAC,kBAAkB,KAAK,SAAS,IAAI,gBAAgB,GAAG;GACtG,KAAK,yBAAyB,SAAS,IAAI,iBAAiB,wBAAwB;EACtF;EACA,IAAI,SAAS,IAAI,gBAAgB,KAAK,KAAK,CAAC,aAAa,KAAK,SAAS,IAAI,WAAW,GAAG;GACvF,KAAK,oBAAoB,SAAS,IAAI,YAAY,8CAA8C;EAClG;EACA,IAAI,UAAU,SAAS,IAAI;EAC3B,IAAI,SAAS;GACX,IAAI,sBAAsB;GAC1B,IAAI,CAAC,SAAS,IAAI,oBAAoB,OAAO,SAAS,IAAI,gBAAgB,IAAI,IAAI;IAChF,KAAK,4DAA4D;GACnE;GACA,IAAI,CAAC,2DAA2D,KAAK,QAAQ,QAAQ,GAAG;IACtF,KAAK,4EAA4E;GACnF;GACA,IAAI,CAAC,4BAA4B,KAAK,QAAQ,IAAI,GAAG;IACnD,KAAK,qDAAqD;GAC5D;GACA,IAAI,GAAG,uBAAuB,QAAQ,iBAAiB,QAAQ,yBAAyB,KAAK,IAAI,KAAK,IAAI,qBAAqB,KAAK,MAAM,GAAG,uBAAuB,QAAQ,iBAAiB,QAAQ,yBAAyB,KAAK,IAAI,KAAK,IAAI,qBAAqB,KAAK,IAAI;IAC5Q,KAAK,mEAAmE;GAC1E;GACA,IAAI,QAAQ,sBAAsB,KAAK,KAAK,OAAO,QAAQ,sBAAsB,WAAW;IAC1F,KAAK,iDAAiD;GACxD;EACF;CACF;CACA,IAAI,CAAC,YAAY,aAAa,WAAW;EACvC,IAAI;EACJ,IAAI,GAAG,oBAAoB,SAAS,aAAa,QAAQ,sBAAsB,KAAK,IAAI,KAAK,IAAI,kBAAkB,kBAAkB,CAAC,YAAY,KAAK,SAAS,QAAQ,aAAa,GAAG;GACtL,IAAI;GACJ,KAAK,2BAA2B,qBAAqB,SAAS,aAAa,QAAQ,uBAAuB,KAAK,IAAI,KAAK,IAAI,mBAAmB,cAAc,sBAAsB;EACrL;EACA,IAAI,SAAS,QAAQ,WAAW,KAAK,MAAM,CAAC,OAAO,UAAU,SAAS,QAAQ,MAAM,KAAK,SAAS,QAAQ,SAAS,MAAM,SAAS,QAAQ,SAAS,KAAK;GACtJ,KAAK,mBAAmB,SAAS,QAAQ,OAAO,mCAAmC;EACrF;EACA,IAAI,SAAS,QAAQ,gBAAgB,KAAK,MAAM,CAAC,OAAO,UAAU,SAAS,QAAQ,WAAW,KAAK,SAAS,QAAQ,cAAc,IAAI;GACpI,KAAK,wBAAwB,SAAS,QAAQ,YAAY,6BAA6B;EACzF;EACA,IAAI,SAAS,QAAQ,qBAAqB,KAAK,MAAM,OAAO,SAAS,QAAQ,qBAAqB,YAAY,SAAS,QAAQ,iBAAiB,KAAK,MAAM,KAAK;GAC9J,KAAK,qDAAqD;EAC5D;CACF;CACA,OAAO;AACT"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vxrn/utils",
3
- "version": "2.0.0-beta.82.1",
3
+ "version": "2.0.0-beta.97.1",
4
4
  "sideEffects": false,
5
5
  "type": "module",
6
6
  "types": "./types/index.d.ts",
@@ -41,12 +41,12 @@
41
41
  "typecheck": "tsc --noEmit"
42
42
  },
43
43
  "dependencies": {
44
- "@vxrn/debug": "2.0.0-beta.82.1",
45
- "@vxrn/resolve": "2.0.0-beta.82.1",
44
+ "@vxrn/debug": "2.0.0-beta.97.1",
45
+ "@vxrn/resolve": "2.0.0-beta.97.1",
46
46
  "ws": "^8.21.0"
47
47
  },
48
48
  "devDependencies": {
49
- "@tamagui/build": "3.0.0-beta.1309.1",
49
+ "@tamagui/build": "3.0.0-beta.1432.1",
50
50
  "@types/ws": "^8.18.1",
51
51
  "vitest": "^4.1.0"
52
52
  },
@@ -72,6 +72,36 @@ describe('native.app manifest', () => {
72
72
  )
73
73
  })
74
74
 
75
+ test('validates the iOS widget target and App Group before prebuild', () => {
76
+ const widgets = {
77
+ appGroup: 'group.dev.one.myapp',
78
+ kind: 'MyAppStatus',
79
+ displayName: 'Status',
80
+ description: 'Current status',
81
+ }
82
+ expect(() =>
83
+ validateNativeApp({ ...app, ios: { ...app.ios, widgets } })
84
+ ).not.toThrow()
85
+ expect(() =>
86
+ validateNativeApp({
87
+ ...app,
88
+ ios: { ...app.ios, widgets: { ...widgets, pushNotifications: 'yes' as any } },
89
+ })
90
+ ).toThrow(/pushNotifications/)
91
+ expect(() =>
92
+ validateNativeApp({
93
+ ...app,
94
+ ios: { ...app.ios, deploymentTarget: '16.4', widgets },
95
+ })
96
+ ).toThrow(/deploymentTarget/)
97
+ expect(() =>
98
+ validateNativeApp({
99
+ ...app,
100
+ ios: { ...app.ios, widgets: { ...widgets, appGroup: 'dev.one.myapp' } },
101
+ })
102
+ ).toThrow(/appGroup/)
103
+ })
104
+
75
105
  test('rejects missing platform ids and out-of-range platform values', () => {
76
106
  expect(() => validateNativeApp({ name: 'MyApp' } as any)).toThrow(/bundleId/)
77
107
  expect(() =>
@@ -129,6 +159,19 @@ describe('native.app manifest', () => {
129
159
  ).toThrow(/versionCode/)
130
160
  })
131
161
 
162
+ test('accepts notifications and rejects a non-boolean push', () => {
163
+ expect(() => validateNativeApp({ ...app, notifications: undefined })).not.toThrow()
164
+ expect(() =>
165
+ validateNativeApp({ ...app, notifications: { push: true } })
166
+ ).not.toThrow()
167
+ expect(() =>
168
+ validateNativeApp({ ...app, notifications: { push: 'yes' } } as any)
169
+ ).toThrow(/notifications\.push/)
170
+ expect(() => validateNativeApp({ ...app, notifications: true } as any)).toThrow(
171
+ /notifications\.push/
172
+ )
173
+ })
174
+
132
175
  test('accepts a maps key and rejects empty ones', () => {
133
176
  expect(() =>
134
177
  validateNativeApp({
@@ -22,6 +22,13 @@ export interface NativeAppManifest {
22
22
  // One.ImagePicker.launchCamera.
23
23
  camera?: string
24
24
  }
25
+ // present when the app uses local notifications. prebuild stamps the
26
+ // android notification permissions and receiver plus the ios delegate gate.
27
+ // push opts into remote push: the fcm source set and the aps-environment
28
+ // entitlement. without it firebase stays out of the app entirely.
29
+ notifications?: {
30
+ push?: boolean
31
+ }
25
32
  ios?: {
26
33
  bundleId: string
27
34
  buildNumber?: string
@@ -33,6 +40,13 @@ export interface NativeAppManifest {
33
40
  usesNonExemptEncryption?: boolean
34
41
  // exposes the app's Documents in the Files app and document pickers.
35
42
  fileSharing?: boolean
43
+ widgets?: {
44
+ appGroup: string
45
+ kind: string
46
+ displayName: string
47
+ description: string
48
+ pushNotifications?: boolean
49
+ }
36
50
  }
37
51
  android?: {
38
52
  applicationId: string
@@ -115,6 +129,15 @@ export function validateNativeApp(
115
129
  ) {
116
130
  fail('imagePicker.camera must be a non-empty string')
117
131
  }
132
+ if (manifest.notifications !== undefined) {
133
+ if (
134
+ typeof manifest.notifications !== 'object' ||
135
+ (manifest.notifications.push !== undefined &&
136
+ typeof manifest.notifications.push !== 'boolean')
137
+ ) {
138
+ fail('notifications.push must be a boolean')
139
+ }
140
+ }
118
141
  if (!platform || platform === 'ios') {
119
142
  if (!manifest.ios?.bundleId || !REVERSE_DNS.test(manifest.ios.bundleId)) {
120
143
  fail(`ios.bundleId "${manifest.ios?.bundleId}" must be reverse-dns`)
@@ -135,6 +158,29 @@ export function validateNativeApp(
135
158
  `ios.buildNumber "${manifest.ios.buildNumber}" must contain only letters, digits, and dots`
136
159
  )
137
160
  }
161
+ const widgets = manifest.ios.widgets
162
+ if (widgets) {
163
+ if (!manifest.ios.deploymentTarget || Number(manifest.ios.deploymentTarget) < 17) {
164
+ fail('ios.widgets requires ios.deploymentTarget of 17.0 or newer')
165
+ }
166
+ if (
167
+ !/^group\.[A-Za-z][A-Za-z0-9-]*(\.[A-Za-z][A-Za-z0-9-]*)+$/.test(widgets.appGroup)
168
+ ) {
169
+ fail('ios.widgets.appGroup must be a reverse-dns App Group beginning with group.')
170
+ }
171
+ if (!/^[A-Za-z][A-Za-z0-9._-]*$/.test(widgets.kind)) {
172
+ fail('ios.widgets.kind must be a non-empty WidgetKit kind')
173
+ }
174
+ if (!widgets.displayName?.trim() || !widgets.description?.trim()) {
175
+ fail('ios.widgets.displayName and description must be non-empty strings')
176
+ }
177
+ if (
178
+ widgets.pushNotifications !== undefined &&
179
+ typeof widgets.pushNotifications !== 'boolean'
180
+ ) {
181
+ fail('ios.widgets.pushNotifications must be a boolean')
182
+ }
183
+ }
138
184
  }
139
185
  if (!platform || platform === 'android') {
140
186
  if (
@@ -15,6 +15,9 @@ export interface NativeAppManifest {
15
15
  imagePicker?: {
16
16
  camera?: string;
17
17
  };
18
+ notifications?: {
19
+ push?: boolean;
20
+ };
18
21
  ios?: {
19
22
  bundleId: string;
20
23
  buildNumber?: string;
@@ -25,6 +28,13 @@ export interface NativeAppManifest {
25
28
  ccache?: boolean;
26
29
  usesNonExemptEncryption?: boolean;
27
30
  fileSharing?: boolean;
31
+ widgets?: {
32
+ appGroup: string;
33
+ kind: string;
34
+ displayName: string;
35
+ description: string;
36
+ pushNotifications?: boolean;
37
+ };
28
38
  };
29
39
  android?: {
30
40
  applicationId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"nativeAppManifest.d.ts","sourceRoot":"","sources":["../src/nativeAppManifest.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE;QACL,MAAM,EAAE,MAAM,CAAA;QACd,eAAe,EAAE,MAAM,CAAA;KACxB,CAAA;IACD,MAAM,CAAC,EAAE;QACP,MAAM,EAAE,MAAM,CAAA;QACd,eAAe,EAAE,MAAM,CAAA;QACvB,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,CAAA;IACD,WAAW,CAAC,EAAE;QAIZ,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;IACD,GAAG,CAAC,EAAE;QACJ,QAAQ,EAAE,MAAM,CAAA;QAChB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,MAAM,CAAC,EAAE,OAAO,CAAA;QAChB,gBAAgB,CAAC,EAAE,MAAM,CAAA;QACzB,YAAY,CAAC,EAAE,OAAO,CAAA;QACtB,aAAa,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;QACpC,MAAM,CAAC,EAAE,OAAO,CAAA;QAChB,uBAAuB,CAAC,EAAE,OAAO,CAAA;QAEjC,WAAW,CAAC,EAAE,OAAO,CAAA;KACtB,CAAA;IACD,OAAO,CAAC,EAAE;QACR,aAAa,EAAE,MAAM,CAAA;QACrB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,YAAY,CAAC,EAAE;YACb,UAAU,CAAC,EAAE,MAAM,CAAA;YACnB,UAAU,CAAC,EAAE,MAAM,CAAA;SACpB,CAAA;QAID,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAC1B,CAAA;CACF;AAiBD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,iBAAiB,EAC3B,QAAQ,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,GACpC,iBAAiB,CAwGnB"}
1
+ {"version":3,"file":"nativeAppManifest.d.ts","sourceRoot":"","sources":["../src/nativeAppManifest.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE;QACL,MAAM,EAAE,MAAM,CAAA;QACd,eAAe,EAAE,MAAM,CAAA;KACxB,CAAA;IACD,MAAM,CAAC,EAAE;QACP,MAAM,EAAE,MAAM,CAAA;QACd,eAAe,EAAE,MAAM,CAAA;QACvB,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,CAAA;IACD,WAAW,CAAC,EAAE;QAIZ,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;IAKD,aAAa,CAAC,EAAE;QACd,IAAI,CAAC,EAAE,OAAO,CAAA;KACf,CAAA;IACD,GAAG,CAAC,EAAE;QACJ,QAAQ,EAAE,MAAM,CAAA;QAChB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,MAAM,CAAC,EAAE,OAAO,CAAA;QAChB,gBAAgB,CAAC,EAAE,MAAM,CAAA;QACzB,YAAY,CAAC,EAAE,OAAO,CAAA;QACtB,aAAa,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;QACpC,MAAM,CAAC,EAAE,OAAO,CAAA;QAChB,uBAAuB,CAAC,EAAE,OAAO,CAAA;QAEjC,WAAW,CAAC,EAAE,OAAO,CAAA;QACrB,OAAO,CAAC,EAAE;YACR,QAAQ,EAAE,MAAM,CAAA;YAChB,IAAI,EAAE,MAAM,CAAA;YACZ,WAAW,EAAE,MAAM,CAAA;YACnB,WAAW,EAAE,MAAM,CAAA;YACnB,iBAAiB,CAAC,EAAE,OAAO,CAAA;SAC5B,CAAA;KACF,CAAA;IACD,OAAO,CAAC,EAAE;QACR,aAAa,EAAE,MAAM,CAAA;QACrB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,YAAY,CAAC,EAAE;YACb,UAAU,CAAC,EAAE,MAAM,CAAA;YACnB,UAAU,CAAC,EAAE,MAAM,CAAA;SACpB,CAAA;QAID,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAC1B,CAAA;CACF;AAiBD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,iBAAiB,EAC3B,QAAQ,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,GACpC,iBAAiB,CAwInB"}