Coder Social home page Coder Social logo

hydracg / heracles.ts Goto Github PK

View Code? Open in Web Editor NEW
34.0 34.0 16.0 1.85 MB

Reference implementation of a Hydra client in TypeScript

Home Page: https://hydracg.github.io/Heracles.ts/

License: MIT License

TypeScript 98.75% JavaScript 1.25%
hydra hydra-api hypermedia json-ld linked-data rest typescript webapi

heracles.ts's People

Contributors

alien-mcl avatar elf-pavlik avatar lanthaler avatar renovate-bot avatar renovate[bot] avatar snyk-bot avatar tpluscode avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

heracles.ts's Issues

Improve operation invocation API with IRI templates

Current implementation of the Heracles.ts API does not take into account on how to create a correct request when an operation is a composition of:

  • IRI template with variable mappings
  • request body

This enforces on the API user additional knowledge to make a distinction between IRI template/non-IRI template requests before making a final server call.

Some more unified mechanism would come in handy which would just expect an operation and body resource to be passed regardless the fact that the operation needs (or not) an IRI template expanded, i.e.:

const client = new HydraClient();
const addMemberOperation = 
    .getApiDocumentation("http://temp.uri")
    .getEntryPoint()
    .collections.first()
    .operations
    .ofType("http://schema.org/AddAction").first();
client.invoke(addMemberOperation, myNewCollectionMember);

and the operation mentioned contains an IRI template that needs to be filled with values.

Add support for other RDF serializations

As @elf-pavlik stated in issue #8, currently Heracles.ts supports only JSON-LD RDF serialization. It is desired to add support for other serializations, i.e. by using N3.js for these media types:

  • 'text/turtle'
  • 'text/trig'
  • 'text/n-triples'
  • 'text/n-quads'
  • 'text/n3' (optional)

Consider compensation for missing entry point in API documentation

It seems that there are API's that has a broken API documentation that does not provide entry point link (i.e. example API for hydra console: http://www.markus-lanthaler.com/hydra/event-api/).

While this behavior is in fact an incorrect implementation of the hydra vocabulary, it seems that for situation when an actual entry point's Url is provided for API discovery, it is possible to compensate that misbehavior.

Consider implementing that compensation as it may enable more APIs available in the wilderness.

Not able to use Heracles.ts in my Project.

I was trying to experiment with hydra client and found it was reference implementation. So i decided to use it. I followed the instructions given in the Readme. I wrote the following code:
import HydraClientFactory from "@hydra-cg/heracles.ts"; let hydraClient = HydraClientFactory.configure().withDefaults().andCreate(); const main = async () => { const resource = await hydraClient.getResource("http://localhost:8000/api"); } main();
And got the following error:
/home/priyanshu/Documents/heracles-demo/node_modules/@hydra-cg/heracles.ts/src/HydraClientFactory.js:44 .with(fetch.bind(window)); ^ ReferenceError: window is not defined at HydraClientFactory.withDefaults (/home/priyanshu/Documents/heracles-demo/node_modules/@hydra-cg/heracles.ts/src/HydraClientFactory.js:44:30) at Object.<anonymous> (/home/priyanshu/Documents/heracles-demo/main.ts:2:50) at Module._compile (internal/modules/cjs/loader.js:776:30) at Module.m._compile (/home/priyanshu/.nvm/versions/node/v10.16.0/lib/node_modules/ts-node/src/index.ts:858:23) at Module._extensions..js (internal/modules/cjs/loader.js:787:10) at Object.require.extensions.(anonymous function) [as .ts] (/home/priyanshu/.nvm/versions/node/v10.16.0/lib/node_modules/ts-node/src/index.ts:861:12) at Module.load (internal/modules/cjs/loader.js:653:32) at tryModuleLoad (internal/modules/cjs/loader.js:593:12) at Function.Module._load (internal/modules/cjs/loader.js:585:3) at Function.Module.runMain (internal/modules/cjs/loader.js:829:12)

Any Help will be appreciated. Thank you.

Decide on "hypermedia removal"

Should Heracle's remove hypermedia controls from the payload or not? If so, should it do so optionally? Or should this be done at a higher layer?

Clarify how client's JSON-LD context, flattening and the hydra helper from namespaces should work together

PR #11 introduces in JSON-LD context

  "http://www.w3.org/ns/hydra/core#Collection": "http://www.w3.org/ns/hydra/core#Collection",
  "http://www.w3.org/ns/hydra/core#Resource": "http://www.w3.org/ns/hydra/core#Resource"

to my understanding to enforce full IRIs which later get matched against hydra helper exported from namespaces module. Possibly currently JSON-LD context, flattening of the response and use of hydra helper from namespaces module don't work together as good as they can.

@lanthaler also questioned the two lines above in JSON-LD context in #11 (comment)

I see this issue a distinct but related to #14

Get class property value

Hi,

I'm trying to loop over a collection and extract the various property values from the members of the collection. Let's say I have the following abbreviated response from my server:

  "member": [
    {
      "@id": "example:2bfd5353-6842-48f7-9f8c-111474f57dfb",
      "@type": "schema:person",
      "label": "Person 1"
    },
    {
      "@id": "example:108d8384-a55a-4b21-8511-654fb3830d5f",
      "@type": "schema:person",
      "label": "Person 2"
    },
  ],

Then, I'm looping over the response.

const data = await Client.getResource(
  "http://localhost:4000/persons"
);
for (const person of data.members) {
  const iri = person.iri;
  const label = person.label; // How can I do this?
}

As written in the comment above, how can I get properties apart from IRI and type from the members? I couldn't find an actual example in the documentation, tests, use cases and other places I was looking. Any help is greatly appreciated!

Best,
Daniel

Decide on client interface to find collections

This was discussed in #2 but merits an issue on its own. @elf-pavlik's current proposal is to implement something along the lines of

var operation = client.get("http://example.com")
    .getApiDocumentation()
    .getEntryPoint()
    .selectCollection({
      property: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
      object: "http://schema.org/Event"
      })
    .getOperationOfType('http://schema.org/CreateAction');

with possible specialization such selectCollectionByMembersType as a for selecting a collection based on the type of its members:

function selectCollectionByMembersType (membersType) {
  return this.selectCollection({
    property: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
    object: membersType
  }))
}

Apidocumentation instance set entrypoint property as undefined

Hello.
When I call the following function:

const testHeraclesApiDoc = async () => {
  let hydraClient = HydraClientFactory.configure()
    .withDefaults()
    .withAllLinks()  
    .andCreate();
  const apiDoc = await hydraClient.getApiDocumentation("http://localhost:8080/api");
  console.log(await apiDoc.getEntryPoint());  
};

I get the following error:

Uncaught (in promise) Error: There was no Url provided.
    getUrl HydraClient.js:111
    getResource HydraClient.js:62
    getEntryPoint factories.js:13
    testHeraclesApiDoc App.tsx:13
HydraClient.js:111
    testHeraclesApiDoc App.tsx:13
    AsyncFunctionThrow self-hosted:698

I am trying to use heracles.ts in a react application that consumes a mockup hydra API wich explicitly defines its entry point. This is the json-ld output of the documentation path:

{
  "@id": "api/vocab",
  "@type": "hydra:ApiDocumentation",
  "hydra:entrypoint": "http://localhost:8080/api",
  "hydra:supportedClass": [
    {
      "@id": "api/vocab#EntryPoint",
      "@type": [
        "hydra:Class",
        "sh:Shape"
      ],
      "hydra:description": "The main entry point of the API",
      "hydra:supportedOperation": {
        "@type": "hydra:Operation",
        "hydra:description": "The API main entry point",
        "hydra:method": "GET",
        "hydra:returns": {
          "@id": "api/vocab#EntryPoint"
        }
      },
      "hydra:supportedProperty": {
        "@id": "api/vocab#personas",
        "@type": "hydra:SupportedProperty",
        "hydra:property": {
          "@id": "api/vocab#personas-link",
          "@type": "hydra:Link",
          "rdfs:comment": "Enlace a la colección de personas",
          "rdfs:label": "personas-link",
          "rdfs:range": {
            "@id": "api/vocab#PersonaCollection"
          },
          "hydra:supportedOperation": [
            {
              "@type": "hydra:Operation",
              "hydra:method": "GET",
              "hydra:returns": {
                "@id": "api/vocab#PersonaCollection"
              }
            },
            {
              "@type": "hydra:Operation",
              "hydra:expects": {
                "@id": "http://www.personas-mexico.org/persona#Persona"
              },
              "hydra:method": "POST",
              "hydra:returns": {
                "@id": "http://www.personas-mexico.org/persona#Persona"
              }
            }
          ]
        }
      },
      "hydra:title": "EntryPoint"
    },
    {
      "@id": "api/vocab#PersonaCollection",
      "@type": [
        "hydra:Class",
        "hydra:Collection"
      ],
      "hydra:description": "Coleción de todas las personas",
      "hydra:supportedOperation": [],
      "hydra:title": "PersonaCollection",
      "lvz:memberClass": "http://www.personas-mexico.org/persona#Persona"
    },
    {
      "@id": "http://www.personas-mexico.org/persona#Persona",
      "@type": [
        "hydra:Class",
        "sh:Shape"
      ],
      "hydra:description": "Una persona",
      "hydra:supportedOperation": [
        {
          "@type": "hydra:Operation",
          "hydra:method": "GET",
          "hydra:returns": {
            "@id": "http://www.personas-mexico.org/persona#Persona"
          }
        },
        {
          "@type": "hydra:Operation",
          "hydra:method": "DELETE"
        }
      ],
      "hydra:supportedProperty": [
        {
          "@type": "hydra:SupportedProperty",
          "hydra:property": {
            "@id": "http://www.personas-mexico.org/persona#tieneSexo",
            "@type": "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property",
            "rdfs:comment": "El género o sexo de la persona",
            "rdfs:label": "tieneSexo",
            "rdfs:range": {
              "@id": "xsd:string"
            },
            "hydra:supportedOperation": []
          },
          "hydra:required": true
        },
        {
          "@type": "hydra:SupportedProperty",
          "hydra:property": {
            "@id": "http://www.personas-mexico.org/persona#tieneNombre",
            "@type": "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property",
            "rdfs:comment": "El nombre de la persona",
            "rdfs:label": "tieneNombre",
            "rdfs:range": {
              "@id": "xsd:string"
            },
            "hydra:supportedOperation": []
          },
          "hydra:required": true
        },
        {
          "@type": "hydra:SupportedProperty",
          "hydra:property": {
            "@id": "http://www.personas-mexico.org/persona#tieneSegundoApellido",
            "@type": "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property",
            "rdfs:comment": "El segundo apellido de la persona",
            "rdfs:label": "tieneSegundoApellido",
            "rdfs:range": {
              "@id": "xsd:string"
            },
            "hydra:supportedOperation": []
          },
          "hydra:required": false
        },
        {
          "@type": "hydra:SupportedProperty",
          "hydra:property": {
            "@id": "http://www.personas-mexico.org/persona#tienePrimerApellido",
            "@type": "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property",
            "rdfs:comment": "El primer apellido de la persona",
            "rdfs:label": "tienePrimerApellido",
            "rdfs:range": {
              "@id": "xsd:string"
            },
            "hydra:supportedOperation": []
          },
          "hydra:required": true
        }
      ],
      "hydra:title": "Persona"
    },
    {
      "@id": "http://www.personas-mexico.org/persona#Medico",
      "@type": [
        "hydra:Class",
        "sh:Shape"
      ],
      "hydra:description": "Un médico",
      "hydra:supportedOperation": [
        {
          "@type": "hydra:Operation",
          "hydra:method": "GET",
          "hydra:returns": {
            "@id": "http://www.personas-mexico.org/persona#Medico"
          }
        },
        {
          "@type": "hydra:Operation",
          "hydra:method": "DELETE"
        }
      ],
      "hydra:supportedProperty": [
        {
          "@id": "http://www.personas-mexico.org/persona#info-basica-link",
          "@type": "hydra:SupportedProperty",
          "hydra:property": {
            "@id": "http://www.personas-mexico.org/persona#info-basica",
            "@type": "hydra:Link",
            "rdfs:comment": "Información básica de una persona",
            "rdfs:label": "info-basica",
            "rdfs:range": {
              "@id": "http://www.personas-mexico.org/persona#Persona"
            },
            "hydra:supportedOperation": [
              {
                "@type": "hydra:Operation",
                "hydra:method": "GET",
                "hydra:returns": {
                  "@id": "http://www.personas-mexico.org/persona#Persona"
                }
              },
              {
                "@type": "hydra:Operation",
                "hydra:expects": {
                  "@id": "http://www.personas-mexico.org/persona#Persona"
                },
                "hydra:method": "POST",
                "hydra:returns": {
                  "@id": "http://www.personas-mexico.org/persona#Persona"
                }
              }
            ]
          },
          "hydra:readonly": true
        },
        {
          "@type": "hydra:SupportedProperty",
          "hydra:property": {
            "@id": "http://www.personas-mexico.org/persona#tieneCedulaProfesional",
            "@type": "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property",
            "rdfs:comment": "La cédula profesional de un médico",
            "rdfs:label": "tieneCedulaProfesional",
            "rdfs:range": {
              "@id": "xsd:string"
            },
            "hydra:supportedOperation": []
          },
          "hydra:required": true
        }
      ],
      "hydra:title": "Medico"
    },
    {
      "@id": "http://www.personas-mexico.org/persona#Paciente",
      "@type": [
        "hydra:Class",
        "sh:Shape"
      ],
      "hydra:description": "Un paciente",
      "hydra:supportedOperation": [
        {
          "@type": "hydra:Operation",
          "hydra:method": "GET",
          "hydra:returns": {
            "@id": "http://www.personas-mexico.org/persona#Paciente"
          }
        },
        {
          "@type": "hydra:Operation",
          "hydra:method": "DELETE"
        }
      ],
      "hydra:supportedProperty": [
        {
          "@id": "http://www.personas-mexico.org/persona#info-basica-link",
          "@type": "hydra:SupportedProperty",
          "hydra:property": {
            "@id": "http://www.personas-mexico.org/persona#info-basica",
            "@type": "hydra:Link",
            "rdfs:comment": "Información básica de una persona",
            "rdfs:label": "info-basica",
            "rdfs:range": {
              "@id": "http://www.personas-mexico.org/persona#Persona"
            },
            "hydra:supportedOperation": [
              {
                "@type": "hydra:Operation",
                "hydra:method": "GET",
                "hydra:returns": {
                  "@id": "http://www.personas-mexico.org/persona#Persona"
                }
              },
              {
                "@type": "hydra:Operation",
                "hydra:expects": {
                  "@id": "http://www.personas-mexico.org/persona#Persona"
                },
                "hydra:method": "POST",
                "hydra:returns": {
                  "@id": "http://www.personas-mexico.org/persona#Persona"
                }
              }
            ]
          },
          "hydra:readonly": true
        },
        {
          "@type": "hydra:SupportedProperty",
          "hydra:property": {
            "@id": "http://www.personas-mexico.org/persona#tieneFechaDeNacimiento",
            "@type": "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property",
            "rdfs:comment": "La fecha de nacimiento de la persona",
            "rdfs:label": "tieneFechaDeNacimiento",
            "rdfs:range": {
              "@id": "xsd:date-time"
            },
            "hydra:supportedOperation": []
          },
          "hydra:required": true
        }
      ],
      "hydra:title": "Paciente"
    }
  ],
  "lvz:entrypointClass": "http://localhost:8080/api/vocab#EntryPoint",
  "@context": {
    "@vocab": "http://localhost:8080/api/vocab#",
    "@base": "http://localhost:8080/",
    "hydra": "http://www.w3.org/ns/hydra/core#",
    "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
    "xsd": "http://www.w3.org/2001/XMLSchema#",
    "sh": "http://www.w3.org/ns/shacl#"
  }
}

From what I see the error is generated because the ApiDocumentation object obtained does not set the entryPoint property. This is the output of the object:

image

I don't know if this is a bug or maybe I'm missing something.

Consider using/merging the api-doc-parser library

Hi everybody,

Some months ago I published a Hydra client library we use for API Platform's client-side tools: https://github.com/dunglas/api-doc-parser

It looks very similar to what you are doing (but uses ES6 + Flow instead of TypeScript). It is already used by two of our tools:

I looked quickly to your implementation, and it looks really similar to ours. The main difference is that we designed our library with an abstraction layer to be able to consume other formats like Swagger or JSONAPI (but it's not done yet).
Can we find a way to collaborate? It's useless to duplicate the effort.

should JSON-LD @context from payload get ignored?

When JsonLdHypermediaProcessor flattens the payload it should probably always use context provided to the client by the developer using the client and never the one from the payload returned from the server.

Developer using a client has to have full control over JSON-LD context used to flatten paylad to use aliases from that context in the code. Context in the payload (response from the server) should stay considered as not under control of the developer using client and the code should not make any assumptions about that context and only rely on context directly provided to the client by the developer.

Possibly related to what @alien-mcl mentioned in #11 (comment)

Ahh. It was some time ago, but I think this was to force either framing or flattening to enforce those urls. For some reason these were incorrectly processed.

Hypermedia lacks response headers

Currently client returns a received resource from a client.getResource(url) call.
While the hypermedia property provides all the hydra related details that were discovered, current approach hides all the physical response parameters, especially headers (including content type).

Consider adding those details to either the hypermedia container or some other property designated.

Revisit extraction of "hypermedia" from resources

Currently Heracles extracts things like operations into a hypermedia property. The proposal is to either use hydra instead or directly use Hydra terms like member.

The reason I don't like hypermedia is because it is the combination of the controls and the information etc. This comment from Roy T. Fielding probably describes best what I want to say: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven#comment-718

When I say hypertext, I mean the simultaneous presentation of information and controls such that the information becomes the affordance through which the user (or automaton) obtains choices and selects actions.

What we try to do here is to extract the controls out of the hypertext/hypermedia.

I thought about controls too but things like controls.member don't seem to make too much sense. Since this is the Hydra reference client, I wouldn't be too worried about using the term hydra for this.

Dependency Dashboard

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

This repository currently has no open or pending branches.

Detected dependencies

npm
package.json
  • @rdfjs/parser-n3 ^2.0.0
  • @rdfjs/serializer-jsonld ^2.0.0
  • isomorphic-fetch 3.0.0
  • jsonld ^8.0.0
  • parse-link-header 2.0.0
  • uri-templates 0.2.0
  • urijs 1.19.11
  • @types/body-parser 1.19.5
  • @types/express 4.17.21
  • @types/jasmine 5.1.4
  • @types/js-md5 0.7.2
  • @types/node 20.12.11
  • @types/parse-link-header 2.0.3
  • @types/sinon 17.0.3
  • @types/uri-templates 0.1.34
  • babel-core 6.26.3
  • babel-loader 9.1.3
  • babel-preset-env 1.7.0
  • babel-preset-es2017 6.24.1
  • babel-preset-stage-0 6.24.1
  • body-parser 1.20.2
  • express 4.19.2
  • istanbul-instrumenter-loader 3.0.1
  • jasmine 5.1.0
  • jasmine-sinon 0.4.0
  • js-md5 0.8.3
  • karma 6.4.3
  • karma-chrome-launcher 3.2.0
  • karma-coverage-istanbul-reporter 3.0.3
  • karma-coveralls 2.1.0
  • karma-jasmine 5.1.0
  • karma-jasmine-sinon 1.0.4
  • karma-sinon 1.0.5
  • karma-source-map-support 1.4.0
  • karma-sourcemap-loader 0.4.0
  • karma-summary-reporter 4.0.1
  • karma-webpack 5.0.1
  • prettier 3.2.5
  • raw-loader 4.0.2
  • sinon 17.0.2
  • source-map-loader 5.0.0
  • ts-loader 9.5.1
  • ts-node 10.9.2
  • tslint 6.1.3
  • tslint-eslint-rules 5.4.0
  • tslint-language-service 0.9.9
  • typedoc 0.25.13
  • typedoc-plugin-markdown 4.0.1
  • typescript 5.4.5
  • webpack 5.91.0
  • webpack-karma-jasmine 4.0.0
src/N3/package.json
  • @rdfjs/parser-n3 ^2.0.0
  • @rdfjs/serializer-jsonld ^2.0.0
  • @hydra-cg/heracles.ts 0.5.1
travis
.travis.yml
  • node 10
  • node 9
  • node 8
  • node 7

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

Are responses fully typed?

I'm trying to gauge how good the TS types are in the responses from this client.

The example in the readme doesn't look great:

CleanShot 2022-09-30 at 10 02 48

Although there are a lot of .d.ts files in this package, so there's at least some level of type defs added.

Cease support for memberTemplate

Currently heracles.ts uses memberTemplate for collection's templated operations. This predicate never reached a spec (still at PR stage) and I think it will never do so.

Consider removing it in favour of templated link's supported operations.

Consider lazy response processing

There is an option of having a lazy payload processing implementation that would carry a response object received from the 'fetch' API and use the client's facilities to process that response on demand once proper properties or methods are invoked.
This may delay or in some cases prevent unnecessary processing.

correctly using heracles on a localhost

I looked at the tests and all the IDs there are relative to the server, e.g. "@id": "/api/people", However, my server returns json-ld with a domain name "@id": "http://mydomain.com/api/people",

What's the correct way to use heracles on a localhost?

Currently I'm rewriting the getResource-Function to point any requests to the test-server running on localhost. The entrypoint's hypermedia gets a mixture of both: "iri"-property is from localhost, "@id" is "mydomain". Here's my HydraClient-initialization:

private static initHydra(): HydraClientAPI { let rv: HydraClientAPI = new HydraClientAPI(); let factory: HydraClientFactory = new HydraClientFactory(); rv.hc = factory.withDefaults().andCreate() as HydraClient; rv.hc.getResource = async (urlOrResource) => { //START getUrl let url: any = urlOrResource; if (typeof url === "object") { url = !!url.target ? url.target.iri : url.iri; } if (!!!url) { throw new Error(HydraClient.noUrlProvided); } //END getUrl serverURLMap.forEach((val, key) => { if ((url as string).startsWith(key)) { url = (url as string).replace(key, val); } }); const response = await fetch(url); if (response.status !== 200) { throw new Error(HydraClient.invalidResponse + response.status); } const hypermediaProcessor = rv.hc.getHypermediaProcessor(response); if (!hypermediaProcessor) { throw new Error(HydraClient.responseFormatNotSupported); } const result = await hypermediaProcessor.process(response, rv.hc); Object.defineProperty(result, "iri", { value: response.url }); return result; }; rv.setHydraApiDoc(hydraApiDocURL); return rv; }

Multiple API documentations

Currently the client cannot process correctly multiple API documentations (i.e. linked by the LINK header). This should be corrected so multiple API documentations can be exposed in the client's API.

Question on status of spec and releases

I wanted to find out about the status of Heracles.ts relative to the spec, especially with regards to releases on NPM. Is there a particular release that ties to the current draft?

Links are to strict

Current implementation adds as links only those predicates that are either known to be hydra:Link or hydra:TemplatedLink or are explicitely defined as so within the obtained graph. This seems to be to strict for most of the APIs, thus some configurable policy would come in handy.

Should we keep using the "hypermedia interface" or switch to something else?

This was raised in PR #11:

            expect(this.result.hypermedia).toEqual([
                {
                    iri: "http://temp.uri/api/events",
                    isA: [hydra.Collection],
                    totalItems: 1,
                    members: [
                        {
                            iri: "http://temp.uri/api/events/1",
                            isA: [],
                            "http://schema.org/endDate": "2017-04-19",
                            "http://schema.org/eventDescription": "Some event 1",
                            "http://schema.org/eventName": "Event 1",
                            "http://schema.org/startDate": "2017-04-19"
                        }
                    ]
                }, {
                    iri: "http://temp.uri/api/events/1",
                    isA: [],
                    "http://schema.org/endDate": "2017-04-19",
                    "http://schema.org/eventDescription": "Some event 1",
                    "http://schema.org/eventName": "Event 1",
                    "http://schema.org/startDate": "2017-04-19"
                }, {
                    iri: 'some:named.graph',
                    isA: []
                }
            ]);
        });

I made the following comment:

I think this shows the leaky nature of this interface quite clearly. It returns a more or less random set of data. I'd expect to be able to get a list of links to related resources and a list of operations that I then can invoke.

Something like

links = this.result.getLinks();
--> returns an array of Link instances which have the property, the target 
    (and perhaps a few additional properties describing the target)
links[0].getProperty() --> examplevocab:events
links[0].getTarget() --> /api/events
...

This link could then simply be passed to the client this.client.getResource(links[0]) or, perhaps more intuitive, links[0].retrieveTarget(this.client)

Obtaining whole collection

Current implementation allows to gather collection's members, but whether it is a complete one, or just a partial view, client will discover afterwards. It could be useful to have a mechanism that will fetch all collection's members regardless underlying implementation details (full or parial view).

Consider renaming displayName to title

Both hydra:Class and hydra:ApiDocumentation use:

    /**
     * Gets a title of this API documentation.
     * @readonly
     * @returns {string}
     */
    readonly displayName?: string;

However, the spec uses hydra:title. Is this difference meaningful? If not, I think it should probably be renamed in the next breaking version because it could cause some confusion for new users.

Also: maybe the Typescript documentation should link to the relevant properties in the Hydra spec.

Don't mint blank node IDs unless absolutely necessary

Heracles sometimes mints blank node IDs without avoiding collisions with already existing blank node IDs. We either need to do that or stop minting such identifiers as they shouldn't be necessary in the first place.

Extending from Arrays (Compatibility)

Hi everyone,

in a personal project I'm using Heracles, and it runs into an issue with TypesCollection.

The issue comes from directly extending Array, so I've done some research on the matter:

  • Extending from Array isn't possible at all on older javascript versions
  • It's possible to do this in newer Typescript versions, but if someone uses Babel to transpile, they must use a plugin , and I haven't yet been able to make it work
  • There are alternatives to directly extending arrays, such as wrappers. I assume the TypesCollection-type's functionality might grow in the future, wouldn't that be a good alternative?

Hope you all had a good start into 2018!

NPM publish

I renamed the old Heracles and I can transfer ownership on the NPM package.

What do you guys think?

Get rid of prettier

... or at least reconfigure it.
I try to embrace my own code reformatted by this component and I find it difficult.
My IDE's defaults shows a break line at 120 chars long line, but prettier mostly uses half of it.
I know that someone may need to print it with a legacy 80 chars long needle printer on a toilette paper or just switched from COBOL console, but these setting makes my Full HD 31 inch monitor pretty useless.
I don't know what readability preferences were used by creators, but when I try to write my code to be fluent-like where each line tries to be a sentence, it's a mess at the end.
It's my personal opinion, but please try to write/read some code reformatted with these settings before using it. For me, it's pain in the ... you know where.

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.