diff --git a/packages/connected-nextgraph/src/NextGraphConnectedPlugin.ts b/packages/connected-nextgraph/src/NextGraphConnectedPlugin.ts new file mode 100644 index 0000000..fd46bdf --- /dev/null +++ b/packages/connected-nextgraph/src/NextGraphConnectedPlugin.ts @@ -0,0 +1,15 @@ +import type { ConnectedPlugin } from "@ldo/connected"; +import type { NextGraphUri } from "./types"; +import type { NextGraphResource } from "./resources/NextGraphResource"; + +export interface NextGraphConnectedPlugin extends ConnectedPlugin { + name: "nextGraph"; + getResource(uri: NextGraphUri): NextGraphResource; +} + +export const nextGraphConnectedPlugin: NextGraphConnectedPlugin = { + name: "nextGraph", + getResource(_uri: NextGraphUri): NextGraphResource { + throw new Error("Not Implemented"); + }, +}; diff --git a/packages/connected-nextgraph/src/createSolidLdoDataset.ts b/packages/connected-nextgraph/src/createSolidLdoDataset.ts new file mode 100644 index 0000000..27611df --- /dev/null +++ b/packages/connected-nextgraph/src/createSolidLdoDataset.ts @@ -0,0 +1,13 @@ +import { ConnectedLdoDataset } from "@ldo/connected"; +import { solidConnectedPlugin } from "./NextGraphConnectedPlugin"; +import { createDatasetFactory } from "@ldo/dataset"; +import { createTransactionDatasetFactory } from "@ldo/subscribable-dataset"; + +export function createSolidLdoDataset() { + const solidLdoDataset = new ConnectedLdoDataset( + [solidConnectedPlugin], + createDatasetFactory(), + createTransactionDatasetFactory(), + ); + return solidLdoDataset; +} diff --git a/packages/connected-nextgraph/src/index.ts b/packages/connected-nextgraph/src/index.ts new file mode 100644 index 0000000..76b6e45 --- /dev/null +++ b/packages/connected-nextgraph/src/index.ts @@ -0,0 +1,6 @@ +export * from "./types"; +export * from "./NextGraphConnectedPlugin"; + +export * from "./resources/NextGraphResource"; + +export * from "./util/isSolidUri"; diff --git a/packages/connected-nextgraph/src/resources/NextGraphResource.ts b/packages/connected-nextgraph/src/resources/NextGraphResource.ts new file mode 100644 index 0000000..0557cb0 --- /dev/null +++ b/packages/connected-nextgraph/src/resources/NextGraphResource.ts @@ -0,0 +1,3 @@ +import type { Resource } from "@ldo/connected"; + +export class NextGraphResource implements Resource {} diff --git a/packages/connected-nextgraph/src/types.ts b/packages/connected-nextgraph/src/types.ts new file mode 100644 index 0000000..844cb60 --- /dev/null +++ b/packages/connected-nextgraph/src/types.ts @@ -0,0 +1,8 @@ +export type NextGraphUriPrefix = `did:ng`; + +/** + * A NextGraph is a URI that is valid in the NextGraph ecosystem + */ +// The & {} allows for alias preservation +// eslint-disable-next-line @typescript-eslint/ban-types +export type NextGraphUri = `${NextGraphUriPrefix}${string}` & {}; diff --git a/packages/connected-nextgraph/src/util/isSolidUri.ts b/packages/connected-nextgraph/src/util/isSolidUri.ts new file mode 100644 index 0000000..84b6f46 --- /dev/null +++ b/packages/connected-nextgraph/src/util/isSolidUri.ts @@ -0,0 +1,10 @@ +import type { NextGraphUri } from "../types"; + +/** + * Checks if a provided string is a leaf URI + * @param uri - the string to check + * @returns true if the string is a leaf URI + */ +export function isNextGraphUri(uri: string): uri is NextGraphUri { + return uri.startsWith("did:ng"); +} diff --git a/packages/connected-solid/package.json b/packages/connected-solid/package.json index 122ca09..1e9c83d 100644 --- a/packages/connected-solid/package.json +++ b/packages/connected-solid/package.json @@ -23,30 +23,11 @@ }, "homepage": "https://github.com/o-development/ldobjects/tree/main/packages/solid#readme", "devDependencies": { - "@inrupt/solid-client-authn-core": "^2.2.6", - "@ldo/cli": "^1.0.0-alpha.1", - "@rdfjs/data-model": "^1.2.0", - "@rdfjs/types": "^1.0.1", - "@solid-notifications/types": "^0.1.2", - "@solid/community-server": "^7.1.3", - "@types/jest": "^27.0.3", - "cross-env": "^7.0.3", - "dotenv": "^16.3.1", - "jest-rdf": "^1.8.0", - "ts-jest": "^27.1.2", - "ts-node": "^10.9.1", - "typed-emitter": "^2.1.0", - "typedoc": "^0.25.4", - "typedoc-plugin-markdown": "^3.17.1" + }, "dependencies": { - "@ldo/dataset": "^1.0.0-alpha.1", - "@ldo/ldo": "^1.0.0-alpha.1", - "@ldo/rdf-utils": "^1.0.0-alpha.1", - "@solid-notifications/subscription": "^0.1.2", - "cross-fetch": "^3.1.6", - "http-link-header": "^1.1.1", - "ws": "^8.18.0" + "@ldo/connected": "^1.0.0-alpha.1", + "@ldo/connected-nextgraph": "^1.0.0-alpha.1" }, "files": [ "dist", diff --git a/packages/connected-solid/src/SolidConnectedPlugin.ts b/packages/connected-solid/src/SolidConnectedPlugin.ts new file mode 100644 index 0000000..96d16df --- /dev/null +++ b/packages/connected-solid/src/SolidConnectedPlugin.ts @@ -0,0 +1,20 @@ +import type { ConnectedPlugin } from "@ldo/connected"; +import type { SolidContainerUri, SolidLeafUri, SolidUri } from "./types"; +import type { SolidLeaf } from "./resources/SolidLeaf"; +import type { SolidContainer } from "./resources/SolidContainer"; + +export interface SolidConnectedPlugin extends ConnectedPlugin { + name: "solid"; + identifierType: SolidUri; + getResource: + | ((uri: SolidLeafUri) => SolidLeaf) + | ((uri: SolidContainerUri) => SolidContainer); +} + +export const solidConnectedPlugin: SolidConnectedPlugin = { + name: "solid", + identifierType: "https://example.com", + getResource(_uri: SolidUri): SolidContainer | SolidLeaf { + throw new Error("Not Implemented"); + }, +}; diff --git a/packages/connected-solid/src/createSolidLdoDataset.ts b/packages/connected-solid/src/createSolidLdoDataset.ts new file mode 100644 index 0000000..3d1ad7f --- /dev/null +++ b/packages/connected-solid/src/createSolidLdoDataset.ts @@ -0,0 +1,13 @@ +import { ConnectedLdoDataset } from "@ldo/connected"; +import { solidConnectedPlugin } from "./SolidConnectedPlugin"; +import { createDatasetFactory } from "@ldo/dataset"; +import { createTransactionDatasetFactory } from "@ldo/subscribable-dataset"; + +export function createSolidLdoDataset() { + const solidLdoDataset = new ConnectedLdoDataset( + [solidConnectedPlugin], + createDatasetFactory(), + createTransactionDatasetFactory(), + ); + return solidLdoDataset; +} diff --git a/packages/connected-solid/src/index.ts b/packages/connected-solid/src/index.ts new file mode 100644 index 0000000..2f16902 --- /dev/null +++ b/packages/connected-solid/src/index.ts @@ -0,0 +1,8 @@ +export * from "./types"; +export * from "./SolidConnectedPlugin"; + +export * from "./resources/SolidResource"; +export * from "./resources/SolidContainer"; +export * from "./resources/SolidLeaf"; + +export * from "./util/isSolidUri"; diff --git a/packages/connected-solid/src/resources/SolidContainer.ts b/packages/connected-solid/src/resources/SolidContainer.ts new file mode 100644 index 0000000..2208c3c --- /dev/null +++ b/packages/connected-solid/src/resources/SolidContainer.ts @@ -0,0 +1,3 @@ +import { SolidResource } from "./SolidResource"; + +export class SolidContainer extends SolidResource {} diff --git a/packages/connected-solid/src/resources/SolidLeaf.ts b/packages/connected-solid/src/resources/SolidLeaf.ts new file mode 100644 index 0000000..0c8252f --- /dev/null +++ b/packages/connected-solid/src/resources/SolidLeaf.ts @@ -0,0 +1,3 @@ +import { SolidResource } from "./SolidResource"; + +export class SolidLeaf extends SolidResource {} diff --git a/packages/connected-solid/src/resources/SolidResource.ts b/packages/connected-solid/src/resources/SolidResource.ts new file mode 100644 index 0000000..74c7e92 --- /dev/null +++ b/packages/connected-solid/src/resources/SolidResource.ts @@ -0,0 +1,3 @@ +import type { Resource } from "@ldo/connected"; + +export class SolidResource implements Resource {} diff --git a/packages/connected-solid/src/test.ts b/packages/connected-solid/src/test.ts new file mode 100644 index 0000000..9ccdfcd --- /dev/null +++ b/packages/connected-solid/src/test.ts @@ -0,0 +1,19 @@ +import { ConnectedLdoDataset } from "@ldo/connected"; +import { solidConnectedPlugin } from "./SolidConnectedPlugin"; +import { createDatasetFactory } from "@ldo/dataset"; +import { createTransactionDatasetFactory } from "@ldo/subscribable-dataset"; +import { nextGraphConnectedPlugin } from "@ldo/connected-nextgraph"; + +const dataset = new ConnectedLdoDataset( + [solidConnectedPlugin, nextGraphConnectedPlugin], + createDatasetFactory(), + createTransactionDatasetFactory(), +); + +const stringId: string = "blah"; +const allResources = dataset.getResource(stringId); +const containerResource = dataset.getResource("https://example.com/container/"); +const leafResource = dataset.getResource( + "https://example.com/container/index.ttl", +); +const nextGraphResource = dataset.getResource("did:ng:cool", "solid"); diff --git a/packages/connected-solid/src/types.ts b/packages/connected-solid/src/types.ts new file mode 100644 index 0000000..0597227 --- /dev/null +++ b/packages/connected-solid/src/types.ts @@ -0,0 +1,114 @@ +export type SolidUriPrefix = `http${"s" | ""}://`; + +/** + * A SolidUri is a URI that is valid in the Solid ecosystem ("http" and "https") + */ +export type SolidUri = `${SolidUriPrefix}${string}`; + +/** + * A SolidLeafUri is any URI that has a pahtname that ends in a "/". It represents a + * container. + */ +// The & {} allows for alias preservation +// eslint-disable-next-line @typescript-eslint/ban-types +export type SolidContainerUri = `${SolidUri}/${NonPathnameEnding}` & {}; + +/** + * A LeafUri is any URI that does not have a pahtname that ends in a "/". It + * represents a data resource or a binary resource. Not a container. + */ +export type SolidLeafUri = + // The & {} allows for alias preservation + // eslint-disable-next-line @typescript-eslint/ban-types + `${SolidUri}${EveryLegalPathnameCharacterOtherThanSlash}${NonPathnameEnding}` & {}; + +/** + * @internal + */ +type NonPathnameEnding = "" | `?${string}` | `#${string}`; + +/** + * @internal + */ +type EveryLegalPathnameCharacterOtherThanSlash = + | "A" + | "B" + | "C" + | "D" + | "E" + | "F" + | "G" + | "H" + | "I" + | "J" + | "K" + | "L" + | "M" + | "N" + | "O" + | "P" + | "Q" + | "R" + | "S" + | "T" + | "U" + | "V" + | "W" + | "X" + | "Y" + | "Z" + | "a" + | "b" + | "c" + | "d" + | "e" + | "f" + | "g" + | "h" + | "i" + | "j" + | "k" + | "l" + | "m" + | "n" + | "o" + | "p" + | "q" + | "r" + | "s" + | "t" + | "u" + | "v" + | "w" + | "x" + | "y" + | "z" + | "1" + | "2" + | "3" + | "4" + | "5" + | "6" + | "7" + | "8" + | "9" + | "0" + | "-" + | "." + | "_" + | "~" + | ":" + | "[" + | "]" + | "@" + | "!" + | "$" + | "&" + | "'" + | "(" + | ")" + | "*" + | "+" + | "," + | ";" + | "="; diff --git a/packages/connected-solid/src/util/isSolidUri.ts b/packages/connected-solid/src/util/isSolidUri.ts new file mode 100644 index 0000000..6970d21 --- /dev/null +++ b/packages/connected-solid/src/util/isSolidUri.ts @@ -0,0 +1,43 @@ +import type { SolidContainerUri, SolidLeafUri, SolidUri } from "../types"; + +/** + * Checks if a provided string is a leaf URI + * @param uri - the string to check + * @returns true if the string is a leaf URI + */ +export function isSolidUri(uri: string): uri is SolidUri { + try { + const url = new URL(uri); + return url.protocol === "https:" || url.protocol === "http:"; + } catch { + return false; + } +} + +/** + * Checks if a provided string is a Container URI + * @param uri - the string to check + * @returns true if the string is a container URI + */ +export function isSolidContainerUri(uri: string): uri is SolidContainerUri { + try { + const url = new URL(uri); + return url.pathname.endsWith("/"); + } catch { + return false; + } +} + +/** + * Checks if a provided string is a leaf URI + * @param uri - the string to check + * @returns true if the string is a leaf URI + */ +export function isSolidLeafUri(uri: string): uri is SolidLeafUri { + try { + const url = new URL(uri); + return url.pathname.endsWith("/"); + } catch { + return false; + } +} diff --git a/packages/connected/src/ConnectedLdoDataset.ts b/packages/connected/src/ConnectedLdoDataset.ts index c2a5148..a82c1f0 100644 --- a/packages/connected/src/ConnectedLdoDataset.ts +++ b/packages/connected/src/ConnectedLdoDataset.ts @@ -1,12 +1,12 @@ import { LdoDataset } from "@ldo/ldo"; -import type { ConnectedLdoPlugin } from "./ConnectedLdoPlugin"; +import type { ConnectedPlugin } from "./ConnectedPlugin"; import type { Dataset, DatasetFactory, Quad } from "@rdfjs/types"; import type { ITransactionDatasetFactory } from "@ldo/subscribable-dataset"; type ReturnTypeFromArgs = T extends (arg: Arg) => infer R ? R : never; export class ConnectedLdoDataset< - Plugins extends ConnectedLdoPlugin[], + Plugins extends ConnectedPlugin[], > extends LdoDataset { private plugins: Plugins; @@ -23,11 +23,13 @@ export class ConnectedLdoDataset< getResource< Name extends Plugins[number]["name"], Plugin extends Extract, - UriType extends Parameters[0], + UriType extends string, >( _uri: UriType, _pluginName?: Name, - ): ReturnTypeFromArgs { - return "eh?" as ReturnTypeFromArgs; + ): UriType extends Parameters[0] + ? ReturnTypeFromArgs + : ReturnType { + throw new Error("Not Implemented"); } } diff --git a/packages/connected/src/ConnectedLdoPlugin.ts b/packages/connected/src/ConnectedPlugin.ts similarity index 72% rename from packages/connected/src/ConnectedLdoPlugin.ts rename to packages/connected/src/ConnectedPlugin.ts index 2b9ae2e..3ffda7b 100644 --- a/packages/connected/src/ConnectedLdoPlugin.ts +++ b/packages/connected/src/ConnectedPlugin.ts @@ -1,6 +1,6 @@ import type { Resource } from "./Resource"; -export interface ConnectedLdoPlugin { +export interface ConnectedPlugin { name: string; getResource(uri: string): Resource; } diff --git a/packages/connected/src/Resource.ts b/packages/connected/src/Resource.ts index 106a26b..494c961 100644 --- a/packages/connected/src/Resource.ts +++ b/packages/connected/src/Resource.ts @@ -1,7 +1 @@ export interface Resource {} - -export class SolidResource implements Resource {} -export class SolidContainer extends SolidResource {} -export class SolidLeaf extends SolidResource {} - -export class NextGraphResource implements Resource {} diff --git a/packages/connected/src/index.ts b/packages/connected/src/index.ts new file mode 100644 index 0000000..ae02b40 --- /dev/null +++ b/packages/connected/src/index.ts @@ -0,0 +1,5 @@ +import { ConnectedLdoDataset } from "./ConnectedLdoDataset"; + +export * from "./ConnectedLdoDataset"; +export * from "./ConnectedPlugin"; +export * from "./Resource"; diff --git a/packages/connected/src/test.ts b/packages/connected/src/test.ts deleted file mode 100644 index 8f7eebc..0000000 --- a/packages/connected/src/test.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { createDatasetFactory } from "@ldo/dataset"; -import { ConnectedLdoDataset } from "./ConnectedLdoDataset"; -import { createTransactionDatasetFactory } from "@ldo/subscribable-dataset"; -import type { ContainerUri, LeafUri } from "../../solid/src/index"; -import { SolidContainer, SolidLeaf } from "./Resource"; - -interface SolidPlugin { - name: "solid"; - getResource(uri: ContainerUri): SolidContainer; - getResource(uri: LeafUri): SolidLeaf; - getResource(uri: string): SolidLeaf | SolidContainer; -} - -const solidPlugin: SolidPlugin = { - name: "solid", - // eslint-disable-next-line @typescript-eslint/no-explicit-any - getResource(_uri: string): any { - throw new Error(); - }, -}; - -interface NextgraphPlugin { - name: "nextgraph"; - getResource(uri: ContainerUri); - getResource(uri: string): "nextgraphResource"; -} - -const nextgraphPlugin: NextgraphPlugin = { - name: "nextgraph", - getResource(_uri: string): "nextgraphResource" { - return "nextgraphResource"; - }, -}; - -async function main() { - const dataset = new ConnectedLdoDataset( - [solidPlugin, nextgraphPlugin], - createDatasetFactory(), - createTransactionDatasetFactory(), - ); - - const solidContainerResource = dataset.getResource("https://example.com/"); - const solidLeafResource = dataset.getResource( - "https://example.com/resource.ttl", - ); - const stringUri: string = "https://example.com/"; - const allResources = dataset.getResource(stringUri); - const solidResource = dataset.getResource(stringUri, "solid"); - const nextgraphResource = dataset.getResource(stringUri, "nextgraph"); - - const nextgraphResource2 = dataset.getResource( - "did:ng:o:OGNxCWfTXMfYIJi8HCEfL6_uExLtCHrK0JGT4fU5pH4A:v:R2y5iENVwuaaoW86TvMbfZfCIrNXaNIFA3BF6fx9svQA", - ); -} -main();