🎯 MapView v2.0 - Global Deployment Ready

 MAJOR FEATURES:
• Auto-zoom intelligence với smart bounds fitting
• Enhanced 3D GPS markers với pulsing effects
• Professional route display với 6-layer rendering
• Status-based parking icons với availability indicators
• Production-ready build optimizations

🗺️ AUTO-ZOOM FEATURES:
• Smart bounds fitting cho GPS + selected parking
• Adaptive padding (50px) cho visual balance
• Max zoom control (level 16) để tránh quá gần
• Dynamic centering khi không có selection

🎨 ENHANCED VISUALS:
• 3D GPS marker với multi-layer pulse effects
• Advanced parking icons với status colors
• Selection highlighting với animation
• Dimming system cho non-selected items

🛣️ ROUTE SYSTEM:
• OpenRouteService API integration
• Multi-layer route rendering (glow, shadow, main, animated)
• Real-time distance & duration calculation
• Visual route info trong popup

📱 PRODUCTION READY:
• SSR safe với dynamic imports
• Build errors resolved
• Global deployment via Vercel
• Optimized performance

🌍 DEPLOYMENT:
• Vercel: https://whatever-ctk2auuxr-phong12hexdockworks-projects.vercel.app
• Bundle size: 22.8 kB optimized
• Global CDN distribution
• HTTPS enabled

💾 VERSION CONTROL:
• MapView-v2.0.tsx backup created
• MAPVIEW_VERSIONS.md documentation
• Full version history tracking
This commit is contained in:
2025-07-20 19:52:16 +07:00
parent 3203463a6a
commit c65cc97a33
64624 changed files with 7199453 additions and 6462 deletions

View File

@@ -0,0 +1,4 @@
import { Input } from '../commands';
export declare abstract class AbstractAction {
abstract handle(inputs?: Input[], options?: Input[], extraFlags?: string[]): Promise<void>;
}

View File

@@ -0,0 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AbstractAction = void 0;
class AbstractAction {
}
exports.AbstractAction = AbstractAction;

View File

@@ -0,0 +1,12 @@
import { Input } from '../commands';
import { AbstractAction } from './abstract.action';
export declare class AddAction extends AbstractAction {
handle(inputs: Input[], options: Input[], extraFlags: string[]): Promise<void>;
private getSourceRoot;
private installPackage;
private addLibrary;
private getLibraryName;
private getPackageName;
private getCollectionName;
private getTagName;
}

113
backend/node_modules/@nestjs/cli/actions/add.action.js generated vendored Normal file
View File

@@ -0,0 +1,113 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AddAction = void 0;
const chalk = require("chalk");
const get_value_or_default_1 = require("../lib/compiler/helpers/get-value-or-default");
const package_managers_1 = require("../lib/package-managers");
const schematics_1 = require("../lib/schematics");
const ui_1 = require("../lib/ui");
const load_configuration_1 = require("../lib/utils/load-configuration");
const project_utils_1 = require("../lib/utils/project-utils");
const abstract_action_1 = require("./abstract.action");
const schematicName = 'nest-add';
class AddAction extends abstract_action_1.AbstractAction {
async handle(inputs, options, extraFlags) {
const libraryName = this.getLibraryName(inputs);
const packageName = this.getPackageName(libraryName);
const collectionName = this.getCollectionName(libraryName, packageName);
const tagName = this.getTagName(packageName);
const skipInstall = (0, project_utils_1.hasValidOptionFlag)('skip-install', options);
const packageInstallSuccess = skipInstall || (await this.installPackage(collectionName, tagName));
if (packageInstallSuccess) {
const sourceRootOption = await this.getSourceRoot(inputs.concat(options));
options.push(sourceRootOption);
await this.addLibrary(collectionName, options, extraFlags);
}
else {
console.error(chalk.red(ui_1.MESSAGES.LIBRARY_INSTALLATION_FAILED_BAD_PACKAGE(libraryName)));
throw new Error(ui_1.MESSAGES.LIBRARY_INSTALLATION_FAILED_BAD_PACKAGE(libraryName));
}
}
async getSourceRoot(inputs) {
const configuration = await (0, load_configuration_1.loadConfiguration)();
const configurationProjects = configuration.projects;
const appName = inputs.find((option) => option.name === 'project')
.value;
let sourceRoot = appName
? (0, get_value_or_default_1.getValueOrDefault)(configuration, 'sourceRoot', appName)
: configuration.sourceRoot;
const shouldAsk = (0, project_utils_1.shouldAskForProject)(schematicName, configurationProjects, appName);
if (shouldAsk) {
const defaultLabel = ' [ Default ]';
let defaultProjectName = configuration.sourceRoot + defaultLabel;
for (const property in configurationProjects) {
if (configurationProjects[property].sourceRoot ===
configuration.sourceRoot) {
defaultProjectName = property + defaultLabel;
break;
}
}
const projects = (0, project_utils_1.moveDefaultProjectToStart)(configuration, defaultProjectName, defaultLabel);
const answers = await (0, project_utils_1.askForProjectName)(ui_1.MESSAGES.LIBRARY_PROJECT_SELECTION_QUESTION, projects);
const project = answers.appName.replace(defaultLabel, '');
if (project !== configuration.sourceRoot) {
sourceRoot = configurationProjects[project].sourceRoot;
}
}
return { name: 'sourceRoot', value: sourceRoot };
}
async installPackage(collectionName, tagName) {
const manager = await package_managers_1.PackageManagerFactory.find();
tagName = tagName || 'latest';
let installResult = false;
try {
installResult = await manager.addProduction([collectionName], tagName);
}
catch (error) {
if (error && error.message) {
console.error(chalk.red(error.message));
}
}
return installResult;
}
async addLibrary(collectionName, options, extraFlags) {
console.info(ui_1.MESSAGES.LIBRARY_INSTALLATION_STARTS);
const schematicOptions = [];
schematicOptions.push(new schematics_1.SchematicOption('sourceRoot', options.find((option) => option.name === 'sourceRoot').value));
const extraFlagsString = extraFlags ? extraFlags.join(' ') : undefined;
try {
const collection = schematics_1.CollectionFactory.create(collectionName);
await collection.execute(schematicName, schematicOptions, extraFlagsString);
}
catch (error) {
if (error && error.message) {
console.error(chalk.red(error.message));
return Promise.reject();
}
}
}
getLibraryName(inputs) {
const libraryInput = inputs.find((input) => input.name === 'library');
if (!libraryInput) {
throw new Error('No library found in command input');
}
return libraryInput.value;
}
getPackageName(library) {
return library.startsWith('@')
? library.split('/', 2).join('/')
: library.split('/', 1)[0];
}
getCollectionName(library, packageName) {
return ((packageName.startsWith('@')
? packageName.split('@', 2).join('@')
: packageName.split('@', 1).join('@')) +
library.slice(packageName.length));
}
getTagName(packageName) {
return packageName.startsWith('@')
? packageName.split('@', 3)[2]
: packageName.split('@', 2)[1];
}
}
exports.AddAction = AddAction;

View File

@@ -0,0 +1,22 @@
import { Input } from '../commands';
import { AssetsManager } from '../lib/compiler/assets-manager';
import { TsConfigProvider } from '../lib/compiler/helpers/tsconfig-provider';
import { PluginsLoader } from '../lib/compiler/plugins/plugins-loader';
import { TypeScriptBinaryLoader } from '../lib/compiler/typescript-loader';
import { ConfigurationLoader } from '../lib/configuration';
import { FileSystemReader } from '../lib/readers';
import { AbstractAction } from './abstract.action';
export declare class BuildAction extends AbstractAction {
protected readonly pluginsLoader: PluginsLoader;
protected readonly tsLoader: TypeScriptBinaryLoader;
protected readonly tsConfigProvider: TsConfigProvider;
protected readonly fileSystemReader: FileSystemReader;
protected readonly loader: ConfigurationLoader;
protected readonly assetsManager: AssetsManager;
handle(commandInputs: Input[], commandOptions: Input[]): Promise<void>;
runBuild(commandInputs: Input[], commandOptions: Input[], watchMode: boolean, watchAssetsMode: boolean, isDebugEnabled?: boolean, onSuccess?: () => void): Promise<void>;
private runSwc;
private runWebpack;
private runTsc;
private getWebpackConfigFactoryByPath;
}

View File

@@ -0,0 +1,124 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BuildAction = void 0;
const chalk = require("chalk");
const path_1 = require("path");
const assets_manager_1 = require("../lib/compiler/assets-manager");
const delete_out_dir_1 = require("../lib/compiler/helpers/delete-out-dir");
const get_builder_1 = require("../lib/compiler/helpers/get-builder");
const get_tsc_config_path_1 = require("../lib/compiler/helpers/get-tsc-config.path");
const get_value_or_default_1 = require("../lib/compiler/helpers/get-value-or-default");
const get_webpack_config_path_1 = require("../lib/compiler/helpers/get-webpack-config-path");
const tsconfig_provider_1 = require("../lib/compiler/helpers/tsconfig-provider");
const plugins_loader_1 = require("../lib/compiler/plugins/plugins-loader");
const typescript_loader_1 = require("../lib/compiler/typescript-loader");
const configuration_1 = require("../lib/configuration");
const defaults_1 = require("../lib/configuration/defaults");
const readers_1 = require("../lib/readers");
const ui_1 = require("../lib/ui");
const is_module_available_1 = require("../lib/utils/is-module-available");
const abstract_action_1 = require("./abstract.action");
class BuildAction extends abstract_action_1.AbstractAction {
constructor() {
super(...arguments);
this.pluginsLoader = new plugins_loader_1.PluginsLoader();
this.tsLoader = new typescript_loader_1.TypeScriptBinaryLoader();
this.tsConfigProvider = new tsconfig_provider_1.TsConfigProvider(this.tsLoader);
this.fileSystemReader = new readers_1.FileSystemReader(process.cwd());
this.loader = new configuration_1.NestConfigurationLoader(this.fileSystemReader);
this.assetsManager = new assets_manager_1.AssetsManager();
}
async handle(commandInputs, commandOptions) {
try {
const watchModeOption = commandOptions.find((option) => option.name === 'watch');
const watchMode = !!(watchModeOption && watchModeOption.value);
const watchAssetsModeOption = commandOptions.find((option) => option.name === 'watchAssets');
const watchAssetsMode = !!(watchAssetsModeOption && watchAssetsModeOption.value);
await this.runBuild(commandInputs, commandOptions, watchMode, watchAssetsMode);
}
catch (err) {
if (err instanceof Error) {
console.log(`\n${ui_1.ERROR_PREFIX} ${err.message}\n`);
}
else {
console.error(`\n${chalk.red(err)}\n`);
}
process.exit(1);
}
}
async runBuild(commandInputs, commandOptions, watchMode, watchAssetsMode, isDebugEnabled = false, onSuccess) {
const configFileName = commandOptions.find((option) => option.name === 'config').value;
const configuration = await this.loader.load(configFileName);
const appName = commandInputs.find((input) => input.name === 'app')
.value;
const pathToTsconfig = (0, get_tsc_config_path_1.getTscConfigPath)(configuration, commandOptions, appName);
const { options: tsOptions } = this.tsConfigProvider.getByConfigFilename(pathToTsconfig);
const outDir = tsOptions.outDir || defaults_1.defaultOutDir;
const isWebpackEnabled = (0, get_value_or_default_1.getValueOrDefault)(configuration, 'compilerOptions.webpack', appName, 'webpack', commandOptions);
const builder = isWebpackEnabled
? { type: 'webpack' }
: (0, get_builder_1.getBuilder)(configuration, commandOptions, appName);
await (0, delete_out_dir_1.deleteOutDirIfEnabled)(configuration, appName, outDir);
this.assetsManager.copyAssets(configuration, appName, outDir, watchAssetsMode);
const typeCheck = (0, get_value_or_default_1.getValueOrDefault)(configuration, 'compilerOptions.typeCheck', appName, 'typeCheck', commandOptions);
if (typeCheck && builder.type !== 'swc') {
console.warn(ui_1.INFO_PREFIX +
` "typeCheck" will not have any effect when "builder" is not "swc".`);
}
switch (builder.type) {
case 'tsc':
return this.runTsc(watchMode, commandOptions, configuration, pathToTsconfig, appName, onSuccess);
case 'webpack':
return this.runWebpack(configuration, appName, commandOptions, pathToTsconfig, isDebugEnabled, watchMode, onSuccess);
case 'swc':
return this.runSwc(configuration, appName, pathToTsconfig, watchMode, commandOptions, tsOptions, onSuccess);
}
}
async runSwc(configuration, appName, pathToTsconfig, watchMode, options, tsOptions, onSuccess) {
const { SwcCompiler } = await Promise.resolve().then(() => require('../lib/compiler/swc/swc-compiler'));
const swc = new SwcCompiler(this.pluginsLoader);
await swc.run(configuration, pathToTsconfig, appName, {
watch: watchMode,
typeCheck: (0, get_value_or_default_1.getValueOrDefault)(configuration, 'compilerOptions.typeCheck', appName, 'typeCheck', options),
tsOptions,
assetsManager: this.assetsManager,
}, onSuccess);
}
async runWebpack(configuration, appName, commandOptions, pathToTsconfig, debug, watchMode, onSuccess) {
const { WebpackCompiler } = await Promise.resolve().then(() => require('../lib/compiler/webpack-compiler'));
const webpackCompiler = new WebpackCompiler(this.pluginsLoader);
const webpackPath = (0, get_webpack_config_path_1.getWebpackConfigPath)(configuration, commandOptions, appName) ??
defaults_1.defaultWebpackConfigFilename;
const webpackConfigFactoryOrConfig = this.getWebpackConfigFactoryByPath(webpackPath, defaults_1.defaultWebpackConfigFilename);
return webpackCompiler.run(configuration, pathToTsconfig, appName, {
inputs: commandOptions,
webpackConfigFactoryOrConfig,
debug,
watchMode,
assetsManager: this.assetsManager,
}, onSuccess);
}
async runTsc(watchMode, options, configuration, pathToTsconfig, appName, onSuccess) {
if (watchMode) {
const { WatchCompiler } = await Promise.resolve().then(() => require('../lib/compiler/watch-compiler'));
const watchCompiler = new WatchCompiler(this.pluginsLoader, this.tsConfigProvider, this.tsLoader);
const isPreserveWatchOutputEnabled = options.find((option) => option.name === 'preserveWatchOutput' && option.value === true)?.value;
watchCompiler.run(configuration, pathToTsconfig, appName, { preserveWatchOutput: isPreserveWatchOutputEnabled }, onSuccess);
}
else {
const { Compiler } = await Promise.resolve().then(() => require('../lib/compiler/compiler'));
const compiler = new Compiler(this.pluginsLoader, this.tsConfigProvider, this.tsLoader);
compiler.run(configuration, pathToTsconfig, appName, undefined, onSuccess);
this.assetsManager.closeWatchers();
}
}
getWebpackConfigFactoryByPath(webpackPath, defaultPath) {
const pathToWebpackFile = (0, path_1.join)(process.cwd(), webpackPath);
const isWebpackFileAvailable = (0, is_module_available_1.isModuleAvailable)(pathToWebpackFile);
if (!isWebpackFileAvailable && webpackPath === defaultPath) {
return ({}) => ({});
}
return require(pathToWebpackFile);
}
}
exports.BuildAction = BuildAction;

View File

@@ -0,0 +1,5 @@
import { Input } from '../commands';
import { AbstractAction } from './abstract.action';
export declare class GenerateAction extends AbstractAction {
handle(inputs: Input[], options: Input[]): Promise<void>;
}

View File

@@ -0,0 +1,95 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GenerateAction = void 0;
const chalk = require("chalk");
const path = require("path");
const get_value_or_default_1 = require("../lib/compiler/helpers/get-value-or-default");
const schematics_1 = require("../lib/schematics");
const ui_1 = require("../lib/ui");
const load_configuration_1 = require("../lib/utils/load-configuration");
const project_utils_1 = require("../lib/utils/project-utils");
const abstract_action_1 = require("./abstract.action");
class GenerateAction extends abstract_action_1.AbstractAction {
async handle(inputs, options) {
await generateFiles(inputs.concat(options));
}
}
exports.GenerateAction = GenerateAction;
const generateFiles = async (inputs) => {
const configuration = await (0, load_configuration_1.loadConfiguration)();
const collectionOption = inputs.find((option) => option.name === 'collection').value;
const schematic = inputs.find((option) => option.name === 'schematic')
.value;
const appName = inputs.find((option) => option.name === 'project')
.value;
const spec = inputs.find((option) => option.name === 'spec');
const flat = inputs.find((option) => option.name === 'flat');
const specFileSuffix = inputs.find((option) => option.name === 'specFileSuffix');
const collection = schematics_1.CollectionFactory.create(collectionOption || configuration.collection || schematics_1.Collection.NESTJS);
const schematicOptions = mapSchematicOptions(inputs);
schematicOptions.push(new schematics_1.SchematicOption('language', configuration.language));
const configurationProjects = configuration.projects;
let sourceRoot = appName
? (0, get_value_or_default_1.getValueOrDefault)(configuration, 'sourceRoot', appName)
: configuration.sourceRoot;
const specValue = spec.value;
const flatValue = !!flat?.value;
const specFileSuffixValue = specFileSuffix.value;
const specOptions = spec.options;
let generateSpec = (0, project_utils_1.shouldGenerateSpec)(configuration, schematic, appName, specValue, specOptions.passedAsInput);
let generateFlat = (0, project_utils_1.shouldGenerateFlat)(configuration, appName, flatValue);
let generateSpecFileSuffix = (0, project_utils_1.getSpecFileSuffix)(configuration, appName, specFileSuffixValue);
// If you only add a `lib` we actually don't have monorepo: true BUT we do have "projects"
// Ensure we don't run for new app/libs schematics
if ((0, project_utils_1.shouldAskForProject)(schematic, configurationProjects, appName)) {
const defaultLabel = ' [ Default ]';
let defaultProjectName = configuration.sourceRoot + defaultLabel;
for (const property in configurationProjects) {
if (configurationProjects[property].sourceRoot === configuration.sourceRoot) {
defaultProjectName = property + defaultLabel;
break;
}
}
const projects = (0, project_utils_1.moveDefaultProjectToStart)(configuration, defaultProjectName, defaultLabel);
const answers = await (0, project_utils_1.askForProjectName)(ui_1.MESSAGES.PROJECT_SELECTION_QUESTION, projects);
const project = answers.appName.replace(defaultLabel, '');
if (project !== configuration.sourceRoot) {
sourceRoot = configurationProjects[project].sourceRoot;
}
if (answers.appName !== defaultProjectName) {
// Only overwrite if the appName is not the default- as it has already been loaded above
generateSpec = (0, project_utils_1.shouldGenerateSpec)(configuration, schematic, answers.appName, specValue, specOptions.passedAsInput);
generateFlat = (0, project_utils_1.shouldGenerateFlat)(configuration, answers.appNames, flatValue);
generateSpecFileSuffix = (0, project_utils_1.getSpecFileSuffix)(configuration, appName, specFileSuffixValue);
}
}
if (configuration.generateOptions?.baseDir) {
sourceRoot = path.join(sourceRoot, configuration.generateOptions.baseDir);
}
schematicOptions.push(new schematics_1.SchematicOption('sourceRoot', sourceRoot));
schematicOptions.push(new schematics_1.SchematicOption('spec', generateSpec));
schematicOptions.push(new schematics_1.SchematicOption('flat', generateFlat));
schematicOptions.push(new schematics_1.SchematicOption('specFileSuffix', generateSpecFileSuffix));
try {
const schematicInput = inputs.find((input) => input.name === 'schematic');
if (!schematicInput) {
throw new Error('Unable to find a schematic for this configuration');
}
await collection.execute(schematicInput.value, schematicOptions);
}
catch (error) {
if (error && error.message) {
console.error(chalk.red(error.message));
}
}
};
const mapSchematicOptions = (inputs) => {
const excludedInputNames = ['schematic', 'spec', 'flat', 'specFileSuffix'];
const options = [];
inputs.forEach((input) => {
if (!excludedInputNames.includes(input.name) && input.value !== undefined) {
options.push(new schematics_1.SchematicOption(input.name, input.value));
}
});
return options;
};

7
backend/node_modules/@nestjs/cli/actions/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,7 @@
export * from './abstract.action';
export * from './build.action';
export * from './generate.action';
export * from './info.action';
export * from './new.action';
export * from './start.action';
export * from './add.action';

23
backend/node_modules/@nestjs/cli/actions/index.js generated vendored Normal file
View File

@@ -0,0 +1,23 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./abstract.action"), exports);
__exportStar(require("./build.action"), exports);
__exportStar(require("./generate.action"), exports);
__exportStar(require("./info.action"), exports);
__exportStar(require("./new.action"), exports);
__exportStar(require("./start.action"), exports);
__exportStar(require("./add.action"), exports);

View File

@@ -0,0 +1,35 @@
import { AbstractAction } from './abstract.action';
interface LockfileDependency {
version: string;
}
interface PackageJsonDependencies {
[key: string]: LockfileDependency;
}
interface NestDependency {
name: string;
value: string;
packageName: string;
}
interface NestDependencyWarnings {
[key: string]: Array<NestDependency>;
}
export declare class InfoAction extends AbstractAction {
private manager;
private warningMessageDependenciesWhiteList;
handle(): Promise<void>;
private displayBanner;
private displaySystemInformation;
displayPackageManagerVersion(): Promise<void>;
displayNestInformation(): Promise<void>;
displayNestInformationFromPackage(): Promise<void>;
displayCliVersion(): void;
readProjectPackageDependencies(): PackageJsonDependencies;
displayNestVersions(dependencies: PackageJsonDependencies): void;
displayWarningMessage(nestDependencies: NestDependency[]): void;
buildNestVersionsWarningMessage(nestDependencies: NestDependency[]): NestDependencyWarnings;
buildNestVersionsMessage(dependencies: PackageJsonDependencies): NestDependency[];
collectNestDependencies(dependencies: PackageJsonDependencies): NestDependency[];
format(dependencies: NestDependency[]): NestDependency[];
rightPad(name: string, length: number): string;
}
export {};

181
backend/node_modules/@nestjs/cli/actions/info.action.js generated vendored Normal file
View File

@@ -0,0 +1,181 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.InfoAction = void 0;
const chalk = require("chalk");
const fs_1 = require("fs");
const os_1 = require("os");
const path_1 = require("path");
const package_managers_1 = require("../lib/package-managers");
const ui_1 = require("../lib/ui");
const abstract_action_1 = require("./abstract.action");
const os_info_utils_1 = require("../lib/utils/os-info.utils");
class InfoAction extends abstract_action_1.AbstractAction {
constructor() {
super(...arguments);
// Nest dependencies whitelist used to compare the major version
this.warningMessageDependenciesWhiteList = [
'@nestjs/core',
'@nestjs/common',
'@nestjs/schematics',
'@nestjs/platform-express',
'@nestjs/platform-fastify',
'@nestjs/platform-socket.io',
'@nestjs/platform-ws',
'@nestjs/websockets',
];
}
async handle() {
this.manager = await package_managers_1.PackageManagerFactory.find();
this.displayBanner();
await this.displaySystemInformation();
await this.displayNestInformation();
}
displayBanner() {
console.info(chalk.red(ui_1.BANNER));
}
async displaySystemInformation() {
console.info(chalk.green('[System Information]'));
console.info('OS Version :', chalk.blue((0, os_info_utils_1.default)((0, os_1.platform)(), (0, os_1.release)()), (0, os_1.release)()));
console.info('NodeJS Version :', chalk.blue(process.version));
await this.displayPackageManagerVersion();
}
async displayPackageManagerVersion() {
try {
const version = await this.manager.version();
console.info(`${this.manager.name} Version :`, chalk.blue(version), '\n');
}
catch {
console.error(`${this.manager.name} Version :`, chalk.red('Unknown'), '\n');
}
}
async displayNestInformation() {
this.displayCliVersion();
console.info(chalk.green('[Nest Platform Information]'));
await this.displayNestInformationFromPackage();
}
async displayNestInformationFromPackage() {
try {
const dependencies = this.readProjectPackageDependencies();
this.displayNestVersions(dependencies);
}
catch (err) {
console.error(chalk.red(ui_1.MESSAGES.NEST_INFORMATION_PACKAGE_MANAGER_FAILED));
}
}
displayCliVersion() {
console.info(chalk.green('[Nest CLI]'));
console.info('Nest CLI Version :', chalk.blue(JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(__dirname, '../package.json')).toString())
.version), '\n');
}
readProjectPackageDependencies() {
const buffer = (0, fs_1.readFileSync)((0, path_1.join)(process.cwd(), 'package.json'));
const pack = JSON.parse(buffer.toString());
const dependencies = { ...pack.dependencies, ...pack.devDependencies };
Object.keys(dependencies).forEach((key) => {
dependencies[key] = {
version: dependencies[key],
};
});
return dependencies;
}
displayNestVersions(dependencies) {
const nestDependencies = this.buildNestVersionsMessage(dependencies);
nestDependencies.forEach((dependency) => console.info(dependency.name, chalk.blue(dependency.value)));
this.displayWarningMessage(nestDependencies);
}
displayWarningMessage(nestDependencies) {
try {
const warnings = this.buildNestVersionsWarningMessage(nestDependencies);
const majorVersions = Object.keys(warnings);
if (majorVersions.length > 0) {
console.info('\r');
console.info(chalk.yellow('[Warnings]'));
console.info('The following packages are not in the same major version');
console.info('This could lead to runtime errors');
majorVersions.forEach((version) => {
console.info(chalk.bold(`* Under version ${version}`));
warnings[version].forEach(({ packageName, value }) => {
console.info(`- ${packageName} ${value}`);
});
});
}
}
catch {
console.info('\t');
console.error(chalk.red(ui_1.MESSAGES.NEST_INFORMATION_PACKAGE_WARNING_FAILED(this.warningMessageDependenciesWhiteList)));
}
}
buildNestVersionsWarningMessage(nestDependencies) {
const unsortedWarnings = nestDependencies.reduce((depWarningsGroup, { name, packageName, value }) => {
if (!this.warningMessageDependenciesWhiteList.includes(packageName)) {
return depWarningsGroup;
}
const [major] = value.replace(/[^\d.]/g, '').split('.', 1);
const minimumVersion = major;
depWarningsGroup[minimumVersion] = [
...(depWarningsGroup[minimumVersion] || []),
{ name, packageName, value },
];
return depWarningsGroup;
}, Object.create(null));
const unsortedMinorVersions = Object.keys(unsortedWarnings);
if (unsortedMinorVersions.length <= 1) {
return {};
}
const sortedMinorVersions = unsortedMinorVersions.sort((versionA, versionB) => {
const numA = parseFloat(versionA);
const numB = parseFloat(versionB);
if (isNaN(numA) && isNaN(numB)) {
// If both are not valid numbers, maintain the current order.
return 0;
}
// NaN is considered greater than any number, so if numA is NaN, place it later.
return isNaN(numA) ? 1 : isNaN(numB) ? -1 : numB - numA;
});
return sortedMinorVersions.reduce((warnings, minorVersion) => {
warnings[minorVersion] = unsortedWarnings[minorVersion];
return warnings;
}, Object.create(null));
}
buildNestVersionsMessage(dependencies) {
const nestDependencies = this.collectNestDependencies(dependencies);
return this.format(nestDependencies);
}
collectNestDependencies(dependencies) {
const nestDependencies = [];
Object.keys(dependencies).forEach((key) => {
if (key.indexOf('@nestjs') > -1) {
const depPackagePath = require.resolve(key + '/package.json', {
paths: [process.cwd()],
});
const depPackage = (0, fs_1.readFileSync)(depPackagePath).toString();
const value = JSON.parse(depPackage).version;
nestDependencies.push({
name: `${key.replace(/@nestjs\//, '').replace(/@.*/, '')} version`,
value: value || dependencies[key].version,
packageName: key,
});
}
});
return nestDependencies;
}
format(dependencies) {
const sorted = dependencies.sort((dependencyA, dependencyB) => dependencyB.name.length - dependencyA.name.length);
const length = sorted[0].name.length;
sorted.forEach((dependency) => {
if (dependency.name.length < length) {
dependency.name = this.rightPad(dependency.name, length);
}
dependency.name = dependency.name.concat(' :');
dependency.value = dependency.value.replace(/(\^|\~)/, '');
});
return sorted;
}
rightPad(name, length) {
while (name.length < length) {
name = name.concat(' ');
}
return name;
}
}
exports.InfoAction = InfoAction;

View File

@@ -0,0 +1,7 @@
import { Input } from '../commands';
import { AbstractAction } from './abstract.action';
export declare class NewAction extends AbstractAction {
handle(inputs: Input[], options: Input[]): Promise<void>;
}
export declare const retrieveCols: () => number;
export declare const exit: () => never;

186
backend/node_modules/@nestjs/cli/actions/new.action.js generated vendored Normal file
View File

@@ -0,0 +1,186 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.exit = exports.retrieveCols = exports.NewAction = void 0;
const chalk = require("chalk");
const child_process_1 = require("child_process");
const fs = require("fs");
const inquirer = require("inquirer");
const path_1 = require("path");
const defaults_1 = require("../lib/configuration/defaults");
const package_managers_1 = require("../lib/package-managers");
const questions_1 = require("../lib/questions/questions");
const git_runner_1 = require("../lib/runners/git.runner");
const schematics_1 = require("../lib/schematics");
const ui_1 = require("../lib/ui");
const formatting_1 = require("../lib/utils/formatting");
const abstract_action_1 = require("./abstract.action");
class NewAction extends abstract_action_1.AbstractAction {
async handle(inputs, options) {
const directoryOption = options.find((option) => option.name === 'directory');
const dryRunOption = options.find((option) => option.name === 'dry-run');
const isDryRunEnabled = dryRunOption && dryRunOption.value;
await askForMissingInformation(inputs, options);
await generateApplicationFiles(inputs, options).catch(exports.exit);
const shouldSkipInstall = options.some((option) => option.name === 'skip-install' && option.value === true);
const shouldSkipGit = options.some((option) => option.name === 'skip-git' && option.value === true);
const projectDirectory = getProjectDirectory(getApplicationNameInput(inputs), directoryOption);
if (!shouldSkipInstall) {
await installPackages(options, isDryRunEnabled, projectDirectory);
}
if (!isDryRunEnabled) {
if (!shouldSkipGit) {
await initializeGitRepository(projectDirectory);
await createGitIgnoreFile(projectDirectory);
}
printCollective();
}
process.exit(0);
}
}
exports.NewAction = NewAction;
const getApplicationNameInput = (inputs) => inputs.find((input) => input.name === 'name');
const getPackageManagerInput = (inputs) => inputs.find((options) => options.name === 'packageManager');
const getProjectDirectory = (applicationName, directoryOption) => {
return ((directoryOption && directoryOption.value) ||
(0, formatting_1.normalizeToKebabOrSnakeCase)(applicationName.value));
};
const askForMissingInformation = async (inputs, options) => {
console.info(ui_1.MESSAGES.PROJECT_INFORMATION_START);
console.info();
const prompt = inquirer.createPromptModule();
const nameInput = getApplicationNameInput(inputs);
if (!nameInput.value) {
const message = 'What name would you like to use for the new project?';
const questions = [(0, questions_1.generateInput)('name', message)('nest-app')];
const answers = await prompt(questions);
replaceInputMissingInformation(inputs, answers);
}
const packageManagerInput = getPackageManagerInput(options);
if (!packageManagerInput.value) {
const answers = await askForPackageManager();
replaceInputMissingInformation(options, answers);
}
};
const replaceInputMissingInformation = (inputs, answers) => {
return inputs.map((input) => (input.value =
input.value !== undefined ? input.value : answers[input.name]));
};
const generateApplicationFiles = async (args, options) => {
const collectionName = options.find((option) => option.name === 'collection' && option.value != null).value;
const collection = schematics_1.CollectionFactory.create(collectionName || schematics_1.Collection.NESTJS);
const schematicOptions = mapSchematicOptions(args.concat(options));
await collection.execute('application', schematicOptions);
console.info();
};
const mapSchematicOptions = (options) => {
return options.reduce((schematicOptions, option) => {
if (option.name !== 'skip-install') {
schematicOptions.push(new schematics_1.SchematicOption(option.name, option.value));
}
return schematicOptions;
}, []);
};
const installPackages = async (options, dryRunMode, installDirectory) => {
const inputPackageManager = getPackageManagerInput(options).value;
let packageManager;
if (dryRunMode) {
console.info();
console.info(chalk.green(ui_1.MESSAGES.DRY_RUN_MODE));
console.info();
return;
}
try {
packageManager = package_managers_1.PackageManagerFactory.create(inputPackageManager);
await packageManager.install(installDirectory, inputPackageManager);
}
catch (error) {
if (error && error.message) {
console.error(chalk.red(error.message));
}
}
};
const askForPackageManager = async () => {
const questions = [
(0, questions_1.generateSelect)('packageManager')(ui_1.MESSAGES.PACKAGE_MANAGER_QUESTION)([
package_managers_1.PackageManager.NPM,
package_managers_1.PackageManager.YARN,
package_managers_1.PackageManager.PNPM,
]),
];
const prompt = inquirer.createPromptModule();
return await prompt(questions);
};
const initializeGitRepository = async (dir) => {
const runner = new git_runner_1.GitRunner();
await runner.run('init', true, (0, path_1.join)(process.cwd(), dir)).catch(() => {
console.error(chalk.red(ui_1.MESSAGES.GIT_INITIALIZATION_ERROR));
});
};
/**
* Write a file `.gitignore` in the root of the newly created project.
* `.gitignore` available in `@nestjs/schematics` cannot be published to
* NPM (needs to be investigated).
*
* @param dir Relative path to the project.
* @param content (optional) Content written in the `.gitignore`.
*
* @return Resolves when succeeds, or rejects with any error from `fn.writeFile`.
*/
const createGitIgnoreFile = (dir, content) => {
const fileContent = content || defaults_1.defaultGitIgnore;
const filePath = (0, path_1.join)(process.cwd(), dir, '.gitignore');
if (fileExists(filePath)) {
return;
}
return fs.promises.writeFile(filePath, fileContent);
};
const printCollective = () => {
const dim = print('dim');
const yellow = print('yellow');
const emptyLine = print();
emptyLine();
yellow(`Thanks for installing Nest ${ui_1.EMOJIS.PRAY}`);
dim('Please consider donating to our open collective');
dim('to help us maintain this package.');
emptyLine();
emptyLine();
print()(`${chalk.bold(`${ui_1.EMOJIS.WINE} Donate:`)} ${chalk.underline('https://opencollective.com/nest')}`);
emptyLine();
};
const print = (color = null) => (str = '') => {
const terminalCols = (0, exports.retrieveCols)();
const strLength = str.replace(/\u001b\[[0-9]{2}m/g, '').length;
const leftPaddingLength = Math.floor((terminalCols - strLength) / 2);
const leftPadding = ' '.repeat(Math.max(leftPaddingLength, 0));
if (color) {
str = chalk[color](str);
}
console.log(leftPadding, str);
};
const retrieveCols = () => {
const defaultCols = 80;
try {
const terminalCols = (0, child_process_1.execSync)('tput cols', {
stdio: ['pipe', 'pipe', 'ignore'],
});
return parseInt(terminalCols.toString(), 10) || defaultCols;
}
catch {
return defaultCols;
}
};
exports.retrieveCols = retrieveCols;
const fileExists = (path) => {
try {
fs.accessSync(path);
return true;
}
catch (err) {
if (err.code === 'ENOENT') {
return false;
}
throw err;
}
};
const exit = () => process.exit(1);
exports.exit = exit;

View File

@@ -0,0 +1,7 @@
import { Input } from '../commands';
import { BuildAction } from './build.action';
export declare class StartAction extends BuildAction {
handle(commandInputs: Input[], commandOptions: Input[]): Promise<void>;
createOnSuccessHook(entryFile: string, sourceRoot: string, debugFlag: boolean | string | undefined, outDirName: string, binaryToRun: string): () => void;
private spawnChildProcess;
}

View File

@@ -0,0 +1,99 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.StartAction = void 0;
const chalk = require("chalk");
const child_process_1 = require("child_process");
const fs = require("fs");
const path_1 = require("path");
const killProcess = require("tree-kill");
const get_tsc_config_path_1 = require("../lib/compiler/helpers/get-tsc-config.path");
const get_value_or_default_1 = require("../lib/compiler/helpers/get-value-or-default");
const defaults_1 = require("../lib/configuration/defaults");
const ui_1 = require("../lib/ui");
const tree_kill_1 = require("../lib/utils/tree-kill");
const build_action_1 = require("./build.action");
class StartAction extends build_action_1.BuildAction {
async handle(commandInputs, commandOptions) {
try {
const configFileName = commandOptions.find((option) => option.name === 'config').value;
const configuration = await this.loader.load(configFileName);
const appName = commandInputs.find((input) => input.name === 'app')
.value;
const pathToTsconfig = (0, get_tsc_config_path_1.getTscConfigPath)(configuration, commandOptions, appName);
const debugModeOption = commandOptions.find((option) => option.name === 'debug');
const watchModeOption = commandOptions.find((option) => option.name === 'watch');
const isWatchEnabled = !!(watchModeOption && watchModeOption.value);
const watchAssetsModeOption = commandOptions.find((option) => option.name === 'watchAssets');
const isWatchAssetsEnabled = !!(watchAssetsModeOption && watchAssetsModeOption.value);
const debugFlag = debugModeOption && debugModeOption.value;
const binaryToRun = (0, get_value_or_default_1.getValueOrDefault)(configuration, 'exec', appName, 'exec', commandOptions, defaults_1.defaultConfiguration.exec);
const { options: tsOptions } = this.tsConfigProvider.getByConfigFilename(pathToTsconfig);
const outDir = tsOptions.outDir || defaults_1.defaultOutDir;
const entryFile = (0, get_value_or_default_1.getValueOrDefault)(configuration, 'entryFile', appName, 'entryFile', commandOptions, defaults_1.defaultConfiguration.entryFile);
const sourceRoot = (0, get_value_or_default_1.getValueOrDefault)(configuration, 'sourceRoot', appName, 'sourceRoot', commandOptions, defaults_1.defaultConfiguration.sourceRoot);
const onSuccess = this.createOnSuccessHook(entryFile, sourceRoot, debugFlag, outDir, binaryToRun);
await this.runBuild(commandInputs, commandOptions, isWatchEnabled, isWatchAssetsEnabled, !!debugFlag, onSuccess);
}
catch (err) {
if (err instanceof Error) {
console.log(`\n${ui_1.ERROR_PREFIX} ${err.message}\n`);
}
else {
console.error(`\n${chalk.red(err)}\n`);
}
}
}
createOnSuccessHook(entryFile, sourceRoot, debugFlag, outDirName, binaryToRun) {
let childProcessRef;
process.on('exit', () => childProcessRef && (0, tree_kill_1.treeKillSync)(childProcessRef.pid));
return () => {
if (childProcessRef) {
childProcessRef.removeAllListeners('exit');
childProcessRef.on('exit', () => {
childProcessRef = this.spawnChildProcess(entryFile, sourceRoot, debugFlag, outDirName, binaryToRun);
childProcessRef.on('exit', () => (childProcessRef = undefined));
});
childProcessRef.stdin && childProcessRef.stdin.pause();
killProcess(childProcessRef.pid);
}
else {
childProcessRef = this.spawnChildProcess(entryFile, sourceRoot, debugFlag, outDirName, binaryToRun);
childProcessRef.on('exit', (code) => {
process.exitCode = code;
childProcessRef = undefined;
});
}
};
}
spawnChildProcess(entryFile, sourceRoot, debug, outDirName, binaryToRun) {
let outputFilePath = (0, path_1.join)(outDirName, sourceRoot, entryFile);
if (!fs.existsSync(outputFilePath + '.js')) {
outputFilePath = (0, path_1.join)(outDirName, entryFile);
}
let childProcessArgs = [];
const argsStartIndex = process.argv.indexOf('--');
if (argsStartIndex >= 0) {
// Prevents the need for users to double escape strings
// i.e. I can run the more natural
// nest start -- '{"foo": "bar"}'
// instead of
// nest start -- '\'{"foo": "bar"}\''
childProcessArgs = process.argv
.slice(argsStartIndex + 1)
.map((arg) => JSON.stringify(arg));
}
outputFilePath =
outputFilePath.indexOf(' ') >= 0 ? `"${outputFilePath}"` : outputFilePath;
const processArgs = [outputFilePath, ...childProcessArgs];
if (debug) {
const inspectFlag = typeof debug === 'string' ? `--inspect=${debug}` : '--inspect';
processArgs.unshift(inspectFlag);
}
processArgs.unshift('--enable-source-maps');
return (0, child_process_1.spawn)(binaryToRun, processArgs, {
stdio: 'inherit',
shell: true,
});
}
}
exports.StartAction = StartAction;