Untested changes

main
Jackson Morgan 9 months ago
parent 22c476d3ef
commit 2a66bec94b
  1. 113
      package-lock.json
  2. 7
      packages/cli/package.json
  3. 89
      packages/cli/src/create.ts
  4. 75
      packages/cli/src/generateReadme.ts
  5. 2
      packages/cli/src/init.ts
  6. 8
      packages/cli/src/templates/readme/main.ejs
  7. 4
      packages/cli/src/templates/readme/shape.ejs
  8. 15
      packages/cli/src/util/modifyPackageJson.ts

113
package-lock.json generated

@ -8093,6 +8093,32 @@
"@ts-jison/lexer": "^0.4.1-alpha.1"
}
},
"node_modules/@ts-morph/common": {
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.25.0.tgz",
"integrity": "sha512-kMnZz+vGGHi4GoHnLmMhGNjm44kGtKUXGnOvrKmMwAuvNjM/PgKVGfUnL7IDvK7Jb2QQ82jq3Zmp04Gy+r3Dkg==",
"license": "MIT",
"dependencies": {
"minimatch": "^9.0.4",
"path-browserify": "^1.0.1",
"tinyglobby": "^0.2.9"
}
},
"node_modules/@ts-morph/common/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/@tsconfig/node10": {
"version": "1.0.9",
"devOptional": true,
@ -8569,6 +8595,17 @@
"version": "2.7.3",
"license": "MIT"
},
"node_modules/@types/prompts": {
"version": "2.4.9",
"resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.4.9.tgz",
"integrity": "sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*",
"kleur": "^3.0.3"
}
},
"node_modules/@types/prop-types": {
"version": "15.7.11",
"dev": true,
@ -11031,6 +11068,12 @@
"node": ">=4"
}
},
"node_modules/code-block-writer": {
"version": "13.0.3",
"resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz",
"integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==",
"license": "MIT"
},
"node_modules/codepage": {
"version": "1.15.0",
"dev": true,
@ -21261,6 +21304,12 @@
"tslib": "^2.0.3"
}
},
"node_modules/path-browserify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
"integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
"license": "MIT"
},
"node_modules/path-exists": {
"version": "4.0.0",
"license": "MIT",
@ -22759,6 +22808,8 @@
},
"node_modules/prompts": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
"integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
"license": "MIT",
"dependencies": {
"kleur": "^3.0.3",
@ -26605,6 +26656,45 @@
"dev": true,
"license": "MIT"
},
"node_modules/tinyglobby": {
"version": "0.2.10",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.10.tgz",
"integrity": "sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==",
"license": "MIT",
"dependencies": {
"fdir": "^6.4.2",
"picomatch": "^4.0.2"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/tinyglobby/node_modules/fdir": {
"version": "6.4.2",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz",
"integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==",
"license": "MIT",
"peerDependencies": {
"picomatch": "^3 || ^4"
},
"peerDependenciesMeta": {
"picomatch": {
"optional": true
}
}
},
"node_modules/tinyglobby/node_modules/picomatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/tmp": {
"version": "0.2.1",
"dev": true,
@ -26713,6 +26803,16 @@
"version": "0.1.13",
"license": "Apache-2.0"
},
"node_modules/ts-morph": {
"version": "24.0.0",
"resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-24.0.0.tgz",
"integrity": "sha512-2OAOg/Ob5yx9Et7ZX4CvTCc0UFoZHwLEJ+dpDPSUi5TgwwlTlX47w+iFRrEwzUZwYACjq83cgjS/Da50Ga37uw==",
"license": "MIT",
"dependencies": {
"@ts-morph/common": "~0.25.0",
"code-block-writer": "^13.0.3"
}
},
"node_modules/ts-node": {
"version": "10.9.2",
"devOptional": true,
@ -28648,7 +28748,9 @@
"fs-extra": "^10.1.0",
"loading-cli": "^1.1.0",
"prettier": "^3.0.3",
"type-fest": "^4.31.0"
"prompts": "^2.4.2",
"ts-morph": "^24.0.0",
"type-fest": "^2.19.0"
},
"bin": {
"ldo": "dist/index.js"
@ -28658,6 +28760,7 @@
"@types/ejs": "^3.1.1",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^27.0.3",
"@types/prompts": "^2.4.9",
"@types/shexj": "2.1.4",
"copyfiles": "^2.4.1",
"jest": "^27.4.2",
@ -28728,12 +28831,12 @@
}
},
"packages/cli/node_modules/type-fest": {
"version": "4.31.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.31.0.tgz",
"integrity": "sha512-yCxltHW07Nkhv/1F6wWBr8kz+5BGMfP+RbRSYFnegVb0qV/UMT0G0ElBloPVerqn4M2ZV80Ir1FtCcYv1cT6vQ==",
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
"integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
"license": "(MIT OR CC0-1.0)",
"engines": {
"node": ">=16"
"node": ">=12.20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"

@ -21,7 +21,7 @@
"prepublishOnly": "npm run test && npm run build",
"lint": "eslint src/** --fix --no-error-on-unmatched-pattern",
"build:ldo": "./dist/index.js build --input test/.shapes --output test/.ldo",
"generate-readme": "./dist/index.js generate-readme --project ./test --shapes ./test/.shapes/ --ldo ./test/.ldo/"
"generate-readme": "./dist/index.js generate-readme --project ./test --shapes ./test/.shapes/ --ldo ./test/.ldo/"
},
"repository": {
"type": "git",
@ -38,6 +38,7 @@
"@types/ejs": "^3.1.1",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^27.0.3",
"@types/prompts": "^2.4.9",
"@types/shexj": "2.1.4",
"copyfiles": "^2.4.1",
"jest": "^27.4.2",
@ -53,7 +54,9 @@
"fs-extra": "^10.1.0",
"loading-cli": "^1.1.0",
"prettier": "^3.0.3",
"type-fest": "^4.31.0"
"prompts": "^2.4.2",
"ts-morph": "^24.0.0",
"type-fest": "^2.19.0"
},
"files": [
"dist",

@ -1,23 +1,84 @@
import { exec } from "child-process-promise";
import { init } from "./init";
import { modifyPackageJson } from "./util/modifyPackageJson";
import { modifyPackageJson, savePackageJson } from "./util/modifyPackageJson";
import { generateReadme } from "./generateReadme";
import path from "path";
import prompts from "prompts";
import type { PackageJson } from "type-fest";
interface CreateOptions {
directory: string;
name: string;
}
export async function create(options: CreateOptions) {
export async function create(directory: string) {
// Init the NPM Package
await exec(`npm init ${options.directory}`);
const responses = await prompts([
{
type: "text",
name: "name",
message: "Package name:",
initial: path.basename(process.cwd()),
},
{
type: "text",
name: "version",
message: "Version:",
initial: "1.0.0",
},
{
type: "text",
name: "description",
message: "Description:",
},
{
type: "list",
name: "keywords",
message: "Keywords (comma separated):",
separator: ",",
},
{
type: "text",
name: "author",
message: "Author:",
},
{
type: "text",
name: "license",
message: "License:",
initial: "MIT",
},
{
type: "text",
name: "repository",
message: "Git repository (optional):",
},
]);
const packageJson: PackageJson = {
name: responses.name,
version: responses.version,
description: responses.description,
keywords: responses.keywords,
author: responses.author,
license: responses.license,
};
if (responses.repository) {
packageJson.repository = {
type: "git",
url: responses.repository,
};
packageJson.bugs = {
url: `${responses.repository.replace(/\.git$/, "")}/issues`,
};
packageJson.homepage = `${responses.repository.replace(
/\.git$/,
"",
)}#readme`;
}
await savePackageJson(directory, packageJson);
// Init LDO
await init({ directory: options.directory });
await init({ directory });
// Add prepublish script
await modifyPackageJson(async (packageJson) => {
await modifyPackageJson(directory, async (packageJson) => {
if (!packageJson.scripts) packageJson.scripts = {};
packageJson.scripts.prepublish =
"npm run build:ldo & npm run generate-readme";
@ -29,8 +90,8 @@ export async function create(options: CreateOptions) {
// Generate ReadMe
await generateReadme({
readmePath: path.join(options.directory, "README.md"),
shapesPath: path.join(options.directory, ".shapes"),
ldoPath: path.join(options.directory, ".ldo"),
project: directory,
shapes: path.join(directory, ".shapes"),
ldo: path.join(directory, ".ldo"),
});
}

@ -2,11 +2,13 @@ import { getPackageJson } from "./util/modifyPackageJson";
import { forAllShapes } from "./util/forAllShapes";
import { promises as fs } from "fs";
import path from "path";
import { Project } from "ts-morph";
import { renderFile } from "ejs";
interface GenerateReadmeOptions {
projectFolder: string;
shapesPath: string;
ldoPath: string;
project: string;
shapes: string;
ldo: string;
}
interface ReadmeEjsOptions {
@ -24,27 +26,54 @@ interface ReadmeEjsOptions {
}
export async function generateReadme(options: GenerateReadmeOptions) {
const packageJson = await getPackageJson(options.projectFolder);
const projectName = packageJson.name;
const projectDescription = packageJson.description;
const packageJson = await getPackageJson(options.project);
const projectName = packageJson.name!;
const projectDescription = packageJson.description!;
const shapes: ReadmeEjsOptions["shapes"] = [];
await forAllShapes(options.shapesPath, async (fileName, shexC) => {
const typesRaw = await fs.readFile(
path.join(options.shapesPath, `${fileName}.typings.ts`),
"utf8",
);
const shapeTypesRaw = await fs.readFile(
path.join(options.shapesPath, `${fileName}.shapeTypes.ts`),
"utf8",
);
console.log(typesRaw);
console.log(shapeTypesRaw);
// shapes.push({
// name: fileName,
// shex: shexC,
// });
await forAllShapes(options.shapes, async (fileName, shexC) => {
const typeFilePath = path.join(options.shapes, `${fileName}.typings.ts`);
const typesRaw = await fs.readFile(typeFilePath, "utf8");
const shape: ReadmeEjsOptions["shapes"][0] = {
name: fileName,
shex: shexC,
typescript: typesRaw,
types: [],
};
listInterfaces(typeFilePath).forEach((interfaceName) => {
shape.types.push({
typeName: interfaceName,
shapeTypeName: `${interfaceName}ShapeType`,
});
});
});
const readmeEjsOptions: ReadmeEjsOptions = {
projectName,
projectDescription,
shapes,
};
// Save Readme
const finalContent = await renderFile(
path.join(__dirname, "./templates/readme/", "main.ejs"),
readmeEjsOptions,
);
// Save readme to document
await fs.writeFile(path.join(options.project, "README.md"), finalContent);
}
/**
* Helper Function that lists all the interfaces in a typescript file
*/
function listInterfaces(filePath: string): string[] {
const project = new Project();
const sourceFile = project.addSourceFileAtPath(filePath);
// Get all interfaces in the file
const interfaces = sourceFile.getInterfaces().map((iface) => iface.getName());
return interfaces;
}

@ -58,7 +58,7 @@ export async function init(initOptions: InitOptions) {
);
// Add build script
await modifyPackageJson("./", async (packageJson) => {
await modifyPackageJson(parentDirectory, async (packageJson) => {
if (!packageJson.scripts) {
packageJson.scripts = {};
}

@ -1,15 +1,15 @@
# <%= projectname %>
# <%= projectName %>
<%= projectDescrition %>
<%- projectDescription %>
This project includes shapes and generated files for [LDO](https://ldo.js.org).
## Installation
```bash
npm i <%= projectname %>
npm i <%= projectName %>
```
<% shapes.forEach(function(shape) { %>
<%- include('shape', { shape: shape, projectname: projectname }) %>
<%- include('shape', { shape: shape, projectName: projectName }) %>
<% }); %>

@ -4,8 +4,8 @@
```typescript
import { createLdoDataset } from "@ldo/ldo";
import { <%= shape.types.map((type) => type.shapeTypeName).join(", ") %> } from "<%= projectName =>";
import type { <%= shape.types.map((type) => type.typeName).join(", ") %> } from "<%= projectName =>";
import { <%= shape.types.map((type) => type.shapeTypeName).join(", ") %> } from "<%= projectName %>";
import type { <%= shape.types.map((type) => type.typeName).join(", ") %> } from "<%= projectName %>";
const ldoDataset = createLdoDataset();
<% shape.types.forEach(function(type, index) { %>
const example<%= index %>: <%= type.typeName %> = ldoDataset

@ -12,14 +12,21 @@ export async function getPackageJson(
);
}
export async function savePackageJson(
projectFolder: string,
packageJson: PackageJson,
): Promise<void> {
await fs.promises.writeFile(
path.join(projectFolder, "./package.json"),
JSON.stringify(packageJson, null, 2),
);
}
export async function modifyPackageJson(
projectFolder: string,
modifyCallback: (packageJson: PackageJson) => Promise<PackageJson>,
): Promise<void> {
const packageJson: PackageJson = await getPackageJson(projectFolder);
const newPackageJson = await modifyCallback(packageJson);
await fs.promises.writeFile(
path.join(projectFolder, "./package.json"),
JSON.stringify(newPackageJson, null, 2),
);
await savePackageJson(projectFolder, newPackageJson);
}

Loading…
Cancel
Save