From aac22df1c3fdde17c0e918e59c7d7569f03edcd3 Mon Sep 17 00:00:00 2001 From: Damian Reeves <957246+DamianReeves@users.noreply.github.com> Date: Wed, 22 May 2024 07:38:09 -0400 Subject: [PATCH] Improve how the Morphir CLI handles dependencies and add "includes" to allow providing dependencies at the command line (#1165) * Working on dependencies * Add support for Data Urls as dependencies and includes * Adding support for loading file Urls * Added proper file URL support * Ensure we can download from an http url * Handle loading http dependencies * Restore functionality for loading dataUrl --- cli2/cli.ts | 18 +- cli2/dependencies.ts | 241 +++++++++++++++++++++++- cli2/morphir-make.ts | 1 + package-lock.json | 439 +++++++++++++++++++++++++++++++++++++++---- package.json | 10 +- 5 files changed, 664 insertions(+), 45 deletions(-) diff --git a/cli2/cli.ts b/cli2/cli.ts index 78533df97..f72da204c 100644 --- a/cli2/cli.ts +++ b/cli2/cli.ts @@ -5,6 +5,8 @@ import * as util from "util"; import * as path from "path"; import * as FileChanges from "./FileChanges"; import * as Dependencies from "./dependencies"; +import { DependencyConfig } from "./dependencies"; +import { z } from "zod"; const fsExists = util.promisify(fs.exists); const fsWriteFile = util.promisify(fs.writeFile); @@ -14,9 +16,13 @@ const readdir = util.promisify(fs.readdir); const worker = require("./../Morphir.Elm.CLI").Elm.Morphir.Elm.CLI.init(); +const Includes = z.array(z.string()).optional(); +type Includes = z.infer; + interface MorphirJson { name: string; sourceDirectory: string; + dependencies?: string[]; localDependencies?: string[]; exposedModules: string[]; } @@ -30,15 +36,21 @@ async function make( const hashFilePath: string = path.join(projectDir, "morphir-hashes.json"); const morphirIrPath: string = path.join(projectDir, "morphir-ir.json"); + // Load the `morphir.json` file that describes the project const morphirJson: MorphirJson = JSON.parse( (await fsReadFile(morphirJsonPath)).toString() ); + const includes = Includes.parse(options.include); + const dependencyConfig = DependencyConfig.parse({ + dependencies: morphirJson.dependencies, + localDependencies: morphirJson.localDependencies, + includes: includes + }) + //load List Of Dependency IR - const dependencies = await Dependencies.getDependecies( - morphirJson.localDependencies ?? [] - ); + const dependencies = await Dependencies.loadAllDependencies(dependencyConfig); // check the status of the build incremental flag if (options.buildIncrementally == false) { diff --git a/cli2/dependencies.ts b/cli2/dependencies.ts index e1820ee3e..5b4acedcf 100644 --- a/cli2/dependencies.ts +++ b/cli2/dependencies.ts @@ -1,17 +1,240 @@ import * as util from "util"; import * as fs from "fs"; +import { z } from "zod"; +import { getUri } from "get-uri"; +import { decode, labelToName } from "whatwg-encoding"; +import { Readable } from "stream"; +import { ResultAsync } from "neverthrow"; + +const parseDataUrl = require("data-urls"); const fsReadFile = util.promisify(fs.readFile); -export async function getDependecies( - localDependencies: string[] -): Promise { - const loadedDependencies = localDependencies.map(async (dependencyPath) => { - if (fs.existsSync(dependencyPath)) { - const dependencyIR = (await fsReadFile(dependencyPath)).toString(); - return JSON.parse(dependencyIR); +const DataUrl = z.string().trim().transform((val, ctx) => { + const parsed = parseDataUrl(val) + if (parsed == null) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: "Not a valid data url" + }) + return z.NEVER; + } + return parsed; +}); + +const FileUrl = z.string().trim().url().transform((val, ctx) => { + if (!val.startsWith("file:")) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: "Not a valid file url" + }) + return z.NEVER; + } + return new URL(val); +}); + +const Url = z.string().url().transform((url) => new URL(url)); + +const PathOrUrl = z.union([FileUrl, z.string().trim().min(1)]); + +const GithubData = z.object({ + owner: z.string(), + repo: z.string(), + baseUrl: z.string().optional() +}); + +const GithubConfig = z.union([GithubData, z.string()]); + +const DependencySettings = z.union([DataUrl, FileUrl, z.string().trim()]) +const Dependencies = z.array(DependencySettings).default([]); + +export const DependencyConfig = z.object({ + dependencies: Dependencies, + localDependencies: z.array(z.string()).default([]), + includes: z.array(z.string()).default([]), +}); + +const IncludeProvided = z.object({ + eventKind: z.literal('IncludeProvided'), + payload: z.string() +}); + +const LocalDependencyProvided = z.object({ + eventKind: z.literal('LocalDependencyProvided'), + payload: z.string() +}) + +const DependencyProvided = z.object({ + eventKind: z.literal('DependencyProvided'), + payload: DependencySettings +}); + +const DependencyEvent = z.discriminatedUnion("eventKind", [ + IncludeProvided, + LocalDependencyProvided, + DependencyProvided +]); + +const DependencyEvents = z.array(DependencyEvent); + +const DependencyConfigToDependencyEvents = DependencyConfig.transform((config) => { + let events = DependencyEvents.parse([]); + const includes = config.includes.map((include) => IncludeProvided.parse({ eventKind: "IncludeProvided", payload: include })); + events.push(...includes); + const localDeps = config.localDependencies.map((localDependency) => LocalDependencyProvided.parse({ eventKind: "LocalDependencyProvided", payload: localDependency })); + events.push(...localDeps); + const deps = config.dependencies.map((dep) => DependencyProvided.parse({ eventKind: "DependencyProvided", payload: dep })); + events.push(...deps); + return events; +}); + + +const MorphirDistribution = z.tuple([z.string()]).rest(z.unknown()); +const MorphirIRFile = z.object({ + formatVersion: z.number().int(), + distribution: MorphirDistribution +}).passthrough(); + +type DataUrl = z.infer; +type FileUrl = z.infer; +type Url = z.infer; +type DependencyConfigToDependencyEvents = z.infer +type PathOrUrl = z.infer; +type GithubData = z.infer; +type GithubConfig = z.infer; +type DependencyEvent = z.infer; +type MorphirDistribution = z.infer; +type MorphirIRFile = z.infer; +export type DependencyConfig = z.infer; + +export async function loadAllDependencies(config: DependencyConfig) { + const events = DependencyConfigToDependencyEvents.parse(config); + const results = events.map(load); + const finalResults = await Promise.all(results); + return finalResults.flatMap((result) => { + if (result.isOk()) { + console.error("Successfully loaded dependency", result.value.dependency) + return result.value.dependency; } else { - throw new Error(`${dependencyPath} does not exist`); + console.error("Error loading dependency", result.error); + return []; } }); - return Promise.all(loadedDependencies); } + +function load(event: DependencyEvent) { + console.error("Loading event", event); + let source: "dependencies" | "localDependencies" | "includes"; + let payload = event.payload; + switch (event.eventKind) { + case 'IncludeProvided': + source = "includes"; + return loadDependenciesFromString(event.payload, source) + .map((dependency) => ({ dependency: dependency, source: source, payload: payload })); + case 'LocalDependencyProvided': + source = "localDependencies"; + return loadDependenciesFromString(event.payload, source) + .map((dependency) => ({ dependency: dependency, source: source, payload: payload })); + case 'DependencyProvided': + source = "dependencies"; + if (typeof payload === "string") { + return loadDependenciesFromString(payload, source) + .map((dependency) => ({ dependency: dependency, source: source, payload: payload })); + } else { + return loadDependenciesFromURL(payload, source) + .map((dependency) => ({ dependency: dependency, source: source, payload: payload })); + } + } +} + +function loadDependenciesFromString(input: string, source: string) { + const doWork = async () => { + let sanitized = input.trim(); + let { success, data } = DataUrl.safeParse(sanitized); + if (success) { + console.error("Loading Data url", data); + const encodingName = labelToName(data.mimeType.parameters.get("charset") || "utf-8") || "UTF-8"; + const bodyDecoded = decode(data.body, encodingName); + console.error("Data from data url", bodyDecoded); + return JSON.parse(bodyDecoded); + } + let { success: fileSuccess, data: fileData } = FileUrl.safeParse(sanitized); + if (fileSuccess && fileData !== undefined) { + console.error("Loading file url", fileData); + const data = await getUri(fileData); + const buffer = await toBuffer(data); + const jsonString = buffer.toString(); + return JSON.parse(jsonString); + } + let { success: urlSuccess, data: urlData } = Url.safeParse(sanitized); + if (urlSuccess && urlData !== undefined) { + console.error("Loading url", urlData); + if (urlData.protocol.startsWith("http") || urlData.protocol.startsWith("ftp")) { + console.error("Loading http or ftp url", urlData); + const data = await getUri(urlData); + const buffer = await toBuffer(data); + const jsonString = buffer.toString(); + return JSON.parse(jsonString); + } + } + throw new DependencyError("Invalid dependency string", input); + } + return ResultAsync.fromPromise(doWork(), (err) => new DependencyError("Error loading dependency", source, input, err)); +} + +function loadDependenciesFromURL(url: URL | Url, source: string) { + const doWork = async () => { + const data = await getUri(url); + const buffer = await toBuffer(data); + const jsonString = buffer.toString(); + return JSON.parse(jsonString); + } + return ResultAsync.fromPromise(doWork(), (err) => new DependencyError("Error loading dependency", source, url, err)); +} + +async function toBuffer(stream: Readable): Promise { + const chunks: Buffer[] = []; + for await (const chunk of stream) { + chunks.push(chunk); + } + return Buffer.concat(chunks); +} + +class DependencyError extends Error { + constructor(message: string, source?: string, dependency?: string | FileUrl | DataUrl | URL, cause?: Error | unknown) { + super(message); + this.name = "DependencyError"; + if (cause) { + this.cause = cause; + } + if (dependency) { + this.dependency = dependency; + } + if (source) { + this.source = source; + } + } + cause?: Error | unknown; + dependency?: string | FileUrl | DataUrl | URL; + source?: string; +} + +class LocalDependencyNotFound extends Error { + constructor(message: string, source?: string, pathOrUrl?: PathOrUrl, cause?: Error | unknown) { + super(message); + this.name = "LocalDependencyNotFound"; + if (cause) { + this.cause = cause; + } + if (pathOrUrl) { + this.pathOrUrl = pathOrUrl; + } + if (source) { + this.source = source; + } + } + + cause?: Error | unknown; + pathOrUrl?: PathOrUrl; + source?: string; + +} \ No newline at end of file diff --git a/cli2/morphir-make.ts b/cli2/morphir-make.ts index 0ac649a64..bbb062bd7 100644 --- a/cli2/morphir-make.ts +++ b/cli2/morphir-make.ts @@ -16,6 +16,7 @@ program .option('-o, --output ', 'Target file location where the Morphir IR will be saved.', 'morphir-ir.json') .option('-t, --types-only', 'Only include type information in the IR, no values.', false) .option('-i, --indent-json', 'Use indentation in the generated JSON file.', false) + .option("-I, --include [pathOrUrl...]", "Include additional Morphir distributions as a dependency. Can be specified multiple times. Can be a path, url, or data-url.") .parse(process.argv) const dirAndOutput = program.opts() diff --git a/package-lock.json b/package-lock.json index 9083643b0..98d0d31d1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,13 +14,19 @@ "chalk": "^4.1.1", "commander": "^9.0.0", "cookie-parser": "^1.4.6", + "data-urls": "^5.0.0", "express": "^4.19.2", "fs-extra": "^9.1.0", "get-stdin": "^8.0.0", + "get-uri": "^6.0.3", "inquirer": "^8.0.0", "log-timestamp": "^0.3.0", + "neverthrow": "^6.2.1", + "packageurl-js": "^1.2.1", "prettier": "^2.4.1", - "vis-network": "^9.1.2" + "vis-network": "^9.1.2", + "whatwg-encoding": "^3.1.1", + "zod": "^3.23.8" }, "bin": { "morphir": "cli2/lib/morphir.js", @@ -29,9 +35,11 @@ }, "devDependencies": { "@morphir/typespec-sdk": "file:redistributable/TypeSpec/sdk", + "@types/data-urls": "^3.0.4", "@types/inquirer": "^9.0.3", "@types/jest": "^27.4.0", "@types/mocha": "^9.0.0", + "@types/whatwg-encoding": "^2.0.3", "@typespec/compiler": "^0.42.0", "@vercel/ncc": "^0.38.1", "del-cli": "3.0.1", @@ -1520,6 +1528,16 @@ "@babel/types": "^7.3.0" } }, + "node_modules/@types/data-urls": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/data-urls/-/data-urls-3.0.4.tgz", + "integrity": "sha512-XRY2WVaOFSTKpNMaplqY1unPgAGk/DosOJ+eFrB6LJcFFbRH3nVbwJuGqLmDwdTWWx+V7U614/kmrj1JmCDl2A==", + "dev": true, + "dependencies": { + "@types/whatwg-mimetype": "*", + "@types/whatwg-url": "*" + } + }, "node_modules/@types/glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", @@ -1640,6 +1658,33 @@ "@types/node": "*" } }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", + "dev": true + }, + "node_modules/@types/whatwg-encoding": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/whatwg-encoding/-/whatwg-encoding-2.0.3.tgz", + "integrity": "sha512-7TJfeaSFIWAKQ4ZynOb5zV3xzJQEEmL0U0j+uH7tnqfL97apXDTwMo0dB2uAWXAbr2dRRi5/eO9jV9dK/1GkiA==", + "dev": true + }, + "node_modules/@types/whatwg-mimetype": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/whatwg-mimetype/-/whatwg-mimetype-3.0.2.tgz", + "integrity": "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==", + "dev": true + }, + "node_modules/@types/whatwg-url": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", + "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", + "dev": true, + "dependencies": { + "@types/webidl-conversions": "*" + } + }, "node_modules/@types/yargs": { "version": "16.0.4", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", @@ -2561,6 +2606,14 @@ "node": ">=0.10.0" } }, + "node_modules/basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", @@ -3487,17 +3540,54 @@ } }, "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" + } + }, + "node_modules/data-urls/node_modules/tr46": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/data-urls/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/data-urls/node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "engines": { + "node": ">=18" + } + }, + "node_modules/data-urls/node_modules/whatwg-url": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", + "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", + "dependencies": { + "tr46": "^5.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" } }, "node_modules/debug": { @@ -5104,6 +5194,62 @@ "node": ">=6" } }, + "node_modules/get-uri": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", + "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4", + "fs-extra": "^11.2.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/get-uri/node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/get-uri/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/get-uri/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/get-uri/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -6332,6 +6478,15 @@ "node": ">=10" } }, + "node_modules/html-encoding-sniffer/node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "dependencies": { + "iconv-lite": "0.4.24" + } + }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -7879,6 +8034,20 @@ } } }, + "node_modules/jsdom/node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/jsdom/node_modules/form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -7893,6 +8062,15 @@ "node": ">= 6" } }, + "node_modules/jsdom/node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "dependencies": { + "iconv-lite": "0.4.24" + } + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -9075,6 +9253,12 @@ "node": ">= 0.6" } }, + "node_modules/neverthrow": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/neverthrow/-/neverthrow-6.2.1.tgz", + "integrity": "sha512-amlnNvPXmiUOmNsDfUngNWPdZYOmCUGExQy/kuPCmLbhrXVXIYhY4bnE4D3dWl7OMhSEr9NndUrl4aKGFhFIQg==", + "license": "MIT" + }, "node_modules/next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", @@ -9639,6 +9823,11 @@ "semver": "bin/semver.js" } }, + "node_modules/packageurl-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/packageurl-js/-/packageurl-js-1.2.1.tgz", + "integrity": "sha512-cZ6/MzuXaoFd16/k0WnwtI298UCaDHe/XlSh85SeOKbGZ1hq0xvNbx3ILyCMyk7uFQxl6scF3Aucj6/EO9NwcA==" + }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -10072,9 +10261,9 @@ } }, "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "engines": { "node": ">=6" } @@ -12543,12 +12732,25 @@ } }, "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", "dependencies": { - "iconv-lite": "0.4.24" + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, "node_modules/whatwg-mimetype": { @@ -12908,6 +13110,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "redistributable/TypeSpec/sdk": { "name": "@morphir/typespec-sdk", "version": "0.2.0", @@ -14037,6 +14247,16 @@ "@babel/types": "^7.3.0" } }, + "@types/data-urls": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/data-urls/-/data-urls-3.0.4.tgz", + "integrity": "sha512-XRY2WVaOFSTKpNMaplqY1unPgAGk/DosOJ+eFrB6LJcFFbRH3nVbwJuGqLmDwdTWWx+V7U614/kmrj1JmCDl2A==", + "dev": true, + "requires": { + "@types/whatwg-mimetype": "*", + "@types/whatwg-url": "*" + } + }, "@types/glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", @@ -14157,6 +14377,33 @@ "@types/node": "*" } }, + "@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", + "dev": true + }, + "@types/whatwg-encoding": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/whatwg-encoding/-/whatwg-encoding-2.0.3.tgz", + "integrity": "sha512-7TJfeaSFIWAKQ4ZynOb5zV3xzJQEEmL0U0j+uH7tnqfL97apXDTwMo0dB2uAWXAbr2dRRi5/eO9jV9dK/1GkiA==", + "dev": true + }, + "@types/whatwg-mimetype": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/whatwg-mimetype/-/whatwg-mimetype-3.0.2.tgz", + "integrity": "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==", + "dev": true + }, + "@types/whatwg-url": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", + "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", + "dev": true, + "requires": { + "@types/webidl-conversions": "*" + } + }, "@types/yargs": { "version": "16.0.4", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", @@ -14845,6 +15092,11 @@ } } }, + "basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==" + }, "batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", @@ -15607,14 +15859,41 @@ "dev": true }, "data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", "requires": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "dependencies": { + "tr46": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "requires": { + "punycode": "^2.3.1" + } + }, + "webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" + }, + "whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==" + }, + "whatwg-url": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", + "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", + "requires": { + "tr46": "^5.0.0", + "webidl-conversions": "^7.0.0" + } + } } }, "debug": { @@ -16882,6 +17161,47 @@ "pump": "^3.0.0" } }, + "get-uri": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", + "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", + "requires": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4", + "fs-extra": "^11.2.0" + }, + "dependencies": { + "data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==" + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -17854,6 +18174,17 @@ "dev": true, "requires": { "whatwg-encoding": "^1.0.5" + }, + "dependencies": { + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + } + } } }, "html-escaper": { @@ -19053,6 +19384,17 @@ "xml-name-validator": "^3.0.0" }, "dependencies": { + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, "form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -19063,6 +19405,15 @@ "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + } } } }, @@ -19979,6 +20330,11 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, + "neverthrow": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/neverthrow/-/neverthrow-6.2.1.tgz", + "integrity": "sha512-amlnNvPXmiUOmNsDfUngNWPdZYOmCUGExQy/kuPCmLbhrXVXIYhY4bnE4D3dWl7OMhSEr9NndUrl4aKGFhFIQg==" + }, "next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", @@ -20413,6 +20769,11 @@ } } }, + "packageurl-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/packageurl-js/-/packageurl-js-1.2.1.tgz", + "integrity": "sha512-cZ6/MzuXaoFd16/k0WnwtI298UCaDHe/XlSh85SeOKbGZ1hq0xvNbx3ILyCMyk7uFQxl6scF3Aucj6/EO9NwcA==" + }, "pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -20742,9 +21103,9 @@ } }, "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==" }, "qs": { "version": "6.11.0", @@ -22668,12 +23029,21 @@ "dev": true }, "whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", "requires": { - "iconv-lite": "0.4.24" + "iconv-lite": "0.6.3" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } } }, "whatwg-mimetype": { @@ -22937,6 +23307,11 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true + }, + "zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==" } } } diff --git a/package.json b/package.json index ad7c37dac..2237a7070 100644 --- a/package.json +++ b/package.json @@ -66,9 +66,11 @@ "homepage": "https://github.com/Morgan-Stanley/morphir-elm#readme", "devDependencies": { "@morphir/typespec-sdk": "file:redistributable/TypeSpec/sdk", + "@types/data-urls": "^3.0.4", "@types/inquirer": "^9.0.3", "@types/jest": "^27.4.0", "@types/mocha": "^9.0.0", + "@types/whatwg-encoding": "^2.0.3", "@typespec/compiler": "^0.42.0", "@vercel/ncc": "^0.38.1", "del-cli": "3.0.1", @@ -100,12 +102,18 @@ "chalk": "^4.1.1", "commander": "^9.0.0", "cookie-parser": "^1.4.6", + "data-urls": "^5.0.0", "express": "^4.19.2", "fs-extra": "^9.1.0", "get-stdin": "^8.0.0", + "get-uri": "^6.0.3", "inquirer": "^8.0.0", "log-timestamp": "^0.3.0", + "neverthrow": "^6.2.1", + "packageurl-js": "^1.2.1", "prettier": "^2.4.1", - "vis-network": "^9.1.2" + "vis-network": "^9.1.2", + "whatwg-encoding": "^3.1.1", + "zod": "^3.23.8" } }