v3: cli and misc fixes for windows (#1027)

* fix: otlp-importer script

* update pluginPath

* Refactor script to ensure compatibility with both Windows and Unix platforms

* Revert command changes

* Fix: Init command was failing on Windows because of bad template paths

* Removed resolveInternalFilePath

* Path fixes for the dev command

* Fix for the import paths being wrong on Windows because the contain backslashes

* The metaOutputKey should have forward slashes in it

* Print the banner immediately, otherwise with bad internet you get a blank console for a long time

* Try normalizing the trigger.config import path

* Allow tsx and jsx files

* Improved task file names and paths

* Removed closing bracket for the upgrade message

* Log out the metafile outputs for debugging

* Log out the entryPointContents before esbuild

* Log the metafile out

* ballmerize the cli

* replace npm-watch with plain old nodemon

* fix text inputs on windows

* changeset

---------

Co-authored-by: Kritik Jiyaviya <kritikjiyaviya07@gmail.com>
Co-authored-by: Matt Aitken <matt@mattaitken.com>
This commit is contained in:
nicktrn
2024-04-12 18:12:01 +01:00
committed by GitHub
parent b82a07ad1c
commit d3a18fbdf6
23 changed files with 194 additions and 127 deletions
+6
View File
@@ -0,0 +1,6 @@
---
"@trigger.dev/otlp-importer": patch
"trigger.dev": patch
---
Fix package builds and CLI commands on Windows
+5
View File
@@ -0,0 +1,5 @@
---
"trigger.dev": patch
---
Init command was failing on Windows because of bad template paths
+2 -5
View File
@@ -45,8 +45,8 @@
"@types/semver": "^7.3.13",
"@types/ws": "^8.5.3",
"cpy-cli": "^5.0.0",
"nodemon": "^3.0.1",
"npm-run-all": "^4.1.5",
"npm-watch": "^0.11.0",
"open": "^10.0.3",
"p-retry": "^6.1.0",
"rimraf": "^3.0.2",
@@ -56,9 +56,6 @@
"vitest": "^0.34.4",
"xdg-app-paths": "^8.3.0"
},
"watch": {
"build:prod-containerfile": "src/Containerfile.prod"
},
"scripts": {
"typecheck": "tsc -p tsconfig.check.json",
"build": "npm run clean && run-p build:**",
@@ -68,7 +65,7 @@
"dev": "npm run clean && run-p dev:**",
"dev:main": "tsup --watch",
"dev:workers": "tsup --config tsup.workers.config.ts --watch",
"dev:prod-containerfile": "npm-watch",
"dev:test": "nodemon -w src/Containerfile.prod -x npm run build:prod-containerfile",
"clean": "rimraf dist",
"start": "node dist/index.js",
"test": "vitest"
+18 -21
View File
@@ -1,4 +1,4 @@
import { intro, log, outro, spinner } from "@clack/prompts";
import { intro, log, outro } from "@clack/prompts";
import { depot } from "@depot/cli";
import { context, trace } from "@opentelemetry/api";
import {
@@ -12,11 +12,10 @@ import chalk from "chalk";
import { Command, Option as CommandOption } from "commander";
import { Metafile, build } from "esbuild";
import { execa } from "execa";
import { resolve as importResolve } from "import-meta-resolve";
import { createHash } from "node:crypto";
import { readFileSync } from "node:fs";
import { copyFile, mkdir, readFile, writeFile } from "node:fs/promises";
import { dirname, join, relative } from "node:path";
import { dirname, join, relative, posix } from "node:path";
import { setTimeout } from "node:timers/promises";
import terminalLink from "terminal-link";
import invariant from "tiny-invariant";
@@ -56,6 +55,8 @@ import {
} from "../utilities/deployErrors";
import { safeJsonParse } from "../utilities/safeJsonParse";
import { JavascriptProject } from "../utilities/javascriptProject";
import { cliRootPath } from "../utilities/resolveInternalFilePath";
import { escapeImportPath, spinner } from "../utilities/windows";
const DeployCommandOptions = CommonCommandOptions.extend({
skipTypecheck: z.boolean().default(false),
@@ -939,27 +940,27 @@ async function compileProject(
const taskFiles = await gatherTaskFiles(config);
const workerFacade = readFileSync(
new URL(importResolve("./workers/prod/worker-facade.js", import.meta.url)).href.replace(
"file://",
""
),
join(cliRootPath(), "workers", "prod", "worker-facade.js"),
"utf-8"
);
const workerSetupPath = new URL(
importResolve("./workers/prod/worker-setup.js", import.meta.url)
).href.replace("file://", "");
const workerSetupPath = join(cliRootPath(), "workers", "dev", "worker-setup.js");
let workerContents = workerFacade
.replace("__TASKS__", createTaskFileImports(taskFiles))
.replace("__WORKER_SETUP__", `import { tracingSDK } from "${workerSetupPath}";`);
.replace(
"__WORKER_SETUP__",
`import { tracingSDK } from "${escapeImportPath(workerSetupPath)}";`
);
if (configPath) {
logger.debug("Importing project config from", { configPath });
workerContents = workerContents.replace(
"__IMPORTED_PROJECT_CONFIG__",
`import * as importedConfigExports from "${configPath}"; const importedConfig = importedConfigExports.config; const handleError = importedConfigExports.handleError;`
`import * as importedConfigExports from "${escapeImportPath(
configPath
)}"; const importedConfig = importedConfigExports.config; const handleError = importedConfigExports.handleError;`
);
} else {
workerContents = workerContents.replace(
@@ -1015,10 +1016,7 @@ async function compileProject(
}
const entryPointContents = readFileSync(
new URL(importResolve("./workers/prod/entry-point.js", import.meta.url)).href.replace(
"file://",
""
),
join(cliRootPath(), "workers", "prod", "entry-point.js"),
"utf-8"
);
@@ -1076,12 +1074,13 @@ async function compileProject(
logger.debug(`Writing compiled files to ${tempDir}`);
// Get the metaOutput for the result build
const metaOutput = result.metafile!.outputs[join("out", "stdin.js")];
const metaOutput = result.metafile!.outputs[posix.join("out", "stdin.js")];
invariant(metaOutput, "Meta output for the result build is missing");
// Get the metaOutput for the entryPoint build
const entryPointMetaOutput = entryPointResult.metafile!.outputs[join("out", "stdin.js")];
const entryPointMetaOutput =
entryPointResult.metafile!.outputs[posix.join("out", "stdin.js")];
invariant(entryPointMetaOutput, "Meta output for the entryPoint build is missing");
@@ -1156,9 +1155,7 @@ async function compileProject(
}
// Write the Containerfile to /tmp/dir/Containerfile
const containerFilePath = new URL(
importResolve("./Containerfile.prod", import.meta.url)
).href.replace("file://", "");
const containerFilePath = join(cliRootPath(), "Containerfile.prod");
// Copy the Containerfile to /tmp/dir/Containerfile
await copyFile(containerFilePath, join(tempDir, "Containerfile"));
+19 -15
View File
@@ -11,12 +11,11 @@ import {
import { watch } from "chokidar";
import { Command } from "commander";
import { BuildContext, Metafile, context } from "esbuild";
import { resolve as importResolve } from "import-meta-resolve";
import { render, useInput } from "ink";
import { createHash } from "node:crypto";
import fs, { readFileSync } from "node:fs";
import { ClientRequestArgs } from "node:http";
import { basename, dirname, join } from "node:path";
import { basename, dirname, join, normalize } from "node:path";
import pDebounce from "p-debounce";
import { WebSocket } from "partysocket";
import React, { Suspense, useEffect } from "react";
@@ -52,6 +51,8 @@ import {
parseNpmInstallError,
} from "../utilities/deployErrors";
import { findUp, pathExists } from "find-up";
import { cliRootPath } from "../utilities/resolveInternalFilePath";
import { escapeImportPath } from "../utilities/windows";
let apiClient: CliApiClient | undefined;
@@ -338,28 +339,27 @@ function useDev({
const taskFiles = await gatherTaskFiles(config);
const workerFacade = readFileSync(
new URL(importResolve("./workers/dev/worker-facade.js", import.meta.url)).href.replace(
"file://",
""
),
"utf-8"
);
const workerFacadePath = join(cliRootPath(), "workers", "dev", "worker-facade.js");
const workerFacade = readFileSync(workerFacadePath, "utf-8");
const workerSetupPath = new URL(
importResolve("./workers/dev/worker-setup.js", import.meta.url)
).href.replace("file://", "");
const workerSetupPath = join(cliRootPath(), "workers", "dev", "worker-setup.js");
let entryPointContents = workerFacade
.replace("__TASKS__", createTaskFileImports(taskFiles))
.replace("__WORKER_SETUP__", `import { tracingSDK, sender } from "${workerSetupPath}";`);
.replace(
"__WORKER_SETUP__",
`import { tracingSDK, sender } from "${escapeImportPath(workerSetupPath)}";`
);
if (configPath) {
configPath = normalize(configPath);
logger.debug("Importing project config from", { configPath });
entryPointContents = entryPointContents.replace(
"__IMPORTED_PROJECT_CONFIG__",
`import * as importedConfigExports from "${configPath}"; const importedConfig = importedConfigExports.config; const handleError = importedConfigExports.handleError;`
`import * as importedConfigExports from "${escapeImportPath(
configPath
)}"; const importedConfig = importedConfigExports.config; const handleError = importedConfigExports.handleError;`
);
} else {
entryPointContents = entryPointContents.replace(
@@ -414,7 +414,11 @@ function useDev({
logger.log(chalkGrey("○ Building background worker…"));
}
const metaOutputKey = join("out", `stdin.js`);
const metaOutputKey = join("out", `stdin.js`).replace(/\\/g, "/");
logger.debug("Metafile", {
metafileOutputs: JSON.stringify(result.metafile?.outputs),
});
const metaOutput = result.metafile!.outputs[metaOutputKey];
+9 -6
View File
@@ -1,4 +1,4 @@
import { intro, isCancel, log, outro, select, spinner, text } from "@clack/prompts";
import { intro, isCancel, log, outro, select, text } from "@clack/prompts";
import { context, trace } from "@opentelemetry/api";
import {
GetProjectResponseBody,
@@ -30,8 +30,9 @@ import { createFile, pathExists, readFile } from "../utilities/fileSystem";
import { getUserPackageManager } from "../utilities/getUserPackageManager";
import { printStandloneInitialBanner } from "../utilities/initialBanner.js";
import { logger } from "../utilities/logger";
import { resolveInternalFilePath } from "../utilities/resolveInternalFilePath";
import { cliRootPath } from "../utilities/resolveInternalFilePath";
import { login } from "./login";
import { spinner } from "../utilities/windows";
const InitCommandOptions = CommonCommandOptions.extend({
projectRef: z.string().optional(),
@@ -185,7 +186,7 @@ async function _initCommand(dir: string, options: InitCommandOptions) {
async function createTriggerDir(dir: string, options: InitCommandOptions) {
return await tracer.startActiveSpan("createTriggerDir", async (span) => {
try {
const defaultValue = `${dir}/src/trigger`;
const defaultValue = join(dir, "src", "trigger");
const location = await text({
message: "Where would you like to create the Trigger.dev directory?",
@@ -199,6 +200,8 @@ async function createTriggerDir(dir: string, options: InitCommandOptions) {
const triggerDir = resolve(process.cwd(), location);
logger.debug({ triggerDir });
span.setAttributes({
"cli.triggerDir": triggerDir,
});
@@ -239,11 +242,11 @@ async function createTriggerDir(dir: string, options: InitCommandOptions) {
return { location, isCustomValue: location !== defaultValue };
}
const exampleFile = resolveInternalFilePath(`./templates/examples/${example}.ts.template`);
const templatePath = join(cliRootPath(), "templates", "examples", `${example}.ts.template`);
const outputPath = join(triggerDir, "example.ts");
await createFileFromTemplate({
templatePath: exampleFile,
templatePath,
outputPath,
replacements: {},
});
@@ -440,7 +443,7 @@ async function writeConfigFile(
spnnr.start("Creating config file");
const projectDir = resolve(process.cwd(), dir);
const templatePath = resolveInternalFilePath("./templates/trigger.config.ts.template");
const templatePath = join(cliRootPath(), "templates", "trigger.config.ts.template");
const outputPath = join(projectDir, "trigger.config.ts");
span.setAttributes({
+2 -1
View File
@@ -1,4 +1,4 @@
import { intro, log, outro, select, spinner } from "@clack/prompts";
import { intro, log, outro, select } from "@clack/prompts";
import { recordSpanException } from "@trigger.dev/core/v3";
import { Command } from "commander";
import open from "open";
@@ -20,6 +20,7 @@ import { printInitialBanner } from "../utilities/initialBanner.js";
import { LoginResult } from "../utilities/session.js";
import { whoAmI } from "./whoami.js";
import { logger } from "../utilities/logger.js";
import { spinner } from "../utilities/windows.js";
export const LoginCommandOptions = CommonCommandOptions.extend({
apiUrl: z.string(),
+2 -1
View File
@@ -1,10 +1,11 @@
import { confirm, spinner } from "@clack/prompts";
import { confirm } from "@clack/prompts";
import { RunOptions, run } from "npm-check-updates";
import path from "path";
import { z } from "zod";
import { chalkError, chalkSuccess } from "../utilities/cliOutput.js";
import { readJSONFileSync, writeJSONFile } from "../utilities/fileSystem.js";
import { installDependencies } from "../utilities/installDependencies.js";
import { spinner } from "../utilities/windows.js";
export const UpdateCommandOptionsSchema = z.object({
to: z.string().optional(),
+2 -1
View File
@@ -1,4 +1,4 @@
import { intro, note, spinner } from "@clack/prompts";
import { intro, note } from "@clack/prompts";
import { chalkLink } from "../utilities/cliOutput.js";
import { logger } from "../utilities/logger.js";
import { isLoggedIn } from "../utilities/session.js";
@@ -12,6 +12,7 @@ import {
} from "../cli/common.js";
import { z } from "zod";
import { CliApiClient } from "../apiClient.js";
import { spinner } from "../utilities/windows.js";
type WhoAmIResult =
| {
+4 -1
View File
@@ -4,6 +4,7 @@ import { readFileSync } from "node:fs";
import { extname, isAbsolute } from "node:path";
import tsConfigPaths from "tsconfig-paths";
import { logger } from "./logger";
import { escapeImportPath } from "./windows";
export function bundleTriggerDevCore(buildIdentifier: string, tsconfigPath?: string): Plugin {
return {
@@ -56,7 +57,9 @@ export function workerSetupImportConfigPlugin(configPath?: string): Plugin {
workerSetupContents = workerSetupContents.replace(
"__SETUP_IMPORTED_PROJECT_CONFIG__",
`import * as setupImportedConfigExports from "${configPath}"; const setupImportedConfig = setupImportedConfigExports.config;`
`import * as setupImportedConfigExports from "${escapeImportPath(
configPath
)}"; const setupImportedConfig = setupImportedConfigExports.config;`
);
logger.debug("Loading worker setup", {
@@ -1,4 +1,3 @@
import { spinner } from "@clack/prompts";
import chalk from "chalk";
import type { Result } from "update-check";
import checkForUpdate from "update-check";
@@ -6,6 +5,7 @@ import pkg from "../../package.json";
import { chalkGrey, chalkRun, chalkTask, chalkWorker, green, logo } from "./cliOutput.js";
import { getVersion } from "./getVersion.js";
import { logger } from "./logger.js";
import { spinner } from "./windows";
export async function printInitialBanner(performUpdateCheck = true) {
const packageVersion = getVersion();
@@ -40,18 +40,18 @@ After installation, run Trigger.dev with \`npx trigger.dev\`.`
export async function printStandloneInitialBanner(performUpdateCheck = true) {
const packageVersion = getVersion();
let text = `\n${logo()} ${chalkGrey("(v3 Developer Preview)")}`;
logger.log(`\n${logo()} ${chalkGrey("(v3 Developer Preview)")}`);
if (performUpdateCheck) {
const maybeNewVersion = await updateCheck();
// Log a slightly more noticeable message if this is a major bump
if (maybeNewVersion !== undefined) {
text = `${text} (update available ${chalk.green(maybeNewVersion)})`;
logger.log(`Update available ${chalk.green(maybeNewVersion)}`);
}
}
logger.log(text + "\n" + chalkGrey("-".repeat(54)));
logger.log(`${chalkGrey("-".repeat(54))}`);
}
export function printDevBanner() {
@@ -1,8 +1,8 @@
import { spinner } from "@clack/prompts";
import chalk from "chalk";
import { execa } from "execa";
import { getUserPackageManager, type PackageManager } from "./getUserPackageManager.js";
import { logger } from "./logger.js";
import { spinner } from "./windows.js";
export async function installDependencies(projectDir: string) {
logger.info("Installing dependencies...");
@@ -1,5 +1,8 @@
import { resolve as importResolve } from "import-meta-resolve";
import path from "path";
import { fileURLToPath } from "url";
export function resolveInternalFilePath(filePath: string): string {
return new URL(importResolve(filePath, import.meta.url)).href.replace("file://", "");
export function cliRootPath() {
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
return __dirname;
}
+14 -4
View File
@@ -24,13 +24,23 @@ export async function gatherTaskFiles(config: ResolvedConfig): Promise<Array<Tas
const files = await fs.promises.readdir(triggerDir, { withFileTypes: true });
for (const file of files) {
if (!file.isFile()) continue;
if (!file.name.endsWith(".js") && !file.name.endsWith(".ts")) continue;
if (
!file.name.endsWith(".js") &&
!file.name.endsWith(".ts") &&
!file.name.endsWith(".jsx") &&
!file.name.endsWith(".tsx")
) {
continue;
}
const fullPath = join(triggerDir, file.name);
const filePath = relative(config.projectDir, fullPath);
const importPath = filePath.replace(/\.(js|ts)$/, "");
const importName = importPath.replace(/\//g, "_").replace(/\./g, "_").replace(/-/g, "_");
//remove the file extension and replace any invalid characters with underscores
const importName = filePath.replace(/\..+$/, "").replace(/[^a-zA-Z0-9_$]/g, "_");
//change backslashes to forward slashes
const importPath = filePath.replace(/\\/g, "/");
taskFiles.push({ triggerDir, importPath, importName, filePath });
}
+23
View File
@@ -0,0 +1,23 @@
import { log, spinner as clackSpinner } from "@clack/prompts";
export const isWindows = process.platform === "win32";
export function escapeImportPath(path: string) {
return isWindows ? path.replaceAll("\\", "\\\\") : path;
}
const ballmerSpinner = () => ({
start: (msg?: string): void => {
log.step(msg ?? "");
},
stop: (msg?: string, code?: number): void => {
log.message(msg ?? "");
},
message: (msg?: string): void => {
log.message(msg ?? "");
},
});
// This will become unecessary with the next clack release, the bug was fixed here:
// https://github.com/natemoo-re/clack/pull/182
export const spinner = () => (isWindows ? ballmerSpinner() : clackSpinner());
+11 -3
View File
@@ -1,7 +1,8 @@
import { cp } from "fs/promises";
import { join } from "path";
import { defineConfig } from "tsup";
const isDev = process.env.npm_lifecycle_event === "dev";
const copyTemplates = "cp -r src/templates dist";
const isDev = process.env.npm_lifecycle_event === "dev:main"; // This must match the npm script name
export default defineConfig({
clean: false,
@@ -15,7 +16,14 @@ export default defineConfig({
sourcemap: true,
target: "esnext",
outDir: "dist",
onSuccess: isDev ? `${copyTemplates} && node dist/index.js` : copyTemplates,
async onSuccess() {
if (isDev) {
console.debug("Running onSuccess() in dev");
// exec: node dist/index.js
}
await cp(join("src", "templates"), "dist/templates", { recursive: true });
},
banner: {
js: "import { createRequire as createRequireFromMetaUrl } from 'node:module';const require = createRequireFromMetaUrl(import.meta.url);",
},
+1
View File
@@ -1,2 +1,3 @@
src/generated/*
!src/generated/.gitkeep
protoc.exe
+2
View File
@@ -14,6 +14,8 @@ apt install -y protobuf-compiler
Alternatively, follow the [manual install instructions](https://github.com/protocolbuffers/protobuf?tab=readme-ov-file#protobuf-compiler-installation) for the protobuf compiler.
On Windows, download the correct binary from the [latest release](https://github.com/protocolbuffers/protobuf/releases) and extract the `protoc` binary to this directory, or add it to your `PATH`.
## Submodules
**Submodule is always pointing to certain revision number. So updating the submodule repo will not have impact on your code.
+1 -1
View File
@@ -32,7 +32,7 @@
"generate": "npm run protos",
"protos": "npm run submodule && npm run protos:generate",
"protos:generate": "node ./scripts/generate-protos.mjs",
"submodule": "command -v git >/dev/null 2>&1 && git submodule sync --recursive && git submodule update --init --recursive || echo 'git not installed'",
"submodule": "node ./scripts/submodule.mjs",
"typecheck": "tsc --noEmit",
"test": "jest"
},
@@ -1,24 +1,19 @@
import { exec } from "child_process";
import { promises as fs } from "fs";
import path from "path";
import { execPromise } from "./utils.mjs";
// Helper function to execute shell commands
const execPromise = (command) =>
new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => {
if (error) {
reject(error);
} else {
resolve({ stdout, stderr });
}
});
});
const isWindows = process.platform === "win32";
// Define the application root and directories for generated files and proto files
const appRoot = process.cwd();
const generatedPath = path.join(appRoot, "src", "generated");
const protosPath = path.join(appRoot, "protos");
const pluginPath = path.join(appRoot, "node_modules", ".bin", "protoc-gen-ts_proto");
const pluginPath = path.join(
appRoot,
"node_modules",
".bin",
isWindows ? "protoc-gen-ts_proto.cmd" : "protoc-gen-ts_proto"
);
// Ensure the generated directory exists
await fs.mkdir(generatedPath, { recursive: true });
@@ -50,7 +45,11 @@ for (const proto of protos) {
`"${path.join(protosPath, proto)}"`;
try {
const { stdout, stderr } = await execPromise(command);
console.log(stdout);
if (stdout) {
console.log(stdout);
} else {
console.log(`Generated ts file for ${proto}`);
}
if (stderr) console.error(stderr);
} catch (error) {
console.error(`An error occurred during generation: ${error}`);
@@ -0,0 +1,31 @@
import { execPromise } from "./utils.mjs";
// git install check
try {
await execPromise("git --version");
} catch (error) {
console.error("Git not installed or missing from PATH.");
process.exit(1);
}
// submodule sync
try {
const { stdout, stderr } = await execPromise("git submodule sync --recursive");
if (stdout) console.log(stdout);
if (stderr) console.error(stderr);
} catch (error) {
console.error("Error during submodule sync.");
process.exit(1);
}
// submodule update
try {
const { stdout, stderr } = await execPromise("git submodule update --init --recursive");
if (stdout) console.log(stdout);
if (stderr) console.error(stderr);
} catch (error) {
console.error("Error during submodule update.");
process.exit(1);
}
+13
View File
@@ -0,0 +1,13 @@
import { exec } from "child_process";
// Helper function to execute shell commands
export const execPromise = (command) =>
new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => {
if (error) {
reject(error);
} else {
resolve({ stdout, stderr });
}
});
});
+5 -46
View File
@@ -1643,12 +1643,12 @@ importers:
cpy-cli:
specifier: ^5.0.0
version: 5.0.0
nodemon:
specifier: ^3.0.1
version: 3.0.1
npm-run-all:
specifier: ^4.1.5
version: 4.1.5
npm-watch:
specifier: ^0.11.0
version: 0.11.0
open:
specifier: ^10.0.3
version: 10.0.3
@@ -22036,6 +22036,7 @@ packages:
/iconv-lite@0.6.3:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
engines: {node: '>=0.10.0'}
requiresBuild: true
dependencies:
safer-buffer: 2.1.2
@@ -25794,23 +25795,6 @@ packages:
/node-releases@2.0.14:
resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==}
/nodemon@2.0.22:
resolution: {integrity: sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==}
engines: {node: '>=8.10.0'}
hasBin: true
dependencies:
chokidar: 3.5.3
debug: 3.2.7(supports-color@5.5.0)
ignore-by-default: 1.0.1
minimatch: 3.1.2
pstree.remy: 1.1.8
semver: 5.7.1
simple-update-notifier: 1.1.0
supports-color: 5.5.0
touch: 3.1.0
undefsafe: 2.0.5
dev: true
/nodemon@3.0.1:
resolution: {integrity: sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==}
engines: {node: '>=10'}
@@ -26028,14 +26012,6 @@ packages:
dependencies:
path-key: 4.0.0
/npm-watch@0.11.0:
resolution: {integrity: sha512-wAOd0moNX2kSA2FNvt8+7ORwYaJpQ1ZoWjUYdb1bBCxq4nkWuU0IiJa9VpVxrj5Ks+FGXQd62OC/Bjk0aSr+dg==}
hasBin: true
dependencies:
nodemon: 2.0.22
through2: 4.0.2
dev: true
/npmlog@6.0.2:
resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==}
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
@@ -29324,6 +29300,7 @@ packages:
/safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
requiresBuild: true
/sander@0.5.1:
resolution: {integrity: sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==}
@@ -29429,11 +29406,6 @@ packages:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
/semver@7.0.0:
resolution: {integrity: sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==}
hasBin: true
dev: true
/semver@7.5.0:
resolution: {integrity: sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==}
engines: {node: '>=10'}
@@ -29662,13 +29634,6 @@ packages:
dependencies:
is-arrayish: 0.3.2
/simple-update-notifier@1.1.0:
resolution: {integrity: sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==}
engines: {node: '>=8.10.0'}
dependencies:
semver: 7.0.0
dev: true
/simple-update-notifier@2.0.0:
resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==}
engines: {node: '>=10'}
@@ -30927,12 +30892,6 @@ packages:
xtend: 4.0.2
dev: true
/through2@4.0.2:
resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==}
dependencies:
readable-stream: 3.6.0
dev: true
/through@2.3.8:
resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}