raiutils 8.7.11 → 9.0.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.
package/README.md CHANGED
@@ -1,128 +1,122 @@
1
1
  # Utils.js
2
- ###### If you, like many devs, prefer native JS to jQuery or similar heavy/bloated frameworks, but can't live without those one or two essential features, then you need Utils.js!
2
+ ###### If you prefer native JS to jQuery or using bloated web frameworks, but can't live without those one or two essential features, then you need Utils.js!
3
3
 
4
- ### Now includes Node.js support!
4
+ Also check out [C-Utils](https://github.com/Pecacheu/C-Utils) and [PyColorUtils](https://github.com/Pecacheu/PyColor).
5
+
6
+ ### Now includes TypeScript & Node.js support!
7
+
8
+ Install via `npm i raiutils`. You can also use raiutils in the browser without a package manager! Simply bundle the minified `dist/utils.min.js`. The package is built to work down to **es2018**, so any vaguely modern browser should work. *(Warning: BigInt won't work before `es2020`, but BigInt functions in this library fallback silently to Numbers.)*
9
+
10
+ # RaiUtils
11
+ The base package contains a ton of useful features and language extensions, which work in both NodeJS and the browser, whether you use a package manager or not! It also bundles in some polyfills for newly available features
5
12
 
6
- Importing in Node works slightly different to most packages, due to the browser/Node.js auto-detection. Install via `npm i raiutils` and import as follows:
7
13
  ```js
8
- import 'utils.js';
14
+ import utils from 'raiutils';
9
15
 
10
- console.log("Hello utils", utils.VER);
16
+ console.log("Hello utils", utils.VER, await utils.getIPs());
11
17
  ```
12
18
 
13
- For client-side use, the minified *utils.min.js* is recommended (Minified with https://toptal.com/developers/javascript-minifier).
14
-
15
- *Note: More detailed usage & help available in utils.js!*
19
+ For a complete list of functions, please check `src/utils.ts` or use an IDE that supports JSDoc.
16
20
 
17
21
  ## Most popular features
22
+ - `UserAgentInfo utils.device` Parsed info about the user's device from the UserAgent.
23
+ - `Boolean utils.mobile` True if running on a mobile device, based on the UserAgent.
24
+ - `utils.mkEl` / `utils.mkDiv` Generate DOM elements with ease! Just remember PCSI: *Parent, class, style, and innerHTML.* Set any option to *null* to skip it.
25
+ - `[Array].each` / `[Array].eachAsync` Works similar to *[Array].forEach*, but allows a custom start and end index (including negative for relative-to-end), enables deleting elements during iteration by returning `!`, and if any other value besides *null* is returned, *each()* breaks the loop and returns the value in question, enabling slick one-liners that search an array for a specific condition.
26
+ - `UtilRect` Getting the bounds/position of an element used to be a complete mess with incompatibilities across every browser. **Not anymore!** Use UtilRects to keep track of your object positions! Simply access the *boundingRect* property of any Element and you can access it's *top*, *bottom*, *left*, *right*, *width*, and *height* on the client's screen! If you need this relative to the top of the page, it's as simple as `Element.boundingRect.top + window.scrollY`.
27
+ - `utils.center` Does what it says on the tin! Input an Element, choose whether you want X, Y, or by default, both, and change the centering type.
28
+ - `utils.rand` Generate random numbers from min to max, with optional decimal resolution and bias curve.
29
+ - `utils.abs` / `utils.min` / `utils.max` Like their **Math** equivalents, but they work with **BigInt** too!
30
+
31
+ # Router
32
+ A super-lightweight minimal web server engine for Node.js. Easy to use, but safe from naughty tricks like directory traversal, built-in support for common MIME types, client caching via the `etag` header, and even streaming media download via `content-range`.
33
+
34
+ ```js
35
+ import http from 'http';
36
+ import router from 'raiutils/router';
37
+
38
+ const debug = 1,
39
+ dir = import.meta.dirname,
40
+ root = dir+"/web",
41
+ vDir = {
42
+ 'coffee.js': dir+"/scripts/coffee.js"
43
+ };
44
+
45
+ router.debug = debug;
46
+
47
+ http.createServer((req, res) => {
48
+ if(debug) console.log("[REQ]", req.url);
49
+ //Special overrides
50
+ if(req.url === '/game/theory') {
51
+ res.write("Hello internet!");
52
+ res.end();
53
+ } else {
54
+ //Standard pages
55
+ router.handle(root, req, res, vDir);
56
+ }
57
+ }).listen(8080, () => {
58
+ console.log("Server up at http://localhost:8080");
59
+ });
60
+ ```
61
+
62
+ ## Methods
63
+ - `handle(root, req, res[, vDir])` Serve files from a directory
64
+ - `serve(path, req, res)` Serve a single file to the client
65
+ - `sendCode(res, code, msg)` Send an error page to the client
66
+ - `etagMode` Set etag mode for client-side caching
67
+ - `types` Map of common MIME types
68
+
69
+ # UUID
70
+ This module provides **ChuID**, a 64-bit UUID format that outputs as a compact, 11 character Base64 string. ChuID is made for situations where a longer 128-bit format like UUIDv4 is overkill.
71
+
72
+ Format: `<U8 Uptime><U8 Magic><U8 CryptoRand><U8 Counter><U32 Date>`
73
+
74
+ *Note: For browser use, UUID requires `npm i buffer`.*
75
+
76
+ ```js
77
+ import UUID from 'raiutils/uuid';
78
+
79
+ //Current date, magic value 15
80
+ const id = UUID.genUUID(0, 15);
81
+
82
+ console.log(id, `String: ${id}\n`,
83
+ id.getDate(), id.getMagic());
84
+ ```
85
+
86
+ ## Methods
87
+ - `new UUID(id)` Construct from a string, Buffer, or if *mongodb* is installed, mdb.Long
88
+ - `UUID.genUUID([date[, magic]])` Generate new random UUID w/ optional date and magic
89
+
90
+ # ChuSchema
91
+ **ChuSchema** is an easy-to-use schema format that provides rigorous yet flexible validation of JSON input to ensure it follows the desired structure.
92
+
93
+ ```js
94
+ import CS from 'raiutils/schema';
95
+
96
+ const schema = {
97
+ name: {t:'str', f:/^[a-z]+$/},
98
+ signals: {t:'list', c:'bool'},
99
+ vals: {t:'list', f:{
100
+ count: {t:'int', min:0, req:false},
101
+ hey: {t:'bool', rej:par => par.count===0}
102
+ }}
103
+ }
104
+
105
+ try {
106
+ CS.checkSchema({
107
+ name: "abc",
108
+ signals: [true, false],
109
+ vals: [
110
+ {count: 15, hey: true}
111
+ ]
112
+ }, schema);
113
+ } catch(e) {
114
+ console.log("Schema check failed @", e);
115
+ }
116
+ ```
18
117
 
19
- **utils.mkEl(t,p,c,s,i) / utils.mkDiv(p,c,s,i)**: Generate DOM elements programmatically with ease! To use these quickly and efficiently, just remember PCSI: Parent Node, Class List, Style Object, and InnerHTML. Set any to *null* to skip it.
20
-
21
- **[Array].each / [Array].eachAsync**: Works similar to *[Array].forEach*, but allows a custom start and end index (including negative for relative-to-end), enables deleting elements during iteration by returning a '!', and if any other value besides *null* is returned, *each()* breaks the loop and returns the value in question, enabling slick one-liners that search an array for a specific condition.
22
-
23
- **UtilRect**: Getting the bounds/position of an element used to be a complete mess with incompatibilities across every browser. **Not anymore!** Use UtilRects to keep track of your object positions! Simply access the *boundingRect* property of any Element and you can access it's *top*, *bottom*, *left*, *right*, *width*, and *height* on the client's screen! If you need this relative to the top of the page, it's as simple as `Element.boundingRect.top + window.scrollY`.
24
-
25
- **utils.center(obj[,only[,type]])**: Does what it says on the tin! Input an Element, choose whether you want X, Y, or by default, both, and change the centering type.
26
-
27
- **[Function].wrap**: This can be quite useful in combination with functions like *setTimeout*, for example `setTimeout(console.log.wrap("Hello!"), 50)`. Also sets the *this* object inside the function to *arguments*, in case you want to access the calling arguments as well!
28
-
29
- ## Also Included
30
-
31
- *Documentation on UUID, Router.js, and ChuSchema coming soon!*
32
-
33
- ## Custom Classes
34
- - `UtilRect` Better class for working with element bounds.
35
- - `Easing` Easing functions for use with *utils.map*.
36
-
37
- ## Prototype Extensions
38
- - `[Function].wrap(...) returns Function` Wrap a function so that it always has a preset argument list when called.
39
- - `String.trim() polyfill`
40
- - `[String].startsWith(s) returns Boolean` Like Java.
41
- - `[String].endsWith(s) returns Boolean` Like Java.
42
- - `[Array].clean(kz)` Remove 'empty' elements like 0, false, ' ', undefined, and NaN from an array. Set 'kz' to true to keep '0's
43
- - `[Array].remove(item) returns Boolean` Remove first instance of item from array. Returns false if not found.
44
- - `[Array].each(fn[,start[,end]]) returns Any` Calls fn on each index of array, with optional start and end index.
45
- - `[Array].eachAsync(fn[,start[,end[,pe=true]]]) returns Any` Like `each` but async.
46
- - `Number [Element].index` Represents an element's index in it's parent. Set to -1 if the element has no parent.
47
- - `[Element].insertChildAt(el,i)` Inserts child at index. Appends child to end if index exceeds child count.
48
- - `UtilRect [Element].boundingRect` Element's bounding rect as a `UtilRect` object.
49
- - `UtilRect [Element].innerRect` Element's inner rect (excluding margin, padding, and border)
50
- - `[TouchList].get(id) returns Touch` Gets touch by id, returns null if none found.
51
- - `[Uint8Array].toBase64([opts]) returns String` Polyfill; See MDN docs.
52
- - `Uint8Array.fromBase64(str[, opts]) returns Uint8Array` Polyfill; See MDN docs.
53
- - `RegExp.escape(string) return String` Polyfill; See MDN docs.
54
-
55
- ## Main Class
56
- - `String utils.VER` Current library version.
57
- - `Number utils.w` and `Number utils.h` Cross-platform window width and height.
58
- - `Boolean utils.mobile` Will be **true** if running on a mobile device, based on the UserAgent.
59
- - `utils.setCookie(name,value,exp,secure)` Set a cookie.
60
- - `utils.getCookie(name) returns String or null` Get a cookie by name.
61
- - `utils.remCookie(name)` Remove a cookie by name.
62
- - `utils.setPropSafe(obj, path, val, onlyNull=false)` Set a nested property, even if higher levels don't exist. Useful for defining settings in a complex config object.
63
- - `utils.getPropSafe(obj, path) returns Object` Gets a nested property, returns undefined if any level doesn't exist.
64
- - `utils.copy(o[,sub]) returns Object` Deep (recursive) Object.create. Copies down to given sub levels, all levels if undefined.
65
- - `utils.numField(field[,min[,max[,decMax[,sym]]]])` Turns your boring input field into a mobile-friendly integer, decimal, or financial entry field with max/min & negative support!
66
- - `utils.autosize(el, maxRows=5, minRows=1)` Auto-resizing textarea, dynamically scales lineHeight based on input.
67
- - `utils.formatCost(n[,sym]) returns String` Format Number as currency. Uses '$' by default.
68
- - `utils.setDateTime(el, date)` Set 'datetime-local' or 'date' input from JS Date, adjusting for local timezone.
69
- - `utils.getDateTime(el) returns Date` Get value of 'datetime-local' or 'date' input as JS Date.
70
- - `utils.formatDate(date[,opts]) returns String` Format Date object into a pretty string, with various options.
71
- - `utils.months` Array of 3-letter month names from Jan to Dec.
72
- - `utils.suffix(n) returns String` Add appropriate suffix to number. (ex. 31st, 12th, 22nd)
73
- - `utils.goBack()` For AJAX navigation. Presses back button.
74
- - `utils.goForward()` For AJAX navigation. Presses forward button.
75
- - `utils.go(url, data)` Push new history state for AJAX navigation. You can provide additional data to access later.
76
- - `utils.onNav = function(data)` Callback called when the browser wants to navigate to a page. Provides the optional data argument supplied to `utils.go`. Also called when the page is first loaded, directly after `window.onload`.
77
- - `utils.mkEl(tag,parent,class,styles,innerHTML) returns Element` Quickly create element with parent, classes, style properties (as key/value pairs), and innerHTML content. All parameters (except for tag) are optional.
78
- - `utils.mkDiv` Same as utils.mkEl, but assumes 'div' for tag.
79
- - `utils.addText(el,text)` Appends a TextNode with given text to element.
80
- - `utils.textWidth(text,font) returns Number` Get predicted width of text given css font style.
81
- - `utils.define(obj,name,get,set)` Add getter/setter pair to an existing object. Get or set may be null to disable.
82
- - `utils.proto(obj,name,val[,static])` Define immutable, non-enumerable property or method in an object prototype (or object if 'static' is **true**).
83
- - `utils.isBlank(o) returns Boolean` Check if string, array, or other object is empty.
84
- - `utils.firstEmpty(arr) returns Number` Finds first empty (undefined/null) slot in array.
85
- - `utils.firstEmptyChar(obj) returns String` Like *firstEmpty*, but uses letters from `utils.numToChar` instead.
86
- - `utils.numToChar(n) returns String` Converts a number into letters (upper and lower) from a to Z.
87
- - `utils.merge(target,source[,source2...]) returns target` Merges two (or more) objects, giving the last precedence. If both objects contain a property at the same index, and both are Arrays/Objects, they are merged.
88
- - `utils.cutStr(s,rem) returns String` Finds and removes all instances of 'rem' contained within String 's'
89
- - `utils.dCut(data,startString,endString[,index[,searchStart]]) returns String` Cuts text out of 'data' from first instance of 'startString' to next instance of 'endString'.
90
- - `utils.dCutToLast(data,startString,endString[,index[,searchStart]]) returns String` Same as *utils.dCut* but using lastIndexOf for end search.
91
- - `utils.dCutLast(data,startString,endString[,index[,searchStart]]) returns String` Same as *utils.dCut* but using lastIndexOf for start search.
92
- - `utils.parseCSS(prop) returns Object` Given css property value 'prop', returns object with space-separated values from the property string.
93
- - `utils.buildCSS(obj) returns String` Rebuilds css string from a *parseCSS* object.
94
- - `utils.addClass(class,propList)` Create a css class and append it to the current document. Fill 'propList' object with key/value pairs representing the properties you want to add to the class.
95
- - `utils.addId(id,propList)` Create a css selector and append it to the current document.
96
- - `utils.addKeyframe(name,content)` Create a css keyframe and append it to the current document.
97
- - `utils.removeSelector(name)` Remove a specific css selector (including the '.' or '#') from all stylesheets in the current document.
98
- - `utils.fromQuery(str) returns Object` Parses a url query string into an Object.
99
- - `utils.toQuery(obj) returns String` Converts an object into a url query string.
100
- - `utils.center(obj[,only[,type]])` Center objects with JavaScript, using a variety of methods. *See utils.js for details.*
101
- - `utils.loadAjax(path,[callback[, meth[, body[, hdList]]]])` Loads a file and returns it's contents, using GET by default. *See utils.js for details.*
102
- - `utils.loadJSONP(path,callback,timeout)` Loads a file at the address from a JSONP-enabled server. Callback is fired with either received data, or **false** if unsuccessful.
103
- - `utils.loadFile(path,callback,timeout)` Good fallback for `utils.loadAjax`. Loads a file at the address via HTML object tag. Callback is fired with either received data, or **false** if unsuccessful.
104
- - `utils.dlFile(filename,uri) returns Promise` Downloads a file from a link.
105
- - `utils.dlData(filename,data)` Downloads a file generated from a Blob or ArrayBuffer.
106
-
107
- - `utils.delay(ms) returns Promise` setTimeout but async.
108
-
109
- ## Math & Numbers
110
- Math operations that work with both `Number` and `BigInt`.
111
-
112
- - `utils.abs(x)` / `utils.min(x)` / `utils.max(x)` Work like their **Math** equivalents.
113
- - `utils.fixedNum(n,len[,radix=10]) returns String` Fix number to a given minimum length with padded 0's. Adds '0b' for binary *(radix=2)* and '0x' for hex *(radix=16)*
114
- - `utils.bounds(n,min=0,max=1) returns Number` Truncate n to range [min,max]. Also handles NaN or null.
115
- - `utils.norm` *OR* `utils.normalize(n,min=0,max=1) returns Number` Normalize n to the range [min,max). This can be used to normalize angles.
116
-
117
- ### Number Only
118
- - `Math.cot(x) returns Number` No idea why this isn't built-in, but it's not.
119
- - `utils.rad(deg)` / `utils.deg(rad)` Convert between radians and degrees.
120
- - `utils.map(input,minIn,maxIn,minOut,maxOut,ease) returns Number` For unit translation and JS animation! See ease functions in *untils.js*.
121
- - `utils.hexToRgb(hex) returns Number` Converts HEX color to 24-bit RGB.
122
- - `utils.rgbToHsl(r,g,b) returns [Number, Number, Number]` Converts R,G,B to H,S,L values.
123
- - `utils.rand(min,max[,res[,ease]]) returns Number` Generates random from min to max, optionally with a decimal resolution (10, 100, 1000, etc.) or custom ease, changing the probability of various numbers being generated
124
-
125
- ## Node.js Only
126
- - `utils.waitInit() returns Promise` You must await this before you can use any of the Node.js methods below.
127
- - `utils.getIPs() returns List[String] or null` Get list of system IPs, or null if no network found.
128
- - `utils.getOS() returns [String, String, String]` Get system OS, arch, and CPU info.
118
+ ## Methods
119
+ - `checkSchema(data, schema[, opt])` Check data against a schema
120
+ - `checkType(val, ent[, opt])` Check value against a single schema entry
121
+ - `prettyJSON(val)` Custom JSON stringify implementation w/ better line-breaks
122
+ - `errAt(key, err[, isList])` Create pretty nested errors
@@ -0,0 +1,25 @@
1
+ import http from 'http';
2
+ import { StringMap } from 'raiutils';
3
+ /** Serve files from a directory
4
+ @param root Root dir to serve web files from
5
+ @param vDir Virtual override paths in the form `{webPath: pathOnDisk}` */
6
+ declare function handle(root: string, req: http.IncomingMessage, res: http.ServerResponse, vDir?: StringMap): Promise<void>;
7
+ /** Serve a single file from `path` to the client */
8
+ declare function serve(path: string, req: http.IncomingMessage, res: http.ServerResponse): Promise<void>;
9
+ /** Convenience method for sending an error page to the client */
10
+ declare function sendCode(res: http.ServerResponse, code: number, msg: string): void;
11
+ declare const _default: {
12
+ /** Debug mode. `>= 1` = Enabled */
13
+ debug: number;
14
+ /** Etag mode for client-side caching
15
+ - `0` or `false` = Disable
16
+ - `> 0` Max file size to calc etag hash
17
+ - `true` Fast mode; use modified date instead of hash */
18
+ etagMode: number | boolean;
19
+ handle: typeof handle;
20
+ serve: typeof serve;
21
+ sendCode: typeof sendCode;
22
+ types: StringMap;
23
+ };
24
+ export default _default;
25
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAMA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAqBrC;;yEAEyE;AACzE,iBAAe,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,EAAE,SAAS,iBAyCxG;AAED,oDAAoD;AACpD,iBAAe,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,IAAI,CAAC,cAAc,iBAGrF;AASD,iEAAiE;AACjE,iBAAS,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,QAEpE;;IA8BA,mCAAmC;WAEtB,MAAM;IACnB;;;4DAGwD;cAExC,MAAM,GAAG,OAAO;;;;;;AATjC,wBAWE"}
package/dist/router.js ADDED
@@ -0,0 +1 @@
1
+ import e from"path";import t from"fs/promises";import r from"crypto";import a from"chalk";let n=0;const i={".html":"text/html",".php":"text/html",".css":"text/css",".png":"image/png",".svg":"image/svg+xml",".js":"application/javascript",".pdf":"application/pdf",".mp4":"video/mp4",".ogg":"video/ogg",".webm":"video/webm"};let o=!0;async function s(s,p,f,u){let m;try{let c,d=await async function(r,a,n){if(-1!==a.indexOf(".."))throw"Bad path";let i=function(t,r,a){if(a){let t,n;for(t in a)if(n=t.startsWith("/")?t:"/"+t,r.startsWith(n))return e.join(a[t],r.slice(n.length))}return t+r}(r,a,n);i.endsWith("/")&&(i=i.slice(0,-1));try{return(await t.stat(i)).isDirectory()?e.join(i,"/index.html"):i}catch(t){if(!e.extname(i))return i+".html";throw t}}(s,new URL(p.url,"http://a").pathname,u),g={},h=200,w=e.extname(d),y=i[w],b=p.headers.range;y&&(g["content-type"]=y),m=await t.open(d);let x=await m.stat(),v=x.size;if(b){if(!b.startsWith("bytes=")||2!==(b=b.slice(6).split("-")).length||!b[0])return await l(m,v,b,f);let e=Number(b[0]),t=Number(b[1]);if(t||(t=v-1),e>=v||t>=v||e>=t)return await l(m,v,b,f);c=m.createReadStream({start:e,end:t}),g["accept-ranges"]="bytes",g["content-range"]=`bytes ${e}-${t}/${v}`,h=206}else if("number"==typeof o){if(v<=o){c=await m.readFile();let e=r.createHash("sha1");e.update(c),g.etag=e.digest("base64url")}}else o&&(g.etag=x.mtime.toISOString());if(g.etag&&g.etag===p.headers["if-none-match"])return f.writeHead(304,""),f.end(),m.close();c||(c=m.createReadStream()),f.writeHead(h,"",g),c instanceof Buffer?(f.write(c),f.end()):c.pipe(f),f.on("close",()=>m.close()),n&&function(e,t){console.log(a.dim("-- Served "+e+(t?" with type "+t:"")))}(d.startsWith(s)?d.slice(s.length):d,y)}catch(e){let t="ENOENT"===e.code;!n&&t||(t?d("-- Not found"):d("-- Read",e)),c(f,t?404:500,t?"Resource Not Found":e),m&&m.close()}}async function l(e,t,r,a){n&&d("-- Bad Range",r);let i={"content-range":"bytes */"+t};a.writeHead(416,"",i),a.end(),e.close()}function c(e,t,r){e.writeHead(t,""),e.write(`<pre style='font-size:16pt'>Error ${t}: ${r}</pre>`),e.end()}function d(e,t){console.error(a.red(e,t))}export default{get debug(){return n},set debug(e){n=e},get etagMode(){return o},set etagMode(e){o=e},handle:s,serve:async function(e,t,r){let a=t.url;return t.url="/",s(e,t,r).finally(()=>t.url=a)},sendCode:c,types:i}//# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["path","fs","crypto","C","debug","types","etagMode","async","handle","root","req","res","vDir","f","str","fn","dir","uri","indexOf","v","vs","startsWith","join","slice","length","parseUri","endsWith","stat","isDirectory","e","extname","resolve","URL","url","pathname","hdr","ext","ct","rng","headers","range","open","st","dl","size","split","rngErr","rs","Number","re","createReadStream","start","end","readFile","h","createHash","update","etag","digest","mtime","toISOString","writeHead","close","Buffer","write","pipe","on","name","console","log","dim","nf","code","err","sendCode","fl","msg","m","error","red","serve","u","finally"],"sources":["../src/router.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,113 @@
1
+ import { AnyMap } from 'raiutils';
2
+ /** An error generated by `errAt` */
3
+ declare class SubError extends Error {
4
+ }
5
+ /** Create pretty nested errors by calling this at multiple try/catch layers
6
+ @param isList Contain this segment in *[brackets]* */
7
+ declare function errAt(key: string | number, err: any, isList?: boolean): SubError;
8
+ type Type = 'str' | 'int' | 'float' | 'bool' | 'list' | 'dict' | 'obj';
9
+ export type Schema = {
10
+ [key: string]: Entry | Entry[];
11
+ };
12
+ export interface Options {
13
+ /** Ignore schema 'req' flag */
14
+ iReq?: boolean;
15
+ _r?: any;
16
+ _p?: any;
17
+ _k?: string | number;
18
+ }
19
+ export interface HookInfo {
20
+ /** Current key being tested. Null if at root */
21
+ k?: string | number;
22
+ /** Current value being tested. Null if key not found */
23
+ v?: any;
24
+ /** Root object given to checkSchema */
25
+ r: any;
26
+ }
27
+ /** Conditional value for Schema parameter
28
+ @param par Parent object/array we're inside
29
+ @param info Extra info for advanced hooks */
30
+ export type Hook<T> = (par: any, info: HookInfo) => T;
31
+ interface GenericEntry {
32
+ /** Required key; defaults to `true` */
33
+ req?: boolean | Hook<boolean>;
34
+ /** Conditionally reject this key */
35
+ rej?: boolean | Hook<boolean>;
36
+ }
37
+ interface SizedEntry {
38
+ /** Minimum length
39
+
40
+ For *list* type, it defaults to `1`, otherwise `0`
41
+ */
42
+ min?: number;
43
+ /** Maximum length */
44
+ max?: number;
45
+ /** Exact length */
46
+ len?: number;
47
+ }
48
+ interface NumEntry {
49
+ /** Minimum value */
50
+ min?: number;
51
+ /** Maximum value */
52
+ max?: number;
53
+ /** Exact value */
54
+ val?: number;
55
+ }
56
+ type ParentEntry = {
57
+ /** Child type */
58
+ c?: Type | Entry | Entry[];
59
+ } | {
60
+ /** Child schema format */
61
+ f?: Schema | Schema[];
62
+ };
63
+ export type Entry = GenericEntry & ((SizedEntry & ({
64
+ /** String */
65
+ t: 'str';
66
+ /** Regex format */
67
+ f?: string | RegExp;
68
+ } | (ParentEntry & {
69
+ /** Array */
70
+ t: 'list';
71
+ }))) | (ParentEntry & {
72
+ /** Dictionary Object */
73
+ t: 'dict';
74
+ /** Child key format */
75
+ k?: string | RegExp;
76
+ /** Allow empty dict */
77
+ z?: boolean;
78
+ }) | (NumEntry & ({
79
+ /** Integer */
80
+ t: 'int';
81
+ } | {
82
+ /** Float */
83
+ t: 'float';
84
+ })) | {
85
+ /** Boolean */
86
+ t: 'bool';
87
+ /** Exact value */
88
+ val?: boolean;
89
+ } | {
90
+ /** Specialized Object */
91
+ t: 'obj';
92
+ /** Class */
93
+ c: NewableFunction;
94
+ });
95
+ /** Check value against a schema entry
96
+ @param val Item to validate
97
+ @param ent Schema Entry(s) to use */
98
+ declare function checkType(val: any, ent: Entry | Entry[], opt?: Options): void;
99
+ /** Check data against a schema
100
+ @param data Object to validate
101
+ @param schema ChuSchema(s) to use */
102
+ declare function checkSchema(data: AnyMap, schema: Schema | Schema[], opt?: Options): void;
103
+ /** Custom JSON stringify implementation w/ better line-breaks */
104
+ declare function prettyJSON(val: any, _d?: number): string;
105
+ declare const _default: {
106
+ SubError: typeof SubError;
107
+ errAt: typeof errAt;
108
+ checkSchema: typeof checkSchema;
109
+ checkType: typeof checkType;
110
+ prettyJSON: typeof prettyJSON;
111
+ };
112
+ export default _default;
113
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
package/dist/schema.js ADDED
@@ -0,0 +1 @@
1
+ class t extends Error{}function r(r,e,n){let i=e instanceof t,o=e.message||e.toString();return r=(n?`[${r}]`:r)+(i?o.startsWith("[")?"":".":": "),i?e.message=r+o:e=new t(r+o,e instanceof Error?{cause:e}:null),e}function e(t){return"object"==typeof t&&null!==t}function n(t){return e(t)&&!Array.isArray(t)}function i(t){return` out-of-bounds (${null==t.min?"*":t.min}-${null==t.max?"*":t.max})`}function o(t){"string"==typeof t.c&&(t.c={t:t.c});let r=e(t.f)?2:e(t.c)?1:0;if(!r)throw"Schema lacks format or childType";if(2===r&&t.c)throw"Cannot require both format and childType";return 2===r}function f(t,r){if(Array.isArray(t)){let e=[];for(const n of t)try{return void r(n)}catch(t){e.push(t)}throw"(Failed all cases) "+e.map(t=>t.message||t).join(", ")}r(t)}function a(t,r,e,n){return"function"==typeof t?t(n._p,{k:r,v:e,r:n._r}):t}function l(t,e,c){let h,u,y,m,w,p;c||(c={}),"_r"in c||(c._r=t,p=1),"_p"in c||(c._p=t);try{f(e,e=>{try{if(a(e.rej,c._k,t,c))throw"Disallowed key";switch(e.t){case"str":if("string"!=typeof t)throw-1;if(h=t.length,h<e.min||h>e.max)throw"Str len "+h+i(e);if(null!=e.len&&h!==e.len)throw"Str len must be "+e.len;if("string"==typeof e.f&&(e.f=RegExp(`^(?:${e.f})$`)),e.f&&!e.f.test(t))throw`Str '${t}' does not match format ${e.f}`;break;case"int":case"float":if("number"!=typeof t||!("int"===e.t?Number.isSafeInteger(t):Number.isFinite(t)))throw-1;if(null!=e.val&&t!==e.val)throw"Num != "+e.val;if(t<e.min||t>e.max)throw"Num "+t+i(e);break;case"bool":if("boolean"!=typeof t)throw-1;if(null!=e.val&&t!==e.val)throw"Bool != "+e.val;break;case"list":if(!Array.isArray(t))throw-1;if(h=t.length,!h&&0!==e.min)throw"Empty list";if(null!=e.len&&h!==e.len)throw"Array size must be "+e.len;if(h<e.min||h>e.max)throw"Array size "+h+i(e);for(m=0,w=o(e),y={...c,_p:t};m<h;++m)try{y._k=m,w?s(t[m],e.f,y):l(t[m],e.c,y)}catch(t){throw r(m,t,!0)}break;case"dict":if(!n(t))throw-1;if(u=Object.keys(t),!u.length&&!e.z)throw"Empty dict";for(m of("string"==typeof e.k&&(e.k=RegExp(`^(?:${e.k})$`)),w=o(e),y={...c,_p:t},u))try{if(m.startsWith("$"))throw"Key cannot start with $";if(e.k&&!e.k.test(m))throw`Key '${m}' does not match format ${e.k}`;y._k=m,w?s(t[m],e.f,y):l(t[m],e.c,y)}catch(t){throw r(m,t,!0)}break;case"obj":if("function"!=typeof e.c)throw"Obj schema requires class";if(!(t instanceof e.c))throw"Obj must be of type "+e.c.name;break;default:throw`Unknown type ${e.t} in schema`}}catch(t){if(-1===t)throw"Must be of type "+e.t;throw t}})}finally{p&&(delete c._r,delete c._p)}}function s(t,i,o){if(!n(t))throw"Data must be dict";if(!e(i))throw"Schema must be dict|list[dict]";let s,c,h;o||(o={}),"_r"in o||(o._r=t,h=1),o._p=t;try{f(i,e=>{for(s in t)try{if(c=e[s],!c)throw"Not in schema";if(s.startsWith("$"))throw"Key cannot start with $";o._k=s,l(t[s],c,o)}catch(t){throw r(s,t)}if(!o.iReq)for(s in e)if(!(s in t)&&(c=e[s],Array.isArray(c)&&(c=c[0]),null==c.req||a(c.req,s,null,o)))throw s+": Required"})}finally{h&&delete o._r,delete o._p,delete o._k}}function c(t){for(let r of t)if("number"!=typeof r)return;return 1}export default{SubError:t,errAt:r,checkSchema:s,checkType:l,prettyJSON:function t(r,e=0){let n=typeof r;if("number"===n||"string"===n||"boolean"===n)return JSON.stringify(r);if(Array.isArray(r)){if(c(r))return JSON.stringify(r);let n="[",i=e+1,o=0,f=r.length;for(;o<f;++o)n+=(o?",\n":"\n")+"\t".repeat(i)+t(r[o],i);return n+"\n"+"\t".repeat(e)+"]"}if("object"===n){let n,i,o="{",f=!e,a=e+1;for(n in r)Array.isArray(r[n])&&!c(r[n])&&(f=1),o+=(f?i?",\n":"\n":i?", ":"")+"\t".repeat(f?a:0)+JSON.stringify(n)+":"+t(r[n],a),i=1,f=0;return e||(o+="\n"),o+"}"}throw"Unknown type "+n}}//# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["SubError","Error","errAt","key","err","isList","s","es","message","toString","startsWith","cause","isDictOrArr","d","isDict","Array","isArray","oobStr","min","max","dictFmt","c","t","dt","f","tryAny","a","fn","el","e","push","map","join","runHook","k","v","o","_p","r","_r","checkType","val","ent","opt","l","n","sr","rej","_k","length","len","RegExp","test","Number","isSafeInteger","isFinite","checkSchema","Object","keys","z","name","data","schema","sch","iReq","req","isNumArr","prettyJSON","_d","JSON","stringify","d1","i","repeat","ln"],"sources":["../src/schema.ts"],"mappings":"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","ignoreList":[]}