nana800-remote-config 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -95,13 +95,22 @@ Loads the variables for the given user and returns `true` on success.
95
95
 
96
96
  ### `getString(name)`, `getNumber(name)`, `getBoolean(name)`
97
97
  Return the variable converted to the requested type, or `undefined` when the variable is missing, cannot be converted, or `initFetch` has not succeeded yet.
98
- `getNumber` accepts numeric strings, `getBoolean` accepts `"true"` and `"false"`.
98
+ `getNumber` accepts numeric strings, `getBoolean` accepts `"true"` and `"false"`, `getString` returns objects and arrays as JSON text.
99
+
100
+ ### `getJSON<T>(name)`
101
+ Returns the value of a JSON variable. JSON variables arrive already parsed: an object, an array, a string, a number, a boolean or `null`.
102
+
103
+ ```ts
104
+ type Banner = { title: string; url: string }
105
+ const banner = nana800RemoteConfig.getJSON<Banner>('main_banner')
106
+ ```
99
107
 
100
108
  ### `getReceivedVariablesObject()`
101
109
  Returns a copy of all received variables.
102
110
 
103
111
  ### `getLastError()`
104
112
  Returns the error text of the last unsuccessful `initFetch` call.
113
+ The fetch endpoint allows 100 requests per 3 seconds and 300 requests per 10 seconds from one IP, above that it answers `HTTP 429`.
105
114
 
106
115
  ### `isFetched`
107
116
  `true` after the first successful `initFetch` call.
package/dist/main.cjs.js CHANGED
@@ -39,16 +39,9 @@ var RemoteConfigPlatform = /* @__PURE__ */ ((RemoteConfigPlatform2) => {
39
39
  })(RemoteConfigPlatform || {});
40
40
  var isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
41
41
  var toRecordsMap = (value) => {
42
- const result = {};
43
- if (!isPlainObject(value)) return result;
44
- for (const key of Object.keys(value)) {
45
- const item = value[key];
46
- if (typeof item === "string" || typeof item === "number" || typeof item === "boolean") {
47
- result[key] = item;
48
- }
49
- }
50
- return result;
42
+ return isPlainObject(value) ? value : {};
51
43
  };
44
+ var cloneValue = (value) => value !== null && typeof value === "object" ? JSON.parse(JSON.stringify(value)) : value;
52
45
  var getErrorMessage = (error) => {
53
46
  if (error instanceof Error) {
54
47
  return error.name === "AbortError" || error.name === "TimeoutError" ? "request timed out" : error.message;
@@ -95,11 +88,16 @@ var Nana800RemoteConfig = class {
95
88
  return this.lastError;
96
89
  });
97
90
  __publicField(this, "getReceivedVariablesObject", () => {
98
- return { ...this.storage };
91
+ return cloneValue(this.storage);
99
92
  });
100
93
  __publicField(this, "getString", (variable_name) => {
101
94
  const value = this.getVariable(variable_name);
102
- return value === void 0 ? void 0 : String(value);
95
+ if (value === void 0 || value === null) return void 0;
96
+ return typeof value === "object" ? JSON.stringify(value) : String(value);
97
+ });
98
+ /** value of a JSON variable (object, array, string, number, boolean or null), returned as received */
99
+ __publicField(this, "getJSON", (variable_name) => {
100
+ return cloneValue(this.getVariable(variable_name));
103
101
  });
104
102
  __publicField(this, "getNumber", (variable_name) => {
105
103
  const value = this.getVariable(variable_name);
package/dist/main.d.mts CHANGED
@@ -1,4 +1,8 @@
1
- export type RemoteConfigValue = number | string | boolean | undefined;
1
+ /** value of a JSON variable, already parsed */
2
+ export type RemoteConfigJSONValue = string | number | boolean | null | RemoteConfigJSONValue[] | {
3
+ [key: string]: RemoteConfigJSONValue;
4
+ };
5
+ export type RemoteConfigValue = RemoteConfigJSONValue | undefined;
2
6
  export type RemoteConfigRecordsMapType = Record<string, RemoteConfigValue>;
3
7
  export declare enum RemoteConfigPlatform {
4
8
  WEB = "WEB",
@@ -29,6 +33,8 @@ declare class Nana800RemoteConfig {
29
33
  getLastError: () => string;
30
34
  getReceivedVariablesObject: () => RemoteConfigRecordsMapType;
31
35
  getString: (variable_name: string) => string | undefined;
36
+ /** value of a JSON variable (object, array, string, number, boolean or null), returned as received */
37
+ getJSON: <T = RemoteConfigJSONValue>(variable_name: string) => T | undefined;
32
38
  getNumber: (variable_name: string) => number | undefined;
33
39
  getBoolean: (variable_name: string) => boolean | undefined;
34
40
  private getVariable;
package/dist/main.d.ts CHANGED
@@ -1,4 +1,8 @@
1
- export type RemoteConfigValue = number | string | boolean | undefined;
1
+ /** value of a JSON variable, already parsed */
2
+ export type RemoteConfigJSONValue = string | number | boolean | null | RemoteConfigJSONValue[] | {
3
+ [key: string]: RemoteConfigJSONValue;
4
+ };
5
+ export type RemoteConfigValue = RemoteConfigJSONValue | undefined;
2
6
  export type RemoteConfigRecordsMapType = Record<string, RemoteConfigValue>;
3
7
  export declare enum RemoteConfigPlatform {
4
8
  WEB = "WEB",
@@ -29,6 +33,8 @@ declare class Nana800RemoteConfig {
29
33
  getLastError: () => string;
30
34
  getReceivedVariablesObject: () => RemoteConfigRecordsMapType;
31
35
  getString: (variable_name: string) => string | undefined;
36
+ /** value of a JSON variable (object, array, string, number, boolean or null), returned as received */
37
+ getJSON: <T = RemoteConfigJSONValue>(variable_name: string) => T | undefined;
32
38
  getNumber: (variable_name: string) => number | undefined;
33
39
  getBoolean: (variable_name: string) => boolean | undefined;
34
40
  private getVariable;
package/dist/main.mjs CHANGED
@@ -16,16 +16,9 @@ var RemoteConfigPlatform = /* @__PURE__ */ ((RemoteConfigPlatform2) => {
16
16
  })(RemoteConfigPlatform || {});
17
17
  var isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
18
18
  var toRecordsMap = (value) => {
19
- const result = {};
20
- if (!isPlainObject(value)) return result;
21
- for (const key of Object.keys(value)) {
22
- const item = value[key];
23
- if (typeof item === "string" || typeof item === "number" || typeof item === "boolean") {
24
- result[key] = item;
25
- }
26
- }
27
- return result;
19
+ return isPlainObject(value) ? value : {};
28
20
  };
21
+ var cloneValue = (value) => value !== null && typeof value === "object" ? JSON.parse(JSON.stringify(value)) : value;
29
22
  var getErrorMessage = (error) => {
30
23
  if (error instanceof Error) {
31
24
  return error.name === "AbortError" || error.name === "TimeoutError" ? "request timed out" : error.message;
@@ -72,11 +65,16 @@ var Nana800RemoteConfig = class {
72
65
  return this.lastError;
73
66
  });
74
67
  __publicField(this, "getReceivedVariablesObject", () => {
75
- return { ...this.storage };
68
+ return cloneValue(this.storage);
76
69
  });
77
70
  __publicField(this, "getString", (variable_name) => {
78
71
  const value = this.getVariable(variable_name);
79
- return value === void 0 ? void 0 : String(value);
72
+ if (value === void 0 || value === null) return void 0;
73
+ return typeof value === "object" ? JSON.stringify(value) : String(value);
74
+ });
75
+ /** value of a JSON variable (object, array, string, number, boolean or null), returned as received */
76
+ __publicField(this, "getJSON", (variable_name) => {
77
+ return cloneValue(this.getVariable(variable_name));
80
78
  });
81
79
  __publicField(this, "getNumber", (variable_name) => {
82
80
  const value = this.getVariable(variable_name);
@@ -18,16 +18,9 @@
18
18
  })(RemoteConfigPlatform || {});
19
19
  var isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
20
20
  var toRecordsMap = (value) => {
21
- const result = {};
22
- if (!isPlainObject(value)) return result;
23
- for (const key of Object.keys(value)) {
24
- const item = value[key];
25
- if (typeof item === "string" || typeof item === "number" || typeof item === "boolean") {
26
- result[key] = item;
27
- }
28
- }
29
- return result;
21
+ return isPlainObject(value) ? value : {};
30
22
  };
23
+ var cloneValue = (value) => value !== null && typeof value === "object" ? JSON.parse(JSON.stringify(value)) : value;
31
24
  var getErrorMessage = (error) => {
32
25
  if (error instanceof Error) {
33
26
  return error.name === "AbortError" || error.name === "TimeoutError" ? "request timed out" : error.message;
@@ -74,11 +67,16 @@
74
67
  return this.lastError;
75
68
  });
76
69
  __publicField(this, "getReceivedVariablesObject", () => {
77
- return { ...this.storage };
70
+ return cloneValue(this.storage);
78
71
  });
79
72
  __publicField(this, "getString", (variable_name) => {
80
73
  const value = this.getVariable(variable_name);
81
- return value === void 0 ? void 0 : String(value);
74
+ if (value === void 0 || value === null) return void 0;
75
+ return typeof value === "object" ? JSON.stringify(value) : String(value);
76
+ });
77
+ /** value of a JSON variable (object, array, string, number, boolean or null), returned as received */
78
+ __publicField(this, "getJSON", (variable_name) => {
79
+ return cloneValue(this.getVariable(variable_name));
82
80
  });
83
81
  __publicField(this, "getNumber", (variable_name) => {
84
82
  const value = this.getVariable(variable_name);
@@ -1 +1 @@
1
- "use strict";(()=>{var m=Object.defineProperty;var b=(r,e,t)=>e in r?m(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var n=(r,e,t)=>b(r,typeof e!="symbol"?e+"":e,t);var h="x-nana-api-key",y="https://api.nana800.io";var c="nana800-remote-config:",l=(o=>(o.WEB="WEB",o.ANDROID="ANDROID",o.IOS="IOS",o.DESKTOP="DESKTOP",o))(l||{}),R=r=>typeof r=="object"&&r!==null&&!Array.isArray(r),E=r=>{let e={};if(!R(r))return e;for(let t of Object.keys(r)){let s=r[t];(typeof s=="string"||typeof s=="number"||typeof s=="boolean")&&(e[t]=s)}return e},T=r=>r instanceof Error?r.name==="AbortError"||r.name==="TimeoutError"?"request timed out":r.message:String(r),u=class{constructor(){n(this,"storage",{});n(this,"lastError","");n(this,"isFetched",!1);n(this,"initFetch",async(e,t={})=>{var g;let s=(t.base_url||y).replace(/\/+$/,""),o=typeof AbortController!="undefined"?new AbortController:null,f=o?setTimeout(()=>o.abort(),(g=t.timeout_ms)!=null?g:1e4):null;try{let a=await fetch(`${s}/remote_config_records/fetch_user_remote_config_records`,{method:"POST",headers:{"Content-Type":"application/json",[h]:(e==null?void 0:e.api_key)||""},body:JSON.stringify(e),signal:o==null?void 0:o.signal}),i=await a.json().catch(()=>null);return!a.ok||!(i!=null&&i.success)?(this.lastError=(i==null?void 0:i.error_text)||`HTTP ${a.status}`,console.warn(c,"fetch was not successful:",this.lastError),!1):(this.storage=E(i.records),this.isFetched=!0,this.lastError="",!0)}catch(a){return this.lastError=T(a),console.warn(c,"fetch request error:",this.lastError),!1}finally{f&&clearTimeout(f)}});n(this,"getLastError",()=>this.lastError);n(this,"getReceivedVariablesObject",()=>({...this.storage}));n(this,"getString",e=>{let t=this.getVariable(e);return t===void 0?void 0:String(t)});n(this,"getNumber",e=>{let t=this.getVariable(e);if(typeof t=="number")return t;if(typeof t=="string"&&t.trim()!==""){let s=Number(t);return Number.isFinite(s)?s:void 0}});n(this,"getBoolean",e=>{let t=this.getVariable(e);if(typeof t=="boolean")return t;if(t==="true")return!0;if(t==="false")return!1});n(this,"getVariable",e=>{if(!this.isFetched){console.warn(c,"remote config variables list is not fetched. please run initFetch before.");return}return Object.prototype.hasOwnProperty.call(this.storage,e)?this.storage[e]:void 0})}},p=new u;var d=globalThis;d.nana800RemoteConfig=p;d.RemoteConfigPlatform=l;})();
1
+ "use strict";(()=>{var b=Object.defineProperty;var R=(e,r,t)=>r in e?b(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t;var n=(e,r,t)=>R(e,typeof r!="symbol"?r+"":r,t);var h="x-nana-api-key",y="https://api.nana800.io";var c="nana800-remote-config:",l=(o=>(o.WEB="WEB",o.ANDROID="ANDROID",o.IOS="IOS",o.DESKTOP="DESKTOP",o))(l||{}),T=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),E=e=>T(e)?e:{},p=e=>e!==null&&typeof e=="object"?JSON.parse(JSON.stringify(e)):e,O=e=>e instanceof Error?e.name==="AbortError"||e.name==="TimeoutError"?"request timed out":e.message:String(e),u=class{constructor(){n(this,"storage",{});n(this,"lastError","");n(this,"isFetched",!1);n(this,"initFetch",async(r,t={})=>{var g;let a=(t.base_url||y).replace(/\/+$/,""),o=typeof AbortController!="undefined"?new AbortController:null,f=o?setTimeout(()=>o.abort(),(g=t.timeout_ms)!=null?g:1e4):null;try{let i=await fetch(`${a}/remote_config_records/fetch_user_remote_config_records`,{method:"POST",headers:{"Content-Type":"application/json",[h]:(r==null?void 0:r.api_key)||""},body:JSON.stringify(r),signal:o==null?void 0:o.signal}),s=await i.json().catch(()=>null);return!i.ok||!(s!=null&&s.success)?(this.lastError=(s==null?void 0:s.error_text)||`HTTP ${i.status}`,console.warn(c,"fetch was not successful:",this.lastError),!1):(this.storage=E(s.records),this.isFetched=!0,this.lastError="",!0)}catch(i){return this.lastError=O(i),console.warn(c,"fetch request error:",this.lastError),!1}finally{f&&clearTimeout(f)}});n(this,"getLastError",()=>this.lastError);n(this,"getReceivedVariablesObject",()=>p(this.storage));n(this,"getString",r=>{let t=this.getVariable(r);if(t!=null)return typeof t=="object"?JSON.stringify(t):String(t)});n(this,"getJSON",r=>p(this.getVariable(r)));n(this,"getNumber",r=>{let t=this.getVariable(r);if(typeof t=="number")return t;if(typeof t=="string"&&t.trim()!==""){let a=Number(t);return Number.isFinite(a)?a:void 0}});n(this,"getBoolean",r=>{let t=this.getVariable(r);if(typeof t=="boolean")return t;if(t==="true")return!0;if(t==="false")return!1});n(this,"getVariable",r=>{if(!this.isFetched){console.warn(c,"remote config variables list is not fetched. please run initFetch before.");return}return Object.prototype.hasOwnProperty.call(this.storage,r)?this.storage[r]:void 0})}},d=new u;var m=globalThis;m.nana800RemoteConfig=d;m.RemoteConfigPlatform=l;})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nana800-remote-config",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Remote Config (remote variables) client for the NANA800.io platform",
5
5
  "license": "MIT",
6
6
  "homepage": "https://nana800.gitbook.io/doc/features/remote-config-peremennye",