main
jaxoncreed 2 years ago
parent 1db769103f
commit e0520c0d08
  1. 9910
      package-lock.json
  2. 3
      packages/cli/.eslintrc
  3. 26
      packages/cli/README.md
  4. 5
      packages/cli/jest.config.js
  5. 54
      packages/cli/package.json
  6. 69
      packages/cli/src/build.ts
  7. 25
      packages/cli/src/index.ts
  8. 78
      packages/cli/src/init.ts
  9. 8
      packages/cli/src/templates/context.ejs
  10. 19
      packages/cli/src/templates/defaultShapes/foafProfile.ejs
  11. 8
      packages/cli/src/templates/schema.ejs
  12. 24
      packages/cli/src/templates/shapeTypes.ejs
  13. 14
      packages/cli/src/templates/typings.ejs
  14. 3
      packages/cli/test/placeholder.test.ts
  15. 7
      packages/cli/tsconfig.build.json
  16. 6
      packages/demo-react/package.json
  17. 11
      packages/solid-react/package.json

9910
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,3 @@
{
"extends": ["../../eslintrc"]
}

@ -0,0 +1,26 @@
# LDO-CLI
A command line interface for Linked Data Objects. LDO-CLI builds `.shex` shapes into LDO types.
## Setup
Install the CLI
```bash
npm i ldo-cli --save-dev
```
Set up a shapes folder
```bash
mkdir shapes
```
Place ShexC shapes inside `.shex` files
```bash
touch ./shapes/example.shex
```
Build the shpaes
```bash
ldo build --input ./shapes --output ./ldo
```

@ -0,0 +1,5 @@
const sharedConfig = require('../../jest.config.js');
module.exports = {
...sharedConfig,
'rootDir': './',
}

@ -0,0 +1,54 @@
{
"name": "@ldo/cli",
"version": "0.0.0",
"description": "A Command Line Interface for Linked Data Objects",
"main": "./dist/index.js",
"bin": {
"ldo": "./dist/index.js"
},
"scripts": {
"start": "node dist/index.js build",
"start:init": "node dist/index.js init",
"dev": "npm run build && npm run start:init",
"build": "npm run clean && npm run build:ts && npm run copy-files && npm run update-permission",
"build:ts": "tsc --project tsconfig.build.json",
"clean": "rimraf dist/",
"copy-files": "copyfiles -u 1 \"./src/**/*.ejs\" dist/",
"update-permission": "chmod +x ../../node_modules/.bin/ldo",
"watch": "tsc --watch",
"test": "jest --coverage",
"test:watch": "jest --watch",
"prepublishOnly": "npm run test && npm run build",
"postinstall": "npm run build"
},
"repository": {
"type": "git",
"url": "git+https://github.com/o-development/ldo-cli.git"
},
"author": "Jackson Morgan",
"license": "MIT",
"bugs": {
"url": "https://github.com/o-development/ldo-cli/issues"
},
"homepage": "https://github.com/o-development/ldo-cli#readme",
"devDependencies": {
"@types/child-process-promise": "^2.2.2",
"@types/ejs": "^3.1.1",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^27.0.3",
"@types/shexj": "^2.1.4",
"copyfiles": "^2.4.1",
"jest": "^27.4.2",
"rimraf": "^3.0.2",
"ts-jest": "^27.0.7"
},
"dependencies": {
"@shexjs/parser": "^1.0.0-alpha.24",
"child-process-promise": "^2.2.1",
"commander": "^9.3.0",
"ejs": "^3.1.8",
"fs-extra": "^10.1.0",
"loading-cli": "^1.1.0",
"shexj2typeandcontext": "^2.0.0"
}
}

@ -0,0 +1,69 @@
import fs from "fs-extra";
import path from "path";
import { Schema } from "shexj";
import parser from "@shexjs/parser";
import shexjToTypeAndContext from "shexj2typeandcontext";
import { renderFile } from "ejs";
import prettier from "prettier";
import loading from "loading-cli";
interface BuildOptions {
input: string;
output: string;
}
export async function build(options: BuildOptions) {
const load = loading("Peparing Environment");
load.start();
const shapeDir = await fs.promises.readdir(options.input, {
withFileTypes: true,
});
// Filter out non-shex documents
const shexFiles = shapeDir.filter(
(file) => file.isFile() && file.name.endsWith(".shex")
);
// Prepare new folder by clearing/and/or creating it
if (fs.existsSync(options.output)) {
await fs.promises.rm(options.output, { recursive: true });
}
await fs.promises.mkdir(options.output);
load.text = "Generating LDO Documents";
await Promise.all(
shexFiles.map(async (file) => {
const fileName = path.parse(file.name).name;
// Get the content of each document
const shexC = await fs.promises.readFile(
path.join(options.input, file.name),
"utf8"
);
// Convert to ShexJ
const schema: Schema = parser
.construct("https://ldo.js.org/")
.parse(shexC);
// Convert the content to types
const [typings, context] = await shexjToTypeAndContext(schema);
await Promise.all(
["context", "schema", "shapeTypes", "typings"].map(
async (templateName) => {
const finalContent = await renderFile(
path.join(__dirname, "./templates", `${templateName}.ejs`),
{
typings: typings.typings,
fileName,
schema: JSON.stringify(schema, null, 2),
context: JSON.stringify(context, null, 2),
}
);
// Save conversion to document
await fs.promises.writeFile(
path.join(options.output, `${fileName}.${templateName}.ts`),
await prettier.format(finalContent, { parser: "typescript" })
);
}
)
);
})
);
load.stop();
}

@ -0,0 +1,25 @@
#!/usr/bin/env node
import { program } from "commander";
import { build } from "./build";
import { init } from "./init";
program
.name("LDO-CLI")
.description("CLI to some JavaScript string utilities")
.version("3.0.1");
program
.command("build")
.description("Build a shex folder into Shape Types")
.option("-i, --input <inputPath>", "Provide the input path", "./shapes")
.option("-o, --output <outputPath>", "Provide the output path", "./ldo")
.action(build);
program
.command("init")
.option("-d --directory>", "A parent directory for ldo files")
.description("Initializes a project for ldo")
.action(init);
program.parse();

@ -0,0 +1,78 @@
import { exec } from "child-process-promise";
import fs from "fs-extra";
import path from "path";
import { renderFile } from "ejs";
const DEFAULT_SHAPES_FOLDER = "./shapes";
const DEFAULT_LDO_FOLDER = "./ldo";
const POTENTIAL_PARENT_DIRECTORIES = ["src", "lib", "bin"];
export interface InitOptions {
directory?: string;
}
export async function init(initOptions: InitOptions) {
// Install dependencies
await exec("npm install ldo --save");
await exec("npm install ldo-cli @types/shexj @types/jsonld --save-dev");
// Find folder to save to
let parentDirectory = initOptions.directory;
if (!parentDirectory) {
parentDirectory = "./";
const allDirectories = (
await fs.promises.readdir("./", {
withFileTypes: true,
})
).filter((file) => file.isDirectory());
for (let i = 0; i < POTENTIAL_PARENT_DIRECTORIES.length; i++) {
if (
allDirectories.some(
(dir) => dir.name === POTENTIAL_PARENT_DIRECTORIES[i]
)
) {
parentDirectory = POTENTIAL_PARENT_DIRECTORIES[i];
break;
}
}
}
// Create "shapes" folder
const shapesFolderPath = path.join(parentDirectory, DEFAULT_SHAPES_FOLDER);
await fs.promises.mkdir(shapesFolderPath);
const defaultShapePaths = await fs.promises.readdir(
path.join(__dirname, "./templates/defaultShapes")
);
await Promise.all(
defaultShapePaths.map(async (shapePath) => {
const shapeContent = await renderFile(
path.join(__dirname, "./templates/defaultShapes", shapePath),
{}
);
await fs.promises.writeFile(
path.join(shapesFolderPath, `${path.parse(shapePath).name}.shex`),
shapeContent
);
})
);
// Add build script
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const packageJson: any = JSON.parse(
(await fs.promises.readFile("./package.json")).toString()
);
if (!packageJson.scripts) {
packageJson.scripts = {};
}
const ldoFolder = path.join(parentDirectory, DEFAULT_LDO_FOLDER);
packageJson.scripts[
"build:ldo"
] = `ldo build --input ${shapesFolderPath} --output ${ldoFolder}`;
await fs.promises.writeFile(
"./package.json",
JSON.stringify(packageJson, null, 2)
);
// Build LDO
await exec("npm run build:ldo");
}

@ -0,0 +1,8 @@
import { ContextDefinition } from "jsonld";
/**
* =============================================================================
* <%- fileName %>Context: JSONLD Context for <%- fileName %>
* =============================================================================
*/
export const <%- fileName %>Context: ContextDefinition = <%- context %>;

@ -0,0 +1,19 @@
# This shape is provided by default as an example
# You can create your own shape to fit your needs using ShEx (https://shex.io)
# Also check out https://shaperepo.com for examples of more shapes.
PREFIX ex: <https://example.com/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
ex:FoafProfile EXTRA a {
a [ foaf:Person ]
// rdfs:comment "Defines the node as a Person (from foaf)" ;
foaf:name xsd:string ?
// rdfs:comment "Define a person's name." ;
foaf:img xsd:string ?
// rdfs:comment "Photo link but in string form" ;
foaf:knows @ex:FoafProfile *
// rdfs:comment "A list of WebIds for all the people this user knows." ;
}

@ -0,0 +1,8 @@
import { Schema } from "shexj";
/**
* =============================================================================
* <%- fileName %>Schema: ShexJ Schema for <%- fileName %>
* =============================================================================
*/
export const <%- fileName %>Schema: Schema = <%- schema %>;

@ -0,0 +1,24 @@
import { ShapeType } from "ldo";
import { <%- fileName %>Schema } from "./<%- fileName %>.schema";
import { <%- fileName %>Context } from "./<%- fileName %>.context";
import {
<% typings.forEach((typing) => { -%>
<%- typing.dts.name %>,
<% }); -%>} from "./<%- fileName %>.typings";
/**
* =============================================================================
* LDO ShapeTypes <%- fileName %>
* =============================================================================
*/
<% typings.forEach((typing) => { -%>
/**
* <%- typing.dts.name %> ShapeType
*/
export const <%- typing.dts.name %>ShapeType: ShapeType<<%- typing.dts.name %>> = {
schema: <%- fileName %>Schema,
shape: "<%- typing.dts.shapeId %>",
context: <%- fileName %>Context,
};
<% }); -%>

@ -0,0 +1,14 @@
import { ContextDefinition } from "jsonld";
/**
* =============================================================================
* Typescript Typings for <%- fileName %>
* =============================================================================
*/
<% typings.forEach((typing) => { -%>
/**
* <%- typing.dts.name %> Type
*/
export <%- typing.typingString -%>
<% }); -%>

@ -0,0 +1,3 @@
it("placeholder", () => {
expect(true).toBe(true);
});

@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist"
},
"include": ["./src"]
}

@ -1,10 +1,9 @@
{ {
"name": "@ldo/demo-react", "name": "@ldo/demo-react",
"version": "0.1.0", "version": "0.0.0",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@ldo/solid-react": "^0.0.0", "@ldo/solid-react": "^0.0.0",
"ldo": "^1.0.3",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
@ -13,7 +12,6 @@
"scripts": { "scripts": {
"start": "craco start", "start": "craco start",
"build": "craco build", "build": "craco build",
"test": "craco test",
"eject": "react-scripts eject", "eject": "react-scripts eject",
"lint": "eslint src/** --fix", "lint": "eslint src/** --fix",
"build:ldo": "ldo build --input src/shapes --output src/ldo" "build:ldo": "ldo build --input src/shapes --output src/ldo"
@ -38,9 +36,9 @@
}, },
"devDependencies": { "devDependencies": {
"@craco/craco": "^7.1.0", "@craco/craco": "^7.1.0",
"@ldo/cli": "^0.0.0",
"@types/jsonld": "^1.5.9", "@types/jsonld": "^1.5.9",
"@types/shexj": "^2.1.4", "@types/shexj": "^2.1.4",
"ldo-cli": "^3.0.1",
"tsconfig-paths-webpack-plugin": "^4.1.0" "tsconfig-paths-webpack-plugin": "^4.1.0"
} }
} }

@ -8,12 +8,8 @@
"watch": "tsc --watch", "watch": "tsc --watch",
"test": "jest --coverage", "test": "jest --coverage",
"test:watch": "jest --watch", "test:watch": "jest --watch",
"docs": "typedoc", "prepublishOnly": "npm run test && npm run build",
"prepublishOnly": "npm run test && npm run build && npm run docs", "build:ldo": "ldo build --input src/shapes --output src/ldo"
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build",
"storybook:ldo": "ldo build --input stories/shapes --output stories/ldo",
"build:ldo": "ldo build --input lib/shapes --output lib/ldo"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -29,13 +25,12 @@
"@babel/preset-env": "^7.22.10", "@babel/preset-env": "^7.22.10",
"@babel/preset-react": "^7.22.5", "@babel/preset-react": "^7.22.5",
"@babel/preset-typescript": "^7.22.11", "@babel/preset-typescript": "^7.22.11",
"@ldo/cli": "^0.0.0",
"@rdfjs/types": "^1.1.0", "@rdfjs/types": "^1.1.0",
"@types/jest": "^29.0.3", "@types/jest": "^29.0.3",
"@types/jsonld": "^1.5.8", "@types/jsonld": "^1.5.8",
"@types/n3": "^1.10.4", "@types/n3": "^1.10.4",
"@types/shexj": "^2.1.4", "@types/shexj": "^2.1.4",
"ldo-cli": "^3.0.1",
"prop-types": "^15.8.1",
"ts-jest": "^29.0.2" "ts-jest": "^29.0.2"
}, },
"dependencies": { "dependencies": {

Loading…
Cancel
Save