Comparing version 5.3.0 to 6.0.0
(function() { | ||
'use strict'; | ||
var CND, def, def_oneoff, hide, misfit, rpr; | ||
var CND, def, def_oneoff, hide, misfit, no_such_value, props, rpr; | ||
@@ -10,2 +10,6 @@ //########################################################################################################### | ||
props = this; | ||
no_such_value = Symbol('no_such_value'); | ||
//----------------------------------------------------------------------------------------------------------- | ||
@@ -102,3 +106,3 @@ this._misfit = misfit = Symbol('misfit'); | ||
constructor(cfg) { | ||
var R, has_target; | ||
var R; | ||
cfg = { | ||
@@ -112,45 +116,13 @@ target: this, | ||
get: (target, key) => { | ||
var value; | ||
if (key === Symbol.toStringTag) { | ||
return void 0; | ||
} | ||
if ((R = target[key]) === void 0) { | ||
if ((value = props.get(target, key, no_such_value)) === no_such_value) { | ||
throw new Error(`^guy.props.Strict_owner@1^ ${this.constructor.name} instance does not have property ${rpr(key)}`); | ||
} | ||
return R; | ||
return value; | ||
} | ||
}); | ||
// set: ( target, key, value ) => | ||
// target[key] = value | ||
// return true | ||
//....................................................................................................... | ||
has_target = (key) => { | ||
if (key === Symbol.toStringTag) { | ||
return true; | ||
} | ||
return cfg.target[key] !== void 0; | ||
}; | ||
//....................................................................................................... | ||
if (cfg.target.has == null) { | ||
hide(cfg.target, 'has', new Proxy(has_target, { | ||
get: (_, key) => { | ||
return has_target(key); | ||
} | ||
})); | ||
} | ||
//....................................................................................................... | ||
if (cfg.target.get == null) { | ||
hide(cfg.target, 'get', (key, fallback = misfit) => { | ||
var error; | ||
try { | ||
return cfg.target[key]; | ||
} catch (error1) { | ||
error = error1; | ||
if (fallback !== misfit) { | ||
return fallback; | ||
} | ||
} | ||
throw error; | ||
}); | ||
} | ||
//....................................................................................................... | ||
return R; | ||
@@ -161,4 +133,27 @@ } | ||
//----------------------------------------------------------------------------------------------------------- | ||
this.has = (target, key) => { | ||
var error; | ||
try { | ||
/* safe version of `Reflect.has()` that never throws an error */ | ||
return Reflect.has(target, key); | ||
} catch (error1) { | ||
error = error1; | ||
return false; | ||
} | ||
}; | ||
//----------------------------------------------------------------------------------------------------------- | ||
this.get = (target, key, fallback = misfit) => { | ||
if (this.has(target, key)) { | ||
return target[key]; | ||
} | ||
if (fallback !== misfit) { | ||
return fallback; | ||
} | ||
throw new Error(`^guy.props.get@1^ no such property ${rpr(key)}`); | ||
}; | ||
}).call(this); | ||
//# sourceMappingURL=props.js.map |
{ | ||
"name": "guy", | ||
"version": "5.3.0", | ||
"version": "6.0.0", | ||
"description": "npm dependencies checker", | ||
@@ -5,0 +5,0 @@ "main": "lib/main.js", |
127
README.md
@@ -13,14 +13,14 @@ | ||
- [Modules](#modules) | ||
- [`guy.props`: Common Operations on Object Properties](#guyprops-common-operations-on-object-properties) | ||
- [`GUY.props`: Common Operations on Object Properties](#guyprops-common-operations-on-object-properties) | ||
- [Class for Strict Ownership](#class-for-strict-ownership) | ||
- [`guy.async`: Asynchronous Helpers](#guyasync-asynchronous-helpers) | ||
- [`guy.nowait`: De-Asyncify JS Async Functions](#guynowait-de-asyncify-js-async-functions) | ||
- [`guy.process`: Process-Related Utilities](#guyprocess-process-related-utilities) | ||
- [`guy.cfg`: Instance Configuration Helper](#guycfg-instance-configuration-helper) | ||
- [`GUY.async`: Asynchronous Helpers](#guyasync-asynchronous-helpers) | ||
- [`GUY.nowait`: De-Asyncify JS Async Functions](#guynowait-de-asyncify-js-async-functions) | ||
- [`GUY.process`: Process-Related Utilities](#guyprocess-process-related-utilities) | ||
- [`GUY.cfg`: Instance Configuration Helper](#guycfg-instance-configuration-helper) | ||
- [Usage Examples](#usage-examples) | ||
- [Most Minimal (Bordering Useless)](#most-minimal-bordering-useless) | ||
- [More Typical](#more-typical) | ||
- [`guy.lft`: Freezing Objects](#guylft-freezing-objects) | ||
- [`guy.fs`: File-Related Stuff](#guyfs-file-related-stuff) | ||
- [`guy.src`: JS Source Code Analysis](#guysrc-js-source-code-analysis) | ||
- [`GUY.lft`: Freezing Objects](#guylft-freezing-objects) | ||
- [`GUY.fs`: File-Related Stuff](#guyfs-file-related-stuff) | ||
- [`GUY.src`: JS Source Code Analysis](#guysrc-js-source-code-analysis) | ||
- [To Do](#to-do) | ||
@@ -36,4 +36,4 @@ - [Is Done](#is-done) | ||
* Only Peer-Dependencies (except `cnd`, `intertype`) | ||
* Sub-libraries accessible as `guy.${library_name}` | ||
* Most sub-libraries implemented using `guy.props.def_oneoff()`, therefore dependencies (which are declared | ||
* Sub-libraries accessible as `GUY.${library_name}` | ||
* Most sub-libraries implemented using `GUY.props.def_oneoff()`, therefore dependencies (which are declared | ||
peer dependencies) will only be `require()`d when needed. | ||
@@ -43,12 +43,12 @@ | ||
### `guy.props`: Common Operations on Object Properties | ||
### `GUY.props`: Common Operations on Object Properties | ||
* **`guy.props.def: ( target, name, cfg ) ->`** is just another name for `Object.defineProperty()`. | ||
* **`GUY.props.def: ( target, name, cfg ) ->`** is just another name for `Object.defineProperty()`. | ||
* **`guy.props.hide: ( object, name, value ) ->`** is a shortcut to define a non-enumerable property as in | ||
* **`GUY.props.hide: ( object, name, value ) ->`** is a shortcut to define a non-enumerable property as in | ||
`Object.defineProperty object, name, { enumerable: false, value, }`. | ||
* **`guy.props.def_oneoff: ()`** | ||
* **`GUY.props.def_oneoff: ()`** | ||
* **`guy.props.pick_with_fallback = ( d, fallback, keys... ) ->`**—Given an object `d`, a `fallback` value and | ||
* **`GUY.props.pick_with_fallback = ( d, fallback, keys... ) ->`**—Given an object `d`, a `fallback` value and | ||
some `keys`, return an object that whose `keys` are the ones passed in, and whose values are either the | ||
@@ -58,8 +58,33 @@ same as found in `d`, or `fallback` in case a key is missing in `d` or set to `undefined`. If `d[ key ]` | ||
* **`guy.props.nullify_undefined = ( d ) ->`**—Given an object `d`, return a copy of it where all `undefined` | ||
* **`GUY.props.nullify_undefined = ( d ) ->`**—Given an object `d`, return a copy of it where all `undefined` | ||
values are replaced with `null`. In case `d` is `null` or `undefined`, an empty object will be returned. | ||
* **`guy.props.omit_nullish = ( d ) ->`**—Given an object `d`, return a copy of it where all `undefined` and | ||
* **`GUY.props.omit_nullish = ( d ) ->`**—Given an object `d`, return a copy of it where all `undefined` and | ||
`null` values are not set. In case `d` is `null` or `undefined`, an empty object will be returned. | ||
* **`GUY.props.has = ( x, key ) ->`**—Given any value `x`, return whether the value has a given property | ||
(`key`). This is a safe version of `Reflect.has()` that never throws an error. Like direct property access | ||
(using `x.key` or `x[ 'key' ]`) but unlike `Object.getOwnPropertyDescriptor()` &c, `GUY.props.has()` looks | ||
into the prototype chain; like `Object.getOwnPropertyDescriptor()`, it does not trigger property getters. | ||
* **`GUY.props.get = ( x, key, fallback ) ->`**—Given any value `x`, return the value of property named in | ||
`key`. If that property is missing, throw an error, but when `fallback` has been given, return `fallback` | ||
instead. Using `GUY.props.get x, 'foo'` is like saying `x.foo` or `x[ 'foo' ]` except that it doesn't | ||
tolerate missing property keys; using it with a fallback as in `GUY.props.get x, 'foo', undefined` is like | ||
saying `x.foo` or `x[ 'foo' ]` except that it also works for `null` and `undefined`. | ||
Using `GUY.props.has()` and `GUY.props.get()` it is always possible to circumvent errors being thrown and | ||
instead do value-based error handling (and raise one own's errors where seen fit). One pattern to do so is | ||
to define a private Symbol instead of relying on `undefined` that could have been caused by all kinds of | ||
circumstances: | ||
```coffee | ||
no_such_value = Symbol 'no_such_value' | ||
if ( value = GUY.props.get x, key, no_such_value ) is no_such_value | ||
# deal with missing value here | ||
else | ||
# deal with present value here | ||
``` | ||
#### Class for Strict Ownership | ||
@@ -72,17 +97,4 @@ | ||
When you extend your class with `GUY.props.Strict_owner`, instance of your class will now throw an error | ||
when a non-existing property is accessed. In addition (and if you don't override those properties), your | ||
instances will have two special members `x.has()` and `x.get()` to test for membership and to retrieve | ||
values in a 'safe' way: | ||
when a non-existing property is accessed. | ||
* `x.has key` will return `true` if `x` has the attribute identified by `key` and `false` otherwise. In | ||
addition, `has()` is a proxy that treats all property accesses like it treats function calls, so one can | ||
say `x.has.foobar` and `x.has[ 'foobar' ]` instead of `x.has 'foobar'`. | ||
* `x.get key, fallback` will return `x[ key ]` when `key` names an existing property; otherwise, it will | ||
return `fallback`. The `fallback` argument is optional; if it is omitted, `x.get key` works exactly like | ||
`x[ key ]` (i.e. it will throw an error when `key` is not found on `x`). | ||
**Note** Membership is tested by comparing values against `undefined`, so setting a property explicitly to | ||
`undefined` will work much the same as `delete`. | ||
**Note** Most often one will want to define a class that extends `Strict_owner`, however, it is also | ||
@@ -96,4 +108,10 @@ possible to pass in an arbitrary object—including a function—as property `target` to the constructor, e.g. | ||
### `guy.async`: Asynchronous Helpers | ||
**Note** As of Guy v6, special methods `get()` and `set()` have been removed from `Strict_owner`. They have | ||
been replaced with a much cleaner and more correct implementation as `GUY.props.get()` and | ||
`GUY.props.has()`. These methods are more versatile, too, since they can be used with *any* JS value | ||
(including the always-problematic `null` and `undefined`). | ||
### `GUY.async`: Asynchronous Helpers | ||
These 'five letter' methods are convenience methods in the sense that they are very thin shims over the | ||
@@ -118,3 +136,3 @@ somewhat less convenient JavaScript methods. For many people, the most strightforward way to understand what | ||
### `guy.nowait`: De-Asyncify JS Async Functions | ||
### `GUY.nowait`: De-Asyncify JS Async Functions | ||
@@ -127,7 +145,7 @@ **Note** Due to ongoing issues when compiling the `deasync` module that this functionality | ||
* **`guy.nowait.for_callbackable: ( fn_with_callback ) ->`**—given an asynchronous function `afc` that | ||
* **`GUY.nowait.for_callbackable: ( fn_with_callback ) ->`**—given an asynchronous function `afc` that | ||
accepts a NodeJS-style callback (as in `afc v1, v2, ..., ( error, result ) -> ...`), returns a synchronous | ||
function `sf` that can be used without a callback (as in `result = sf v1, v2, ...`). | ||
* **`guy.nowait.for_awaitable: ( fn_with_promise ) ->`**—given an asynchronous function `afp` that can be | ||
* **`GUY.nowait.for_awaitable: ( fn_with_promise ) ->`**—given an asynchronous function `afp` that can be | ||
used with `await` (as in `result = await afp v1, v2, ...`) returns a synchronous function `f` that can be | ||
@@ -138,7 +156,7 @@ used without `await` (as in `result = sf v1, v2, ...`). | ||
### `guy.process`: Process-Related Utilities | ||
### `GUY.process`: Process-Related Utilities | ||
**Peer Dependencies**: [`sindresorhus/exit-hook`](https://github.com/sindresorhus/exit-hook) | ||
* **`guy.process.on_exit: ( fn ) => ...`**—call `fn()` before process exits. Convenience link for | ||
* **`GUY.process.on_exit: ( fn ) => ...`**—call `fn()` before process exits. Convenience link for | ||
[`sindresorhus/exit-hook`](https://github.com/sindresorhus/exit-hook), which see for details. **Note** | ||
@@ -148,5 +166,5 @@ When installing this peer dependency, make sure to do so with the last CommonJS version added, as in `npm | ||
### `guy.cfg`: Instance Configuration Helper | ||
### `GUY.cfg`: Instance Configuration Helper | ||
* **`guy.cfg.configure_with_types: ( self, cfg = null, types = null ) => ...`**—Given a class instance | ||
* **`GUY.cfg.configure_with_types: ( self, cfg = null, types = null ) => ...`**—Given a class instance | ||
`self`, an optional `cfg` object and an optional | ||
@@ -181,3 +199,3 @@ [Intertype](https://github.com/loveencounterflow/intertype)-like `types` instance, | ||
It is allowable to call `configure_with_types()` with an instance of whatever class. | ||
`guy.cfg.configure_with_types()` will look for properties `clasz.C.defaults`, `clasz.declare_types()` (and a | ||
`GUY.cfg.configure_with_types()` will look for properties `clasz.C.defaults`, `clasz.declare_types()` (and a | ||
`types` object as third argument to `configure_with_types()`) and provide defaults where missing: | ||
@@ -188,3 +206,3 @@ | ||
constructor: ( cfg ) -> | ||
guy.cfg.configure_with_types @, cfg | ||
GUY.cfg.configure_with_types @, cfg | ||
#......................................................................................................... | ||
@@ -207,3 +225,3 @@ ex1 = new Ex() | ||
@C: guy.lft.freeze | ||
@C: GUY.lft.freeze | ||
foo: 'foo-constant' | ||
@@ -225,3 +243,3 @@ bar: 'bar-constant' | ||
constructor: ( cfg ) -> | ||
guy.cfg.configure_with_types @, cfg | ||
GUY.cfg.configure_with_types @, cfg | ||
return undefined | ||
@@ -238,5 +256,5 @@ | ||
### `guy.lft`: Freezing Objects | ||
### `GUY.lft`: Freezing Objects | ||
`guy.left.freeze()` and `guy.lft.lets()` provide access to the epynomous methods in | ||
`GUY.left.freeze()` and `GUY.lft.lets()` provide access to the epynomous methods in | ||
[`letsfreezethat`](https://github.com/loveencounterflow/letsfreezethat). `freeze()` is basically | ||
@@ -248,5 +266,5 @@ `Object.freeze()` for nested objects, while `d = lets d, ( d ) -> mutate d` provides a handy way to mutate | ||
### `guy.fs`: File-Related Stuff | ||
### `GUY.fs`: File-Related Stuff | ||
* **`guy.fs.walk_lines = ( path, cfg ) ->`**—Given a `path`, return a *synchronous* iterator over file | ||
* **`GUY.fs.walk_lines = ( path, cfg ) ->`**—Given a `path`, return a *synchronous* iterator over file | ||
lines. This is the most hassle-free approach to synchronously obtain lines of text files in NodeJS that | ||
@@ -256,3 +274,3 @@ I'm aware of, yet. The optional `cfg` argument may be an object with a single property `decode`; when set | ||
* **`guy.fs.walk_circular_lines = ( path, cfg ) ->`**—Given a `path`, return an iterator over the lines in | ||
* **`GUY.fs.walk_circular_lines = ( path, cfg ) ->`**—Given a `path`, return an iterator over the lines in | ||
the referenced file; optionally, when the iterator is exhausted (all lines have been read), restart from | ||
@@ -265,10 +283,10 @@ the beginning. `cfg` may be an object with the keys: | ||
* The iteration will finish as soon as the one or the other limit has been reached. | ||
* By default, `guy.fs.walk_circular_lines()` will act like `guy.fs.walk_lines`. | ||
* By default, `GUY.fs.walk_circular_lines()` will act like `GUY.fs.walk_lines`. | ||
* The iterator will not yield anything when either `loop_count` or `line_count` are set to `0`. | ||
* **`guy.fs.get_content_hash = ( path, cfg ) ->`**—Given a `path`, return the | ||
* **`GUY.fs.get_content_hash = ( path, cfg ) ->`**—Given a `path`, return the | ||
hexadecimal `sha1` hash digest for its contents. On Linux, this uses `sha1sum`, and `shasum` on all | ||
other systems. | ||
### `guy.src`: JS Source Code Analysis | ||
### `GUY.src`: JS Source Code Analysis | ||
@@ -371,3 +389,3 @@ > This submodule needs peer-dependencies, install them with | ||
warning.</ins> | ||
* **[–]** `guy.fs.walk_lines()`: allow to configure; make `trimEnd()` the default | ||
* **[–]** `GUY.fs.walk_lines()`: allow to configure; make `trimEnd()` the default | ||
@@ -410,2 +428,7 @@ * implement easy way to collect, rediect `process.stdout`, `process.stderr`: | ||
Currently it is the empty string which is not ideal | ||
* **[–]** use | ||
[`Reflect.has()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect) | ||
to check for property availability for `Strict_owner`s instead of using instance method; provide as | ||
`GUY.props.has()` | ||
* **[–]** likewise, use `GUY.props.get: ( target, name, fallback = misfit ) ->` instead of instance method | ||
@@ -412,0 +435,0 @@ ## Is Done |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
108040
426
763