open-index/open-npm huggingface dataset:
npm package: @laoban/admin
Description: Configures and manages laoban projects
Latest version: 1.0.30
Deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

# laoban-admin

The tool laoban is used to manage projects in mono-repos.

In order to make the experience of 'setting up the project' easier, laoban-admin has been created. In most projects
this will only be used once, to set up the project.

Laoban is used constantly: some users might use it a hundred times a day. It is optimised for this type of usage
pattern. Laoban-admin is not: it is only used very rarely. Thus it is expected that the users are not very familiar with
it.

## Documentation

The documentation for laoban-admin is [here](https://laoban-github.github.io/laoban-admin/DOCUMENTATION.html)

## Installation

`npm i -g laoban-admin@latest` installs the latest version of laoban-admin and the latest version of laoban.
npm package: @laoban/debug
Description: A general debug utility that allows debugs to be turned on and off easily and thus left in the code
Latest version: 1.4.58

# Debugging

I often find that I use 'printline debugging'. This is where we add 'console.log' lines to 
code in order to find defects.

In general it's a bad idea to leave these in production for a number of reasons: 
* They pollute console.log with noise making it hard to find real issues
* They can take time (but actually usually don't)

However when logging we often have different levels of logging. In java for example
we often have 'logging levels'. 'Error', 'Warn', 'Info' and debug, and then we have tools to
examine the logging files. 

While I don't feel the need for levels here (yet), I want the ability to 'turn on and off' 
debugging in parts of the code.

For example I might have a section of the code called 'generations' and I might want to have
logging messages that only appear when I have a problem in the 'generations' code and
want to debug it. 

# Setting up to use
I typically have an object I used for dependency inject. Say it's called context. 
I have a comma separated list of names called debugString. This
is the list of 'sections' that I want debugging enabled for

```
let contextWithDebug=addDebug(debugString, x => console.log('#', ...x))(context)
```
This context was previously some object, and now it is an object with `{debug: <the debug function>}` added

# Using
``` 
    let s = contextWithDebug.debug('generations');
    ...
    ...
    s.message(() => ['some', 'list', 'that', 'might', 'get', 'logged']
    ...
    ...
    ...s.k(() => 'about to fullfill a promise', () => <something that returns a promise>>)
```
* The first line created a javascript object that will only print to the output when the debugString contains 'generations'.
* s.message sends a message to console.log if 'generations' is in the debugString
* s.k() returns the promise returned by `<something that returns a promise>`. It logs errors in that promise as well
npm package: @laoban/generations
Description: A library that typologically sorts data into generations
Latest version: 1.4.58

# A library to do topological sorting

Many things have have 'generations'. This is where 'a series of tasks have to be done before others'

For example when you have a series of software libraries that you produce,
and some use other libraries, then when you compile/pubish them (and you want to do this in parallel),
you can sort them into generations:
* gen0: those that don't depend on any others
* gen1: those that only depend on gen0
* gen2: those that only depend on gen1 or gen0
* ...

# Using the library

## GenerationFns
You need to create an instance of 
```
interface GenerationFns<G> {
    name: (g: G) => string,
    children: (g: G) => string[],
    errorMessage: (view: GenerationView) => Error
}
```
All the sorting is done by names (for speed as much as anything) so each G has to have a unique name

## Sorting

A reasonably common use case is when we have a list of Gs. This isn't the full list. For
example we might have 10,000 items in a todo list: some depedendant on each other. We are
only going to topologically sort some of these, so we ignore things that aren't in the list we are sorting

There are two methods used:

```
 function calcGenerationsPromise<G>(genFns: GenerationFns<G>): (gs: G[]) => Promise<G[][]> 
 function calcGenerations<G>(genFns: GenerationFns<G>): (gs: G[]) => GenerationsResult<G> {
```
The methods with a promise can be convenient when working with heavy async code, and captures the idea that the
sort can fail (if there is a loop)
npm package: @laoban/validation
Description: A library for validating json
Latest version: 1.4.58

# This is library for single field validation.

This is a common requirement in my applications: objects are parsed from JSON and I want
to make sure that they meet a contract

I want a list of all the error messages, and I would like it if the code reads declarative.

The `return type` of the validation is a string[] or a Promise<string[]>

## Approach
We wrap the object under test with a validate object then we can do things like the following. The validate
object accumulates issues internaly and you can call `.issues` to see those issues
```
function validateProjectDetails(v: Validate<ProjectDetails>) {
    return v.isString("name").//
        isString("description").//
        isString("template").//
        isObject("details", validateDetails)
}

function validateDetails(v: Validate<Details>) {
    return v.isBoolean("publish", 'Should the project be published').//
        isArrayofObjects('links', v => v).//
        optObject("extraDeps", v => v, 'These are added to package.json dependencies').//
        optObject("extraDevDeps", v => v, 'These are added to package.json devDependencies').//
        optObject("extraBins", v => v, 'These are added to package.json bin')
}
```
## Extra goodness
When working with CLIs I often want to validate that directories and files exist.


```
function validateTemplateDirectory(context: string, c: Config, templateDir: string): Promise<string[]> {
    let dir = path.join(c.templateDir, templateDir);
    return Validate.validateDirectoryExists(context, dir).then(dirErrors => dirErrors.length === 0 ?
        Validate.validateFile(`package.json in template directory ${templateDir}`, path.join(dir, 'package.json'), validatePackageJson) :
        dirErrors)
}```