Initial commit: notification-elements-demo app

Interactive Angular 19 demo for @sda/notification-elements-ui with
6 sections: Bell & Feed, Notification Center, Inbox, Comments &
Threads, Mention Input, and Full-Featured layout. Includes mock
data, dark mode toggle, and real-time event log.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Giuliano Silvestro
2026-02-13 21:49:19 +10:00
commit 5d0c9ec7eb
36473 changed files with 3778146 additions and 0 deletions

View File

@@ -0,0 +1,67 @@
import { APP_BASE_HREF } from '@angular/common';
import { CommonEngine, isMainModule } from '@angular/ssr/node';
import express from 'express';
import { dirname, join, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import <% if (isStandalone) { %>bootstrap<% } else { %>AppServerModule<% } %> from './main.server';
const serverDistFolder = dirname(fileURLToPath(import.meta.url));
const browserDistFolder = resolve(serverDistFolder, '../<%= browserDistDirectory %>');
const indexHtml = join(serverDistFolder, 'index.server.html');
const app = express();
const commonEngine = new CommonEngine();
/**
* Example Express Rest API endpoints can be defined here.
* Uncomment and define endpoints as necessary.
*
* Example:
* ```ts
* app.get('/api/**', (req, res) => {
* // Handle API request
* });
* ```
*/
/**
* Serve static files from /<%= browserDistDirectory %>
*/
app.get(
'**',
express.static(browserDistFolder, {
maxAge: '1y',
index: 'index.html'
}),
);
/**
* Handle all other requests by rendering the Angular application.
*/
app.get('**', (req, res, next) => {
const { protocol, originalUrl, baseUrl, headers } = req;
commonEngine
.render({
<% if (isStandalone) { %>bootstrap<% } else { %>bootstrap: AppServerModule<% } %>,
documentFilePath: indexHtml,
url: `${protocol}://${headers.host}${originalUrl}`,
publicPath: browserDistFolder,
providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }],
})
.then((html) => res.send(html))
.catch((err) => next(err));
});
/**
* Start the server if this module is the main entry point.
* The server listens on the port defined by the `PORT` environment variable, or defaults to 4000.
*/
if (isMainModule(import.meta.url)) {
const port = process.env['PORT'] || 4000;
app.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
export default app;

View File

@@ -0,0 +1,66 @@
import {
AngularNodeAppEngine,
createNodeRequestHandler,
isMainModule,
writeResponseToNodeResponse,
} from '@angular/ssr/node';
import express from 'express';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
const serverDistFolder = dirname(fileURLToPath(import.meta.url));
const browserDistFolder = resolve(serverDistFolder, '../<%= browserDistDirectory %>');
const app = express();
const angularApp = new AngularNodeAppEngine();
/**
* Example Express Rest API endpoints can be defined here.
* Uncomment and define endpoints as necessary.
*
* Example:
* ```ts
* app.get('/api/**', (req, res) => {
* // Handle API request
* });
* ```
*/
/**
* Serve static files from /<%= browserDistDirectory %>
*/
app.use(
express.static(browserDistFolder, {
maxAge: '1y',
index: false,
redirect: false,
}),
);
/**
* Handle all other requests by rendering the Angular application.
*/
app.use('/**', (req, res, next) => {
angularApp
.handle(req)
.then((response) =>
response ? writeResponseToNodeResponse(response, res) : next(),
)
.catch(next);
});
/**
* Start the server if this module is the main entry point.
* The server listens on the port defined by the `PORT` environment variable, or defaults to 4000.
*/
if (isMainModule(import.meta.url)) {
const port = process.env['PORT'] || 4000;
app.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
/**
* Request handler used by the Angular CLI (for dev-server and during build) or Firebase Cloud Functions.
*/
export const reqHandler = createNodeRequestHandler(app);

View File

@@ -0,0 +1,69 @@
import 'zone.js/node';
import { APP_BASE_HREF } from '@angular/common';
import { CommonEngine } from '@angular/ssr/node';
import express from 'express';
import { existsSync } from 'node:fs';
import { join } from 'node:path';
import <% if (isStandalone) { %>bootstrap<% } else { %>AppServerModule<% } %> from './main.server';
// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
const server = express();
const distFolder = join(process.cwd(), '<%= browserDistDirectory %>');
const indexHtml = existsSync(join(distFolder, 'index.original.html'))
? join(distFolder, 'index.original.html')
: join(distFolder, 'index.html');
const commonEngine = new CommonEngine();
server.set('view engine', 'html');
server.set('views', distFolder);
// Example Express Rest API endpoints
// server.get('/api/**', (req, res) => { });
// Serve static files from /browser
server.get('*.*', express.static(distFolder, {
maxAge: '1y'
}));
// All regular routes use the Angular engine
server.get('*', (req, res, next) => {
const { protocol, originalUrl, baseUrl, headers } = req;
commonEngine
.render({
<% if (isStandalone) { %>bootstrap<% } else { %>bootstrap: AppServerModule<% } %>,
documentFilePath: indexHtml,
url: `${protocol}://${headers.host}${originalUrl}`,
publicPath: distFolder,
providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }],
})
.then((html) => res.send(html))
.catch((err) => next(err));
});
return server;
}
function run(): void {
const port = process.env['PORT'] || 4000;
// Start up the Node server
const server = app();
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = mainModule && mainModule.filename || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
run();
}
export default <% if (isStandalone) { %>bootstrap<% } else { %>AppServerModule<% } %>;

12
node_modules/@schematics/angular/ssr/index.d.ts generated vendored Executable file
View File

@@ -0,0 +1,12 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { Rule } from '@angular-devkit/schematics';
import { Schema as SSROptions } from './schema';
export default function (inputOptions: SSROptions): Rule;
export type Prompt = (message: string, defaultValue: boolean) => Promise<boolean>;
export declare function setPrompterForTestOnly(prompter?: Prompt): void;

381
node_modules/@schematics/angular/ssr/index.js generated vendored Executable file
View File

@@ -0,0 +1,381 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = default_1;
exports.setPrompterForTestOnly = setPrompterForTestOnly;
const core_1 = require("@angular-devkit/core");
const schematics_1 = require("@angular-devkit/schematics");
const node_path_1 = require("node:path");
const utility_1 = require("../utility");
const json_file_1 = require("../utility/json-file");
const latest_versions_1 = require("../utility/latest-versions");
const ng_ast_utils_1 = require("../utility/ng-ast-utils");
const project_targets_1 = require("../utility/project-targets");
const util_1 = require("../utility/standalone/util");
const workspace_1 = require("../utility/workspace");
const workspace_models_1 = require("../utility/workspace-models");
const tty_1 = require("./tty");
const SERVE_SSR_TARGET_NAME = 'serve-ssr';
const PRERENDER_TARGET_NAME = 'prerender';
const DEFAULT_BROWSER_DIR = 'browser';
const DEFAULT_MEDIA_DIR = 'media';
const DEFAULT_SERVER_DIR = 'server';
async function getLegacyOutputPaths(host, projectName, target) {
// Generate new output paths
const workspace = await (0, utility_1.readWorkspace)(host);
const project = workspace.projects.get(projectName);
const architectTarget = project?.targets.get(target);
if (!architectTarget?.options) {
throw new schematics_1.SchematicsException(`Cannot find 'options' for ${projectName} ${target} target.`);
}
const { outputPath } = architectTarget.options;
if (typeof outputPath !== 'string') {
throw new schematics_1.SchematicsException(`outputPath for ${projectName} ${target} target is not a string.`);
}
return outputPath;
}
async function getApplicationBuilderOutputPaths(host, projectName) {
// Generate new output paths
const target = 'build';
const workspace = await (0, utility_1.readWorkspace)(host);
const project = workspace.projects.get(projectName);
const architectTarget = project?.targets.get(target);
if (!architectTarget?.options) {
throw new schematics_1.SchematicsException(`Cannot find 'options' for ${projectName} ${target} target.`);
}
const { outputPath } = architectTarget.options;
if (outputPath === null || outputPath === undefined) {
throw new schematics_1.SchematicsException(`outputPath for ${projectName} ${target} target is undefined or null.`);
}
const defaultDirs = {
server: DEFAULT_SERVER_DIR,
browser: DEFAULT_BROWSER_DIR,
};
if (outputPath && (0, core_1.isJsonObject)(outputPath)) {
return {
...defaultDirs,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
...outputPath,
};
}
if (typeof outputPath !== 'string') {
throw new schematics_1.SchematicsException(`outputPath for ${projectName} ${target} target is not a string.`);
}
return {
base: outputPath,
...defaultDirs,
};
}
function addScriptsRule({ project }, isUsingApplicationBuilder) {
return async (host) => {
const pkgPath = '/package.json';
const pkg = host.readJson(pkgPath);
if (pkg === null) {
throw new schematics_1.SchematicsException('Could not find package.json');
}
if (isUsingApplicationBuilder) {
const { base, server } = await getApplicationBuilderOutputPaths(host, project);
pkg.scripts ??= {};
pkg.scripts[`serve:ssr:${project}`] = `node ${node_path_1.posix.join(base, server)}/server.mjs`;
}
else {
const serverDist = await getLegacyOutputPaths(host, project, 'server');
pkg.scripts = {
...pkg.scripts,
'dev:ssr': `ng run ${project}:${SERVE_SSR_TARGET_NAME}`,
'serve:ssr': `node ${serverDist}/main.js`,
'build:ssr': `ng build && ng run ${project}:server`,
'prerender': `ng run ${project}:${PRERENDER_TARGET_NAME}`,
};
}
host.overwrite(pkgPath, JSON.stringify(pkg, null, 2));
};
}
function updateApplicationBuilderTsConfigRule(options) {
return async (host) => {
const workspace = await (0, utility_1.readWorkspace)(host);
const project = workspace.projects.get(options.project);
const buildTarget = project?.targets.get('build');
if (!buildTarget || !buildTarget.options) {
return;
}
const tsConfigPath = buildTarget.options.tsConfig;
if (!tsConfigPath || typeof tsConfigPath !== 'string') {
// No tsconfig path
return;
}
const json = new json_file_1.JSONFile(host, tsConfigPath);
const filesPath = ['files'];
const files = new Set(json.get(filesPath) ?? []);
files.add('src/server.ts');
json.modify(filesPath, [...files]);
};
}
function updateApplicationBuilderWorkspaceConfigRule(projectSourceRoot, options, { logger }) {
return (0, utility_1.updateWorkspace)((workspace) => {
const buildTarget = workspace.projects.get(options.project)?.targets.get('build');
if (!buildTarget) {
return;
}
let outputPath = buildTarget.options?.outputPath;
if (outputPath && (0, core_1.isJsonObject)(outputPath)) {
if (outputPath.browser === '') {
const base = outputPath.base;
logger.warn(`The output location of the browser build has been updated from "${base}" to "${node_path_1.posix.join(base, DEFAULT_BROWSER_DIR)}".
You might need to adjust your deployment pipeline.`);
if ((outputPath.media && outputPath.media !== DEFAULT_MEDIA_DIR) ||
(outputPath.server && outputPath.server !== DEFAULT_SERVER_DIR)) {
delete outputPath.browser;
}
else {
outputPath = outputPath.base;
}
}
}
buildTarget.options = {
...buildTarget.options,
outputPath,
outputMode: options.serverRouting ? 'server' : undefined,
prerender: options.serverRouting ? undefined : true,
ssr: {
entry: (0, core_1.join)((0, core_1.normalize)(projectSourceRoot), 'server.ts'),
},
};
});
}
function updateWebpackBuilderWorkspaceConfigRule(projectSourceRoot, options) {
return (0, utility_1.updateWorkspace)((workspace) => {
const projectName = options.project;
const project = workspace.projects.get(projectName);
if (!project) {
return;
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const serverTarget = project.targets.get('server');
(serverTarget.options ??= {}).main = node_path_1.posix.join(projectSourceRoot, 'server.ts');
const serveSSRTarget = project.targets.get(SERVE_SSR_TARGET_NAME);
if (serveSSRTarget) {
return;
}
project.targets.add({
name: SERVE_SSR_TARGET_NAME,
builder: '@angular-devkit/build-angular:ssr-dev-server',
defaultConfiguration: 'development',
options: {},
configurations: {
development: {
browserTarget: `${projectName}:build:development`,
serverTarget: `${projectName}:server:development`,
},
production: {
browserTarget: `${projectName}:build:production`,
serverTarget: `${projectName}:server:production`,
},
},
});
const prerenderTarget = project.targets.get(PRERENDER_TARGET_NAME);
if (prerenderTarget) {
return;
}
project.targets.add({
name: PRERENDER_TARGET_NAME,
builder: '@angular-devkit/build-angular:prerender',
defaultConfiguration: 'production',
options: {
routes: ['/'],
},
configurations: {
production: {
browserTarget: `${projectName}:build:production`,
serverTarget: `${projectName}:server:production`,
},
development: {
browserTarget: `${projectName}:build:development`,
serverTarget: `${projectName}:server:development`,
},
},
});
});
}
function updateWebpackBuilderServerTsConfigRule(options) {
return async (host) => {
const workspace = await (0, utility_1.readWorkspace)(host);
const project = workspace.projects.get(options.project);
const serverTarget = project?.targets.get('server');
if (!serverTarget || !serverTarget.options) {
return;
}
const tsConfigPath = serverTarget.options.tsConfig;
if (!tsConfigPath || typeof tsConfigPath !== 'string') {
// No tsconfig path
return;
}
const tsConfig = new json_file_1.JSONFile(host, tsConfigPath);
const filesAstNode = tsConfig.get(['files']);
const serverFilePath = 'src/server.ts';
if (Array.isArray(filesAstNode) && !filesAstNode.some(({ text }) => text === serverFilePath)) {
tsConfig.modify(['files'], [...filesAstNode, serverFilePath]);
}
};
}
function addDependencies({ skipInstall }, isUsingApplicationBuilder) {
const install = skipInstall ? utility_1.InstallBehavior.None : utility_1.InstallBehavior.Auto;
const rules = [
(0, utility_1.addDependency)('express', latest_versions_1.latestVersions['express'], {
type: utility_1.DependencyType.Default,
install,
}),
(0, utility_1.addDependency)('@types/express', latest_versions_1.latestVersions['@types/express'], {
type: utility_1.DependencyType.Dev,
install,
}),
];
if (!isUsingApplicationBuilder) {
rules.push((0, utility_1.addDependency)('browser-sync', latest_versions_1.latestVersions['browser-sync'], {
type: utility_1.DependencyType.Dev,
install,
}));
}
return (0, schematics_1.chain)(rules);
}
function addServerFile(projectSourceRoot, options, isStandalone) {
return async (host) => {
const projectName = options.project;
const workspace = await (0, utility_1.readWorkspace)(host);
const project = workspace.projects.get(projectName);
if (!project) {
throw new schematics_1.SchematicsException(`Invalid project name (${projectName})`);
}
const isUsingApplicationBuilder = usingApplicationBuilder(project);
const browserDistDirectory = isUsingApplicationBuilder
? (await getApplicationBuilderOutputPaths(host, projectName)).browser
: await getLegacyOutputPaths(host, projectName, 'build');
const applicationBuilderFiles = 'application-builder' + (options.serverRouting ? '' : '-common-engine');
return (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)(`./files/${isUsingApplicationBuilder ? applicationBuilderFiles : 'server-builder'}`), [
(0, schematics_1.applyTemplates)({
...core_1.strings,
...options,
browserDistDirectory,
isStandalone,
}),
(0, schematics_1.move)(projectSourceRoot),
]));
};
}
function default_1(inputOptions) {
return async (host, context) => {
const browserEntryPoint = await (0, util_1.getMainFilePath)(host, inputOptions.project);
const isStandalone = (0, ng_ast_utils_1.isStandaloneApp)(host, browserEntryPoint);
const workspace = await (0, workspace_1.getWorkspace)(host);
const clientProject = workspace.projects.get(inputOptions.project);
if (!clientProject) {
throw (0, project_targets_1.targetBuildNotFoundError)();
}
const isUsingApplicationBuilder = usingApplicationBuilder(clientProject);
const serverRouting = await isServerRoutingEnabled(isUsingApplicationBuilder, inputOptions);
const options = { ...inputOptions, serverRouting };
const sourceRoot = clientProject.sourceRoot ?? node_path_1.posix.join(clientProject.root, 'src');
return (0, schematics_1.chain)([
(0, schematics_1.schematic)('server', {
...options,
skipInstall: true,
}),
...(isUsingApplicationBuilder
? [
updateApplicationBuilderWorkspaceConfigRule(sourceRoot, options, context),
updateApplicationBuilderTsConfigRule(options),
]
: [
updateWebpackBuilderServerTsConfigRule(options),
updateWebpackBuilderWorkspaceConfigRule(sourceRoot, options),
]),
addServerFile(sourceRoot, options, isStandalone),
addScriptsRule(options, isUsingApplicationBuilder),
addDependencies(options, isUsingApplicationBuilder),
]);
};
}
function usingApplicationBuilder(project) {
const buildBuilder = project.targets.get('build')?.builder;
const isUsingApplicationBuilder = buildBuilder === workspace_models_1.Builders.Application || buildBuilder === workspace_models_1.Builders.BuildApplication;
return isUsingApplicationBuilder;
}
const defaultPrompter = async (message, defaultValue) => {
const { confirm } = await Promise.resolve().then(() => __importStar(require('@inquirer/prompts')));
return await confirm({
message,
default: defaultValue,
});
};
// Allow the prompt functionality to be overridden to facilitate testing.
let prompt = defaultPrompter;
function setPrompterForTestOnly(prompter) {
prompt = prompter ?? defaultPrompter;
}
/** Returns whether or not server routing is enabled, potentially prompting the user if necessary. */
async function isServerRoutingEnabled(isUsingApplicationBuilder, options) {
if (!isUsingApplicationBuilder) {
if (options.serverRouting) {
throw new schematics_1.SchematicsException('Server routing APIs can only be added to a project using `application` builder.');
}
else {
return false;
}
}
// Use explicit option if provided.
if (options.serverRouting !== undefined) {
return options.serverRouting;
}
const serverRoutingDefault = false;
// Use the default if not in an interactive terminal.
if (!(0, tty_1.isTTY)()) {
return serverRoutingDefault;
}
// `inquirer` requires `async_hooks` which isn't supported by webcontainers, therefore we can't prompt in that context.
// See: https://github.com/SBoudrias/Inquirer.js/issues/1426
if (process.versions.webcontainer) {
return serverRoutingDefault;
}
// Prompt the user if in an interactive terminal and no option was provided.
return await prompt('Would you like to use the Server Routing and App Engine APIs (Developer Preview) for this server application?',
/* defaultValue */ serverRoutingDefault);
}

23
node_modules/@schematics/angular/ssr/schema.d.ts generated vendored Executable file
View File

@@ -0,0 +1,23 @@
/**
* Enables Server-Side Rendering (SSR) for your Angular application. SSR allows your app to
* be rendered on the server, which can significantly improve its initial load performance
* and Search Engine Optimization (SEO). This schematic configures your project for SSR,
* generating the necessary files and making the required modifications to your project's
* structure.
*/
export type Schema = {
/**
* The name of the project you want to enable SSR for.
*/
project: string;
/**
* Configure the server application to use the Angular Server Routing API and App Engine
* APIs (currently in Developer Preview).
*/
serverRouting?: boolean;
/**
* Skip the automatic installation of packages. You will need to manually install the
* dependencies later.
*/
skipInstall?: boolean;
};

4
node_modules/@schematics/angular/ssr/schema.js generated vendored Executable file
View File

@@ -0,0 +1,4 @@
"use strict";
// THIS FILE IS AUTOMATICALLY GENERATED. TO UPDATE THIS FILE YOU NEED TO CHANGE THE
// CORRESPONDING JSON SCHEMA FILE, THEN RUN devkit-admin build (or bazel build ...).
Object.defineProperty(exports, "__esModule", { value: true });

27
node_modules/@schematics/angular/ssr/schema.json generated vendored Executable file
View File

@@ -0,0 +1,27 @@
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "SchematicsAngularSSR",
"title": "Angular SSR Options Schema",
"type": "object",
"description": "Enables Server-Side Rendering (SSR) for your Angular application. SSR allows your app to be rendered on the server, which can significantly improve its initial load performance and Search Engine Optimization (SEO). This schematic configures your project for SSR, generating the necessary files and making the required modifications to your project's structure.",
"properties": {
"project": {
"type": "string",
"description": "The name of the project you want to enable SSR for.",
"$default": {
"$source": "projectName"
}
},
"skipInstall": {
"description": "Skip the automatic installation of packages. You will need to manually install the dependencies later.",
"type": "boolean",
"default": false
},
"serverRouting": {
"description": "Configure the server application to use the Angular Server Routing API and App Engine APIs (currently in Developer Preview).",
"type": "boolean"
}
},
"required": ["project"],
"additionalProperties": false
}

8
node_modules/@schematics/angular/ssr/tty.d.ts generated vendored Executable file
View File

@@ -0,0 +1,8 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
export declare function isTTY(): boolean;

22
node_modules/@schematics/angular/ssr/tty.js generated vendored Executable file
View File

@@ -0,0 +1,22 @@
"use strict";
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.isTTY = isTTY;
function _isTruthy(value) {
// Returns true if value is a string that is anything but 0 or false.
return value !== undefined && value !== '0' && value.toUpperCase() !== 'FALSE';
}
function isTTY() {
// If we force TTY, we always return true.
const force = process.env['NG_FORCE_TTY'];
if (force !== undefined) {
return _isTruthy(force);
}
return !!process.stdout.isTTY && !_isTruthy(process.env['CI']);
}