Code Monkey home page Code Monkey logo

components-generator.js's Introduction

Components-Generator.js

Build status Coverage Status npm version DOI

This is a tool to automatically generate .jsonld component files from TypeScript classes for the Components.js dependency injection framework.

Before you use this tool, it is recommended to first read the Components.js documentation.

Getting started

1. Install as a dev dependency

npm install -D componentsjs-generator

or

yarn add -D componentsjs-generator

2. Declare components in package.json

If you are already using Components.js, you already have this.

Add the following entry to package.json:

{
  ...
  "lsd:module": true,
  ...
}

On each line, make sure to replace my-package with your package name.

3. (optional) Add generate script

Call componentsjs-generator as a npm script by adding a scripts entry to your package.json:

{
  ...,
  "scripts": {
    ...
    "build": "npm run build:ts && npm run build:components",
    "build:ts": "tsc",
    "build:components": "componentsjs-generator",
    "prepare": "npm run build",
    ...
  }
}

This is only a recommended way of calling componentsjs-generator, you are free to call it in a different way that better suits your pipeline.

4. (optional) Ignore generated components files

Since we automatically generate the components files, we do not have to check them into version control systems like git. So we can add the following line to .gitignore:

components

If you do this, make sure that the components folder is published to npm by adding the following to your package.json:

{
  ...
  "files": [
    ....
    "components/**/*.jsonld",
    "config/**/*.json",
    ....
  ],
  ....
}

Usage

When invoking componentsjs-generator, this tool will automatically generate .jsonld components files for all TypeScript files that are exported by the current package.

For monorepos, multiple package paths may be provided.

Generates component file for a package
Usage:
  componentsjs-generator
  Arguments:
       path/to/package         The directories of the packages to look in, defaults to working directory
  Options:
       -p path/to/package      The directory of the package to look in, defaults to working directory
       -s lib                  Relative path to directory containing source files, defaults to 'lib'
       -c components           Relative path to directory that will contain components files, defaults to 'components'
       -e jsonld               Extension for components files (without .), defaults to 'jsonld'
       -i ignore-classes.json  Relative path to an optional file with class names to ignore
       -r prefix               Optional custom JSON-LD module prefix
       --lenient               If unsupported language features must produce a warning instead of an error
       --debugState            If a 'componentsjs-generator-debug-state.json' file should be created with debug information
       --help                  Show information about this command

Note: This generator will read .d.ts files, so it is important that you invoke the TypeScript compiler (tsc) before using this tool.

Configuration files

While options passed to the CLI tool will always take precedence, it is possible to add a .componentsjs-generator-config.json file to your project to define your configuration.

The following shows an example of the possible options:

{
  "source": "lib",
  "destination": "components",
  "extension": "jsonld",
  "ignorePackagePaths": ["path/to/package-ignored1", "path/to/package-ignored2"],
  "ignoreComponents": ["Class1", "Class2"],
  "logLevel": "info",
  "modulePrefix": "myprefix",
  "debugState": "true",
  "hardErrorUnsupported": false
}

When invoking componentsjs-generator, the tool will look for .componentsjs-generator-config.json in the current working directory. If it can not find one, it will recursively go look into the parent directories until it either finds one or is at the root.

Ignoring classes

If you don't want components to be generated for certain classes, then you can either add it to the ignoreComponents array of the .componentsjs-generator-config.json file (as explained above), or you can pass a JSON file to the -i option containing an array of class names to skip.

For example, invoking componentsjs-generator -i ignore-classes.json will skip BadClass if the contents of ignore-classes.json are:

[
  "BadClass"
]

If you are looking for a way to ignore parameters, see the @ignored argument tag below.

How it works

For each exported TypeScript class, its constructor will be checked, and component parameters will be generated based on the TypeScript type annotations.

Example

TypeScript class:

/**
 * This is a great class!
 */
export class MyClass extends OtherClass {
  /**
   * @param paramA - My parameter
   */
  constructor(paramA: boolean, paramB: number, paramC: string[]) {

  }
}

Component file:

{
  "@context": [
    "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^1.0.0/components/context.jsonld"
  ],
  "@id": "npmd:my-package",
  "components": [
    {
      "@id": "ex:MyFile#MyClass",
      "@type": "Class",
      "requireElement": "MyClass",
      "extends": "ex:OtherFile#OtherClass",
      "comment": "This is a great class!",
      "parameters": [
        {
          "@id": "ex:MyFile#MyClass_paramA",
          "range": "xsd:boolean",
          "comment": "My parameter"
        },
        {
          "@id": "ex:MyFile#MyClass_paramB",
          "range": "xsd:integer"
        },
        {
          "@id": "ex:MyFile#MyClass_paramC",
          "range": {
            "@type": "ParameterRangeArray",
            "parameterRangeValue": "xsd:integer"
          }
        }
      ],
      "constructorArguments": [
        { "@id": "ex:MyFile#MyClass_paramA" },
        { "@id": "ex:MyFile#MyClass_paramB" },
        { "@id": "ex:MyFile#MyClass_paramC" }
      ]
    }
  ]
}

Arguments

Each argument in the constructor of the class must be one of the following:

  • A primitive type such as boolean, number, string, which will be mapped to an XSD type
  • Another class, which will be mapped to the component @id.
  • A record or interface containing key-value pairs where each value matches one of the possible options. Nesting is allowed.
  • Reference to a generic type that is defined on the class.
  • An array, keyof, tuple, union, or intersection over any of the allowed types.

Here is an example that showcases all of these options:

import {Logger} from "@comunica/core";
export class SampleActor {
   constructor(
     args: HashArg,
     number: number,
     component: Logger,
     array: HashArg[],
     complexComposition: (SomeClass & OtherClass) | string,
     complexTuple: [ number, SomeClass, ...string[] ],
     optional?: number,
   ) {}
}
export interface HashArg {
   args: NestedHashArg;
   array: NestedHashArg[];
}
export interface NestedHashArg extends ExtendsTest {
   test: boolean;
   component: Logger;
}
export interface ExtendsTest {
   string: string;
}

Argument tags

Using comment tags, arguments can be customized.

Tags

Tag Action
@ignored This field will be ignored.
@default {value} The default attribute of the parameter will be set to value. See section below for acceptable values.
@defaultNested {value} path_to_args When the given parameter accepts a nested object (child links delimited by _), the default attribute of this nested field will be set to value. See section below for acceptable values.
@range {type} The range attribute of the parameter will be set to type. You can only use values that fit the type of field. Options: json, boolean, int, integer, number, byte, long, float, decimal, double, string. For example, if your field has the type number, you could explicitly mark it as a float by using @range {float}. See the documentation.
Default values

Default values accept a microsyntax, in which several types of values may be provided:

  • Literal values: @default {abc}
  • IRI values: @default {<http://example.org/abc>}
  • Blank-node-based instantiation: @default {a <http://example.org/MyType>}
  • IRI-based instantiation: @default {<http://example.org/myInstance> a <http://example.org/MyType>}

Examples

Tagging constructor fields:

TypeScript class:

export class MyActor {
    /**
     * @param myByte - This is an array of bytes @range {byte}
     * @param ignoredArg - @ignored
     */
    constructor(myByte: number[], ignoredArg: string) {

    }
}

Component file:

{
  "components": [
    {
      "parameters": [
        {
          "@id": "my-actor#TestClass#myByte",
          "range": {
            "@type": "ParameterRangeArray",
            "parameterRangeValue": "xsd:byte"
          },
          "comment": "This is an array of bytes"
        }
      ],
      "constructorArguments": [
        {
          "@id": "my-actor#TestClass#myByte"
        }
      ]
    }
  ]
}

Tagging constructor fields as raw JSON:

TypeScript class:

export class MyActor {
    /**
     * @param myValue - Values will be passed as parsed JSON @range {json}
     * @param ignoredArg - @ignored
     */
    constructor(myValue: any, ignoredArg: string) {

    }
}

Component file:

{
  "components": [
    {
      "parameters": [
        {
          "@id": "my-actor#TestClass#myValue",
          "range": "rdf:JSON",
          "comment": "Values will be passed as parsed JSON"
        }
      ],
      "constructorArguments": [
        {
          "@id": "my-actor#TestClass#myValue"
        }
      ]
    }
  ]
}

When instantiating TestClass as follows, its JSON value will be passed directly into the constructor:

{
  "@id": "ex:myInstance",
  "@type": "TestClass",
  "myValue": {
    "someKey": {
      "someOtherKey1": 1,
      "someOtherKey2": "abc"
    }
  }
}

Tagging interface fields:

TypeScript class:

export class MyActor {
  constructor(args: IActorBindingArgs) {
    super(args)
  }
}

export interface IActorBindingArgs {
  /**
   * This field is very important
   * @range {float}
   * @default {5.0}
   */
   floatField: number;
}

Component file:

{
  "components": [
    {
      "parameters": [
        {
          "@id": "my-actor#floatField",
          "range": "xsd:float",
          "default": "5.0",
          "comment": "This field is very important"
        }
      ],
      "constructorArguments": [
        {
          "fields": [
            {
              "keyRaw": "floatField",
              "value": "my-actor#floatField"
            }
          ]
        }
      ]
    }
  ]
}

License

Components.js is written by Ruben Taelman.

This code is copyrighted by Ghent University – imec and released under the MIT license.

components-generator.js's People

Contributors

adlerfaulkner avatar joachimvh avatar maximvdw avatar pheyvaer avatar renovate-bot avatar renovate[bot] avatar robindebaets avatar rubensworks avatar termontwouter avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

components-generator.js's Issues

Import statement with and without extension

Apparently it is possible to specify a filename with or without an extension when importing local files.
For example, require("../lib/Core") and require("../lib/Core.js") do the same thing.
We need to investigate how this works out in our code and whether this applies to require statements as well.

Default key/value pairs in constructors should be optional

An example is the ExtensionBasedMapper which has default values for acl and meta.

The relevant part of generated JSON-LD:

        {
          "@id": "scs:dist/storage/mapping/ExtensionBasedMapper#ExtensionBasedMapper_overrideTypes_acl",
          "range": "xsd:string",
          "unique": true,
          "required": true
        },

required should not be true here.

It's easy to work around this by adding the values in the config so not an urgent issue.

Allow default imports and exports

Imagine this scenario:
File1.ts

export default class Actor1 {
}

and
File2.ts

import Actor1Alt from "./Actor1";
export default class Actor0 extends Actor1Alt {
}

The current version of the tool will not be able to understand this kind of default-import notation and thus can't find the reference to Actor1Alt in File2.ts.
Furthermore, the part of the tool that reads the index.ts will also not be able to match the Actor1 component to its file.

We should allow default imports and exports to be used (if they are supported by Components.js).
This is relatively low-priority. No Comunica components use this way of exporting.

After implementing this, additional test cases should be added to the local test-package1.

Implement entriesCollection support

Currently, the following type of configuration is not supported.
This is something we want to be able to parse/generate.
This is relatively low-priority because not a lot of packages use this functionality, but we should implement it nonetheless.

An example:

contextKeyShortcuts: {[shortcut: string]: string};

becomes

{  
   "keyRaw":"contextKeyShortcuts",
   "value":{  
      "fields":[  
         {  
            "collectEntries":"cais:contextKeyShortcut",
            "key":"cais:contextKeyShortcut/shortcut",
            "value":"cais:contextKeyShortcut/expanded"
         }
      ]
   }

and

{
  "@id": "cais:contextKeyShortcut",
  "comment": "A context key shortcut entry",
  "range": {
    "@type": "cais:contextKeyShortcut/Entry",
    "parameters": [
      {
        "@id": "cais:contextKeyShortcut/shortcut",
        "comment": "A shortcut string",
        "required": true,
        "unique": true
      },
      {
        "@id": "cais:contextKeyShortcut/expanded",
        "comment": "The full expanded key",
        "required": true,
        "unique": true
      }
    ]
  }
}

Implementing this will require some restructuring: fields are currenty parsed in getFields, but they only receive their unique @id in getParametersAndArguments in AstUtils.

Does not work without a connection

When not connected to the Internet, I get:

Failed to load remote context https://linkedsoftwaredependencies.org/bundles/npm/componentsjs/^3.0.0/components/context.jsonld: request to https://linkedsoftwaredependencies.org/bundles/npm/componentsjs/%5E3.0.0/components/context.jsonld failed, reason: getaddrinfo ENOTFOUND linkedsoftwaredependencies.org

Support Record

When using Record<string, string> instead of e.g. { [id: string] : string } the generator throws the error Could not load class or interface Record.

Allow complex default and defaultScoped tags

Currently, we can put @default {<value>} in a comment to indicate the default attribute will be set to the string <value>.

In practice however, our default attribute can be much more complex:

{
"default": [
  {
    "contextShortcutKey": "source",
    "contextShortcutValue": "@comunica/bus-rdf-resolve-quad-pattern:source"
  },
  {
    "contextShortcutKey": "sources",
    "contextShortcutValue": "@comunica/bus-rdf-resolve-quad-pattern:sources"
  }
]
}

A simple solution would be to try to parse the value from the default tag as a JSON string. This might be a bit cumbersome though.
Example:

@default {[
  {
    "contextShortcutKey": "source",
    "contextShortcutValue": "@comunica/bus-rdf-resolve-quad-pattern:source"
  },
  {
    "contextShortcutKey": "sources",
    "contextShortcutValue": "@comunica/bus-rdf-resolve-quad-pattern:sources"
  }
]}

We're also not sure whether our comment parsing library comment-parser can still parse this.

Parsing as JSON is also not the correct thing to do, especially in the case of an xsd:string.
See this example from comunica:

{
  "@id": "cahn:Actor/Http/Native/agentOptions",
  "comment": "The AgentOptions for the HTTP agent as a JSON string",
  "required": false,
  "unique": true,
  "default": "{ \"keepAlive\": true, \"maxSockets\": 5 }",
  "range": "xsd:string"
}

Parsing the default value as JSON would have been incorrect in this case.

Additionally, we'd like to do the same for defaultScoped: add a new tag that users can use in their TypeScript comments and potentially try to parse the value as JSON.

Update NPM tests

Currently, the results of the NPM test @comunica/[email protected] are incorrect, due to an issue with some dependencies of this version. (See this issue). The test doesn't fail however, because we're checking against an invalid result.

More specifically, the following errors should disappear:

error: Did not find a component for superclass AbstractBindingHash
error: We could not find a matching argument for IActorInitRdfDereferencePagedArgs in a superclass

Once there is an update of this package, we should update the tests to reflect the correct behaviour. Other tests might fail as well and expected output should be corrected.

Constructor argument not generated if interface is "empty"

Not completely sure what causes this. The problem is with the LockingResourceStore constructor:

This is about the second parameter, the ExpiringResourceLocker.

When building the config the following constructor parameters get generated:

      "constructorArguments": [
        {
          "@id": "scs:storage/LockingResourceStore#LockingResourceStore_source"
        },
        {
          "fields": []
        }
      ]

As you can see the locks parameter is missing but there is an empty fields array for some reason.

Even more interesting: if I add a random optional function to the ExpiringResourceLocker interface I do get the correct result:

      "constructorArguments": [
        {
          "@id": "scs:storage/LockingResourceStore#LockingResourceStore_source"
        },
        {
          "@id": "scs:storage/LockingResourceStore#LockingResourceStore_locks"
        }
      ]

If I add a random optional number to the interface instead I get

      "constructorArguments": [
        {
          "@id": "scs:storage/LockingResourceStore#LockingResourceStore_source"
        },
        {
          "fields": [
            {
              "keyRaw": "dummy",
              "value": {
                "@id": "scs:storage/LockingResourceStore#LockingResourceStore_locks_dummy"
              }
            }
          ]
        }
      ]

Which I guess is expected and makes sense.


The main issue of having an incorrect generated config file is that this makes it impossible to configure a LockingResourceStore. With the first example above I get the following error when using it in the server:

Error: Could not run config _:b0bnode111 because exactly one valid component type was expected, while 0 were found in the defined types []. Alternatively, the requireName and requireElement must be provided.
Found: Resource { value: '_:b0bnode111', termType: 'BlankNode' }

Which I guess is related to the empty fields array?

When adding a dummy function to get the correct generated config file the server starts up fine.

Handle native classes so that they don't have to be ignored

Currently, classes such as Error have to be added to the .componentsignore file if they are used within constructors. We should make such well-know classes automatically handleable by Components.js, so that they don't have to be ignored.

Make alternative short predicates available for options hashes with `@nest`

In addition to

{
  "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^0.0.0/components/context.jsonld",
  "@graph": [
    {
      "@id": "urn:solid-server:default:IndexConverter",
      "@type": "ConstantConverter",
      "contentType": "text/html",
      "filePath": "./node_modules/mashlib/dist/databrowser.html",
      "options_container": true,
      "options_minQuality": 1
    }
  ]
}

could we also allow

{
  "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^0.0.0/components/context.jsonld",
  "@graph": [
    {
      "@id": "urn:solid-server:default:IndexConverter",
      "@type": "ConstantConverter",
      "contentType": "text/html",
      "filePath": "./node_modules/mashlib/dist/databrowser.html",
      "container": true,
      "minQuality": 1
    }
  ]
}

Don't copy package.json context

It is not necessary to copy the keys of the lsd:contexts entry in the package.json file of a package. This entry is only used for mapping and is not always necessary.

[BUG] Optional lists are marked as unique parameters

Constructor parameters typed as optional list (i.e. the union type of an array type and undefined) are converted by the generator to component parameters with unique: true, leading Components.js to only load the first element of the list as the parameter itself.

Removing the unique: true statement from the components' JSON-LD description manually solves the problem, but is of course not a long-term solution.

(Edit) Additional diagnosis: this happens from 2.5.0 onwards, and turning back to 2.4.0 or earlier is not possible since back then the generator could not process the union types at all.

Add support for unknown type

Currently, using the unknown type in a constructor leads the generator to throw Could not understand parameter type TSUnknownKeyword. Can we add support for that?

Only copy necessary context

Currently, when another component (or in general something that can be referenced by its IRI) is referenced in a constructor argument or field of a constructor argument, we copy all the context entries of its component file.

However, not all these context entries are necessary to reference to the @id of this component. We should create a way to find out which entries are really necessary and only copy those.
An idea would be to create an index of all available contexts and check per package if any of its prefixes is used.

This is low-priority because it's more of an inconvenience than an issue.
However, if our tool is able to detect which are the required contexts, we could expand the fix tool tests to verify an existing .jsonld file is not missing a required context entry.

Support constructor parameters of extended interface

Not sure if this is a generator issue or components.js itself. Not even sure if this is an issue or if I'm missing something on how to do this.

Situation:

export interface ArgsA {
  a: string;
}

export class ClassA {
  constructor(args: ArgsA) {}
}

export interface ArgsB extends ArgsA {
  b: number;
}

export class ClassB extends ClassA {
  constructor(args: ArgsB) {
    super(args);
  }
}

The problem is that I can't configure the a parameter for instances of ClassB. If I use args_a I get an Invalid predicate IRI: args_a error. If I use ClassA:_args_a I do not get an error but a is not defined. The only solution I have found so far is adding the a paramter to the ArgsB interface, but a solution where I do not have to copy the interface fields would be preferable.

Error on TS type packages

When importing from packages without main entrypoint, such as TS types packages like @rdfjs/types, then the generator will fail with an error: Cannot find module @rdfjs/types

This is because the require.resolve logic depends on this main entrypoint.

We might have to dive into the codebase of tsc to see how they resolve this problem there.
But likely, we'll have to reimplement (parts of) require.resolve ourselves to be able to cope with these kinds of resolutions.

Avoid moduleRoot option

All of our CLI tools and Javascript bindings currently have some kind of moduleRoot option, a path relative to the root of a package, to resolve dependencies.
This default to the root directory of a package, but in Comunica for example, you should use the value ../../, because otherwise relevant node modules won't be found and links can not be made.

This is because we use this internally
let nodeModules = await ComponentsJsUtil.getModuleComponentPaths(directory);

However, this utility class only seems to recurse the subdirectories to search for node modules. In the case of the workspace of Comunica, the node modules are actually located in parent folders.

We should find a way that avoids the users of this tool to have to specify a module root, perhaps by traveling the directory structure upwards?

Proper logging

Currently all debug, info and error statements are logged through console.log.
If we want to offer both a command-line executable and a Javascript library, we will have to allow more control over logging at different levels.

Ideas:

  • Optional logging parameter in command
  • Logging parameter in Javascript library
  • Use Winston for logging

Make union types fallback to no range

Currently, when using union types for parameters in the form of string | number, the generator will crash.

Instead, we should make these fallback to a parameter definition without range.
Optionally, we can emit a warning.

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: undefined. Note: this is a nested preset so please contact the preset author if you are unable to fix it yourself.

Use NPM version numbers in test

In our NPM tests, we download the current source of a package and run some tests on it to check if the output is equal to some predetermined output.

Overtime, these packages will change and the output will no longer be the same.
We should find a way to download a specific version of a package.

Expand existing .jsonld files

A next step would be to add additional functionality that would allow a user to expand an existing .jsonld file according to its TypeScript declaration.

Some use-case examples that we would like to implement:

  • Add missing requireElement field
  • Add comment, required, unique and possibly range attributes to classes and parameters that don't have these attributes yet
  • Add constructorArguments that were added
  • (Delete constructorArguments that were removed)
  • (Alter constructorArguments that were altered)

In each case it is important to consider that our arguments might be nested. In such cases, we should also apply the same alterations to the nested class.

The implementation of these changes will require some more abstraction in the current utility functions that we have.

Avoid hardcoded components folder and add component to import list

To retrieve all component files of a module, we should open it's components.jsonld file and parse the import list in it. This is however far from easy because we need to take multiple things into consideration while converting these paths to local paths.
An example of this is the lsd:importPaths option in the package.json which maps the IRI prefix to the local components folder.

Example:

{
  "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@comunica/core/^1.0.0/components/context.jsonld",
  "@id": "npmd:@comunica/core",
  "@type": "Module",
  "requireName": "@comunica/core",
  "import": [
    "files-cc:components/ActionObserver.jsonld",
    "files-cc:components/Actor.jsonld",
    "files-cc:components/Bus.jsonld",
    "files-cc:components/BusIndexed.jsonld",
    "files-cc:components/Logger.jsonld",
    "files-cc:components/Mediator.jsonld"
  ]
}

Our current program searches through the hardcoded components folder and parses every .jsonld file. We should avoid this behaviour to match the real Components.js behaviour.

https://github.com/LinkedSoftwareDependencies/componentsjs-generator/blob/6eeedfef35a2ce15ce1016503fc277a1c72aaff3/lib/AstUtils.js#L129-L148

On top of this, in practice we should add the 'compacted' path of the newly generated .jsonld file to the import option as well. This is not yet implemented, but is very important if we want to fully automate this tool.

JSON range does not work on external type or any

This is with version 3.0.0-beta.1.

As discussed on mattermost.

I'm getting errors that the claims IRI is invalid here: https://github.com/solid/community-server/blob/main/config/identity/handler/provider-factory/identity.json#L18
but this is part of a JSON object defined here as @range {json} : https://github.com/solid/community-server/blob/main/src/identity/configuration/IdentityProviderFactory.ts#L76
and I have added Configuration to the .componentsignore

The generated range for that parameter is "@type": "ParameterRangeUndefined". The same happens if the type is changed to any. If the type is changed to Record<string, unknown> the correct type is generated ("rdf:JSON")

Ignore classes

It should be possible to ignore a class for generation, either via an annotation, or via the CLI.

Record / TSIndexSignature not supported

A constructor with a TSIndexSignature parameter (e.g. { [id: string]: string }) is not supported by the generator (Unsupported field type TSIndexSignature). Record<string, string> which is pretty much a type for that signature is also not supported but with the error Could not load class or interface Record instead.

Problems with optional nested objects

Example constructor to explain the problems:

constructor(value?: number, options?: { value: number, type: { value: number }}))

When running components generator on this, there will be 3 parameters generated, each of them with the same identical URI (ending on ..._value).

Additionally, the last two (whichare part of the options interface) will not be indicated as being optional. The firstone will be optional as expected.

Publish to NPM

We should publish this repo on NPM so it can be used as a dependency in other projects.
This will also allow for an easier install.

Logging transport configuration

The logging framework we use, Winston, allows you to configure several methods, i.e. ways of displaying and saving logging statements: stdout, different files, different formats etc.

Maybe we should allow the CLI tool and Javascript methods to have control over this. This is not high-priority as the logger is mainly used for informing the end-user.

Add initializer script

When people start using this tool and Components.js, they should be able to initialize all the required base files.
Concretely, the following should be done:

  • Add entries to package.json:
"lsd:module": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server",
  "lsd:components": "components/components.jsonld",
  "lsd:contexts": {
    "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^1.0.0/components/context.jsonld": "components/context.jsonld"
  },
  "lsd:importPaths": {
    "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^1.0.0/components/": "components/",
    "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^1.0.0/config/": "config/"
  },
  • Initialize empty folders and files:
components/context.jsonld
components/components.jsonld
config/

Add support for tuple types

Using tuple types (e.g. tuple: [ string, number ]) in a constructor makes the generator fail with Could not understand parameter type TSTupleType. Can we implement support for these?

Test multiple comment compatibility

For some reason it seems like one comment can contain multiple sub-comments according to the library that we use. We should investigate whether this is actually possible. If so, we should make it possible to parse all comments related to a field.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Warning

These dependencies are deprecated:

Datasource Name Replacement PR?
npm @types/lru-cache Unavailable
npm @types/rimraf Unavailable

Edited/Blocked

These updates have been manually edited so Renovate will no longer make changes. To discard all commits and start over, click on a checkbox.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

npm
package.json
  • @types/lru-cache ^5.1.0
  • @types/semver ^7.3.4
  • @typescript-eslint/typescript-estree ^7.1.0
  • comment-parser ^0.7.6
  • componentsjs ^6.0.0
  • jsonld-context-parser ^2.1.5
  • lru-cache ^6.0.0
  • minimist ^1.2.5
  • rdf-object ^1.13.1
  • semver ^7.3.2
  • @rubensworks/eslint-config ^3.0.0
  • @types/fs-extra ^11.0.0
  • @types/jest ^29.0.0
  • @types/minimist ^1.2.0
  • @types/node ^20.0.0
  • @types/rimraf ^3.0.0
  • fs-extra ^11.0.0
  • husky ^9.0.0
  • jest ^29.7.0
  • jest-extended ^4.0.2
  • manual-git-changelog ^1.0.1
  • ts-jest ^29.1.2
  • typescript ^5.3.3
  • node >=18.12
  • yarn 4.0.1
nvm
.nvmrc
  • node 18

  • Check this box to trigger a request for Renovate to run again on this repository

Arrays in hashes get lost

For example:

export interface RepresentationPreferences {
  type?: RepresentationPreference[];
  charset?: RepresentationPreference[];
  datetime?: RepresentationPreference[];
  encoding?: RepresentationPreference[];
  language?: RepresentationPreference[];
}
export interface RepresentationPreference {
  /**
   * The actual preference value.
   */
  value: string;
  /**
   * How important this preference is in a value going from 0 to 1.
   */
  weight: number;
}

Only singular values seem to be generated for type, charset, ..., while these should form an array.

Compact jsonld paths for new @id's in parameters

Currently, when creating a new parameter, it's @id will equal <components_id>/<className>#fieldName.
In this case, <components_id> is the value of the @id entry in the components.jsonld file.
In a lot of cases, this @id can however be compacted even more, which will create cleaner files.

We can use jsonld-context-parser.js or jsonld to compact this value. However, we should should closely look at which contexts we want to use.

Handle types in a generic manner

Type aliases in TypeScript can become very complex.
Due to #47, we now support custom TypeReferenceOverride's for specific type aliases.
This requires us to hardcode support for type aliases, which is not a sustainable solution (but it works for now).

We should think about a generic handling of type aliases. (this will probably not be easy)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.