UNPKG

react-klasha

Version:

This is an reactJS library for implementing klasha payment gateway

1,231 lines (1,189 loc) 44.5 kB
/*! Stencil CLI v2.6.0 | MIT Licensed | https://stenciljs.com */ const toLowerCase = (str) => str.toLowerCase(); const dashToPascalCase = (str) => toLowerCase(str) .split('-') .map(segment => segment.charAt(0).toUpperCase() + segment.slice(1)) .join(''); const isFunction = (v) => typeof v === 'function'; const isString = (v) => typeof v === 'string'; const buildError = (diagnostics) => { const diagnostic = { level: 'error', type: 'build', header: 'Build Error', messageText: 'build error', relFilePath: null, absFilePath: null, lines: [], }; if (diagnostics) { diagnostics.push(diagnostic); } return diagnostic; }; const catchError = (diagnostics, err, msg) => { const diagnostic = { level: 'error', type: 'build', header: 'Build Error', messageText: 'build error', relFilePath: null, absFilePath: null, lines: [], }; if (isString(msg)) { diagnostic.messageText = msg; } else if (err != null) { if (err.stack != null) { diagnostic.messageText = err.stack.toString(); } else { if (err.message != null) { diagnostic.messageText = err.message.toString(); } else { diagnostic.messageText = err.toString(); } } } if (diagnostics != null && !shouldIgnoreError(diagnostic.messageText)) { diagnostics.push(diagnostic); } return diagnostic; }; const hasError = (diagnostics) => { if (diagnostics == null || diagnostics.length === 0) { return false; } return diagnostics.some(d => d.level === 'error' && d.type !== 'runtime'); }; const shouldIgnoreError = (msg) => { return msg === TASK_CANCELED_MSG; }; const TASK_CANCELED_MSG = `task canceled`; /** * Convert Windows backslash paths to slash paths: foo\\bar ➔ foo/bar * Forward-slash paths can be used in Windows as long as they're not * extended-length paths and don't contain any non-ascii characters. * This was created since the path methods in Node.js outputs \\ paths on Windows. */ const normalizePath = (path) => { if (typeof path !== 'string') { throw new Error(`invalid path to normalize`); } path = normalizeSlashes(path.trim()); const components = pathComponents(path, getRootLength(path)); const reducedComponents = reducePathComponents(components); const rootPart = reducedComponents[0]; const secondPart = reducedComponents[1]; const normalized = rootPart + reducedComponents.slice(1).join('/'); if (normalized === '') { return '.'; } if (rootPart === '' && secondPart && path.includes('/') && !secondPart.startsWith('.') && !secondPart.startsWith('@')) { return './' + normalized; } return normalized; }; const normalizeSlashes = (path) => path.replace(backslashRegExp, '/'); const altDirectorySeparator = '\\'; const urlSchemeSeparator = '://'; const backslashRegExp = /\\/g; const reducePathComponents = (components) => { if (!Array.isArray(components) || components.length === 0) { return []; } const reduced = [components[0]]; for (let i = 1; i < components.length; i++) { const component = components[i]; if (!component) continue; if (component === '.') continue; if (component === '..') { if (reduced.length > 1) { if (reduced[reduced.length - 1] !== '..') { reduced.pop(); continue; } } else if (reduced[0]) continue; } reduced.push(component); } return reduced; }; const getRootLength = (path) => { const rootLength = getEncodedRootLength(path); return rootLength < 0 ? ~rootLength : rootLength; }; const getEncodedRootLength = (path) => { if (!path) return 0; const ch0 = path.charCodeAt(0); // POSIX or UNC if (ch0 === 47 /* slash */ || ch0 === 92 /* backslash */) { if (path.charCodeAt(1) !== ch0) return 1; // POSIX: "/" (or non-normalized "\") const p1 = path.indexOf(ch0 === 47 /* slash */ ? '/' : altDirectorySeparator, 2); if (p1 < 0) return path.length; // UNC: "//server" or "\\server" return p1 + 1; // UNC: "//server/" or "\\server\" } // DOS if (isVolumeCharacter(ch0) && path.charCodeAt(1) === 58 /* colon */) { const ch2 = path.charCodeAt(2); if (ch2 === 47 /* slash */ || ch2 === 92 /* backslash */) return 3; // DOS: "c:/" or "c:\" if (path.length === 2) return 2; // DOS: "c:" (but not "c:d") } // URL const schemeEnd = path.indexOf(urlSchemeSeparator); if (schemeEnd !== -1) { const authorityStart = schemeEnd + urlSchemeSeparator.length; const authorityEnd = path.indexOf('/', authorityStart); if (authorityEnd !== -1) { // URL: "file:///", "file://server/", "file://server/path" // For local "file" URLs, include the leading DOS volume (if present). // Per https://www.ietf.org/rfc/rfc1738.txt, a host of "" or "localhost" is a // special case interpreted as "the machine from which the URL is being interpreted". const scheme = path.slice(0, schemeEnd); const authority = path.slice(authorityStart, authorityEnd); if (scheme === 'file' && (authority === '' || authority === 'localhost') && isVolumeCharacter(path.charCodeAt(authorityEnd + 1))) { const volumeSeparatorEnd = getFileUrlVolumeSeparatorEnd(path, authorityEnd + 2); if (volumeSeparatorEnd !== -1) { if (path.charCodeAt(volumeSeparatorEnd) === 47 /* slash */) { // URL: "file:///c:/", "file://localhost/c:/", "file:///c%3a/", "file://localhost/c%3a/" return ~(volumeSeparatorEnd + 1); } if (volumeSeparatorEnd === path.length) { // URL: "file:///c:", "file://localhost/c:", "file:///c$3a", "file://localhost/c%3a" // but not "file:///c:d" or "file:///c%3ad" return ~volumeSeparatorEnd; } } } return ~(authorityEnd + 1); // URL: "file://server/", "http://server/" } return ~path.length; // URL: "file://server", "http://server" } // relative return 0; }; const isVolumeCharacter = (charCode) => (charCode >= 97 /* a */ && charCode <= 122 /* z */) || (charCode >= 65 /* A */ && charCode <= 90 /* Z */); const getFileUrlVolumeSeparatorEnd = (url, start) => { const ch0 = url.charCodeAt(start); if (ch0 === 58 /* colon */) return start + 1; if (ch0 === 37 /* percent */ && url.charCodeAt(start + 1) === 51 /* _3 */) { const ch2 = url.charCodeAt(start + 2); if (ch2 === 97 /* a */ || ch2 === 65 /* A */) return start + 3; } return -1; }; const pathComponents = (path, rootLength) => { const root = path.substring(0, rootLength); const rest = path.substring(rootLength).split('/'); const restLen = rest.length; if (restLen > 0 && !rest[restLen - 1]) { rest.pop(); } return [root, ...rest]; }; const validateComponentTag = (tag) => { if (tag !== tag.trim()) { return `Tag can not contain white spaces`; } if (tag !== tag.toLowerCase()) { return `Tag can not contain upper case characters`; } if (typeof tag !== 'string') { return `Tag "${tag}" must be a string type`; } if (tag.length === 0) { return `Received empty tag value`; } if (tag.indexOf(' ') > -1) { return `"${tag}" tag cannot contain a space`; } if (tag.indexOf(',') > -1) { return `"${tag}" tag cannot be used for multiple tags`; } const invalidChars = tag.replace(/\w|-/g, ''); if (invalidChars !== '') { return `"${tag}" tag contains invalid characters: ${invalidChars}`; } if (tag.indexOf('-') === -1) { return `"${tag}" tag must contain a dash (-) to work as a valid web component`; } if (tag.indexOf('--') > -1) { return `"${tag}" tag cannot contain multiple dashes (--) next to each other`; } if (tag.indexOf('-') === 0) { return `"${tag}" tag cannot start with a dash (-)`; } if (tag.lastIndexOf('-') === tag.length - 1) { return `"${tag}" tag cannot end with a dash (-)`; } return undefined; }; const parseFlags = (args, sys) => { const flags = { task: null, args: [], knownArgs: [], unknownArgs: null, }; // cmd line has more priority over npm scripts cmd flags.args = args.slice(); if (flags.args.length > 0 && flags.args[0] && !flags.args[0].startsWith('-')) { flags.task = flags.args[0]; } parseArgs(flags, flags.args, flags.knownArgs); if (sys && sys.name === 'node') { const envArgs = getNpmConfigEnvArgs(sys); parseArgs(flags, envArgs, flags.knownArgs); envArgs.forEach(envArg => { if (!flags.args.includes(envArg)) { flags.args.push(envArg); } }); } if (flags.task != null) { const i = flags.args.indexOf(flags.task); if (i > -1) { flags.args.splice(i, 1); } } flags.unknownArgs = flags.args.filter((arg) => { return !flags.knownArgs.includes(arg); }); return flags; }; const parseArgs = (flags, args, knownArgs) => { ARG_OPTS.boolean.forEach(booleanName => { const alias = ARG_OPTS.alias[booleanName]; const flagKey = configCase(booleanName); if (typeof flags[flagKey] !== 'boolean') { flags[flagKey] = null; } args.forEach(cmdArg => { if (cmdArg === `--${booleanName}`) { flags[flagKey] = true; knownArgs.push(cmdArg); } else if (cmdArg === `--${flagKey}`) { flags[flagKey] = true; knownArgs.push(cmdArg); } else if (cmdArg === `--no-${booleanName}`) { flags[flagKey] = false; knownArgs.push(cmdArg); } else if (cmdArg === `--no${dashToPascalCase(booleanName)}`) { flags[flagKey] = false; knownArgs.push(cmdArg); } else if (alias && cmdArg === `-${alias}`) { flags[flagKey] = true; knownArgs.push(cmdArg); } }); }); ARG_OPTS.string.forEach(stringName => { const alias = ARG_OPTS.alias[stringName]; const flagKey = configCase(stringName); if (typeof flags[flagKey] !== 'string') { flags[flagKey] = null; } for (let i = 0; i < args.length; i++) { const cmdArg = args[i]; if (cmdArg.startsWith(`--${stringName}=`)) { const values = cmdArg.split('='); values.shift(); flags[flagKey] = values.join('='); knownArgs.push(cmdArg); } else if (cmdArg === `--${stringName}`) { flags[flagKey] = args[i + 1]; knownArgs.push(cmdArg); knownArgs.push(args[i + 1]); } else if (cmdArg === `--${flagKey}`) { flags[flagKey] = args[i + 1]; knownArgs.push(cmdArg); knownArgs.push(args[i + 1]); } else if (cmdArg.startsWith(`--${flagKey}=`)) { const values = cmdArg.split('='); values.shift(); flags[flagKey] = values.join('='); knownArgs.push(cmdArg); } else if (alias) { if (cmdArg.startsWith(`-${alias}=`)) { const values = cmdArg.split('='); values.shift(); flags[flagKey] = values.join('='); knownArgs.push(cmdArg); } else if (cmdArg === `-${alias}`) { flags[flagKey] = args[i + 1]; knownArgs.push(args[i + 1]); } } } }); ARG_OPTS.number.forEach(numberName => { const alias = ARG_OPTS.alias[numberName]; const flagKey = configCase(numberName); if (typeof flags[flagKey] !== 'number') { flags[flagKey] = null; } for (let i = 0; i < args.length; i++) { const cmdArg = args[i]; if (cmdArg.startsWith(`--${numberName}=`)) { const values = cmdArg.split('='); values.shift(); flags[flagKey] = parseInt(values.join(''), 10); knownArgs.push(cmdArg); } else if (cmdArg === `--${numberName}`) { flags[flagKey] = parseInt(args[i + 1], 10); knownArgs.push(args[i + 1]); } else if (cmdArg.startsWith(`--${flagKey}=`)) { const values = cmdArg.split('='); values.shift(); flags[flagKey] = parseInt(values.join(''), 10); knownArgs.push(cmdArg); } else if (cmdArg === `--${flagKey}`) { flags[flagKey] = parseInt(args[i + 1], 10); knownArgs.push(args[i + 1]); } else if (alias) { if (cmdArg.startsWith(`-${alias}=`)) { const values = cmdArg.split('='); values.shift(); flags[flagKey] = parseInt(values.join(''), 10); knownArgs.push(cmdArg); } else if (cmdArg === `-${alias}`) { flags[flagKey] = parseInt(args[i + 1], 10); knownArgs.push(args[i + 1]); } } } }); }; const configCase = (prop) => { prop = dashToPascalCase(prop); return prop.charAt(0).toLowerCase() + prop.substr(1); }; const ARG_OPTS = { boolean: [ 'build', 'cache', 'check-version', 'ci', 'compare', 'debug', 'dev', 'devtools', 'docs', 'e2e', 'es5', 'esm', 'headless', 'help', 'log', 'open', 'prerender', 'prerender-external', 'prod', 'profile', 'service-worker', 'screenshot', 'serve', 'skip-node-check', 'spec', 'ssr', 'stats', 'update-screenshot', 'verbose', 'version', 'watch', ], number: ['max-workers', 'port'], string: ['address', 'config', 'docs-json', 'emulate', 'log-level', 'root', 'screenshot-connector'], alias: { config: 'c', help: 'h', port: 'p', version: 'v', }, }; const getNpmConfigEnvArgs = (sys) => { // process.env.npm_config_argv // {"remain":["4444"],"cooked":["run","serve","--port","4444"],"original":["run","serve","--port","4444"]} let args = []; try { const npmConfigArgs = sys.getEnvironmentVar('npm_config_argv'); if (npmConfigArgs) { args = JSON.parse(npmConfigArgs).original; if (args[0] === 'run') { args = args.slice(2); } } } catch (e) { } return args; }; const dependencies = [ { name: "@stencil/core", version: "2.6.0", main: "compiler/stencil.js", resources: [ "package.json", "compiler/lib.d.ts", "compiler/lib.dom.d.ts", "compiler/lib.dom.iterable.d.ts", "compiler/lib.es2015.collection.d.ts", "compiler/lib.es2015.core.d.ts", "compiler/lib.es2015.d.ts", "compiler/lib.es2015.generator.d.ts", "compiler/lib.es2015.iterable.d.ts", "compiler/lib.es2015.promise.d.ts", "compiler/lib.es2015.proxy.d.ts", "compiler/lib.es2015.reflect.d.ts", "compiler/lib.es2015.symbol.d.ts", "compiler/lib.es2015.symbol.wellknown.d.ts", "compiler/lib.es2016.array.include.d.ts", "compiler/lib.es2016.d.ts", "compiler/lib.es2016.full.d.ts", "compiler/lib.es2017.d.ts", "compiler/lib.es2017.full.d.ts", "compiler/lib.es2017.intl.d.ts", "compiler/lib.es2017.object.d.ts", "compiler/lib.es2017.sharedmemory.d.ts", "compiler/lib.es2017.string.d.ts", "compiler/lib.es2017.typedarrays.d.ts", "compiler/lib.es2018.asyncgenerator.d.ts", "compiler/lib.es2018.asynciterable.d.ts", "compiler/lib.es2018.d.ts", "compiler/lib.es2018.full.d.ts", "compiler/lib.es2018.intl.d.ts", "compiler/lib.es2018.promise.d.ts", "compiler/lib.es2018.regexp.d.ts", "compiler/lib.es2019.array.d.ts", "compiler/lib.es2019.d.ts", "compiler/lib.es2019.full.d.ts", "compiler/lib.es2019.object.d.ts", "compiler/lib.es2019.string.d.ts", "compiler/lib.es2019.symbol.d.ts", "compiler/lib.es2020.bigint.d.ts", "compiler/lib.es2020.d.ts", "compiler/lib.es2020.full.d.ts", "compiler/lib.es2020.intl.d.ts", "compiler/lib.es2020.promise.d.ts", "compiler/lib.es2020.sharedmemory.d.ts", "compiler/lib.es2020.string.d.ts", "compiler/lib.es2020.symbol.wellknown.d.ts", "compiler/lib.es5.d.ts", "compiler/lib.es6.d.ts", "compiler/lib.esnext.d.ts", "compiler/lib.esnext.full.d.ts", "compiler/lib.esnext.intl.d.ts", "compiler/lib.esnext.promise.d.ts", "compiler/lib.esnext.string.d.ts", "compiler/lib.esnext.weakref.d.ts", "compiler/lib.scripthost.d.ts", "compiler/lib.webworker.d.ts", "compiler/lib.webworker.importscripts.d.ts", "compiler/lib.webworker.iterable.d.ts", "internal/index.d.ts", "internal/index.js", "internal/package.json", "internal/stencil-ext-modules.d.ts", "internal/stencil-private.d.ts", "internal/stencil-public-compiler.d.ts", "internal/stencil-public-docs.d.ts", "internal/stencil-public-runtime.d.ts", "mock-doc/index.js", "mock-doc/package.json", "internal/client/css-shim.js", "internal/client/dom.js", "internal/client/index.js", "internal/client/package.json", "internal/client/patch-browser.js", "internal/client/patch-esm.js", "internal/client/shadow-css.js", "internal/hydrate/index.js", "internal/hydrate/package.json", "internal/hydrate/runner.js", "internal/hydrate/shadow-css.js", "internal/stencil-core/index.d.ts", "internal/stencil-core/index.js" ] }, { name: "rollup", version: "2.42.3", main: "dist/es/rollup.browser.js" }, { name: "terser", version: "5.6.1", main: "dist/bundle.min.js" }, { name: "typescript", version: "4.2.3", main: "lib/typescript.js" } ]; const findConfig = async (opts) => { const sys = opts.sys; const cwd = sys.getCurrentDirectory(); const results = { configPath: null, rootDir: normalizePath(cwd), diagnostics: [], }; let configPath = opts.configPath; if (isString(configPath)) { if (!sys.platformPath.isAbsolute(configPath)) { // passed in a custom stencil config location // but it's relative, so prefix the cwd configPath = normalizePath(sys.platformPath.join(cwd, configPath)); } else { // config path already an absolute path, we're good here configPath = normalizePath(opts.configPath); } } else { // nothing was passed in, use the current working directory configPath = results.rootDir; } const stat = await sys.stat(configPath); if (stat.error) { const diagnostic = buildError(results.diagnostics); diagnostic.absFilePath = configPath; diagnostic.header = `Invalid config path`; diagnostic.messageText = `Config path "${configPath}" not found`; return results; } if (stat.isFile) { results.configPath = configPath; results.rootDir = sys.platformPath.dirname(configPath); } else if (stat.isDirectory) { // this is only a directory, so let's make some assumptions for (const configName of ['stencil.config.ts', 'stencil.config.js']) { const testConfigFilePath = sys.platformPath.join(configPath, configName); const stat = await sys.stat(testConfigFilePath); if (stat.isFile) { results.configPath = testConfigFilePath; results.rootDir = sys.platformPath.dirname(testConfigFilePath); break; } } } return results; }; const loadCoreCompiler = async (sys) => { await sys.dynamicImport(sys.getCompilerExecutingPath()); return globalThis.stencil; }; const startupLog = (logger, task) => { if (task === 'info' || task === 'serve' || task === 'version') { return; } logger.info(logger.cyan(`@stencil/core`)); }; const startupLogVersion = (logger, task, coreCompiler) => { if (task === 'info' || task === 'serve' || task === 'version') { return; } const isDevBuild = coreCompiler.version.includes('-dev.'); let startupMsg; if (isDevBuild) { startupMsg = logger.yellow('[LOCAL DEV]'); } else { startupMsg = logger.cyan(`v${coreCompiler.version}`); } startupMsg += logger.emoji(' ' + coreCompiler.vermoji); logger.info(startupMsg); }; const loadedCompilerLog = (sys, logger, flags, coreCompiler) => { const sysDetails = sys.details; const runtimeInfo = `${sys.name} ${sys.version}`; const platformInfo = `${sysDetails.platform}, ${sysDetails.cpuModel}`; const statsInfo = `cpus: ${sys.hardwareConcurrency}, freemem: ${Math.round(sysDetails.freemem() / 1000000)}MB, totalmem: ${Math.round(sysDetails.totalmem / 1000000)}MB`; if (logger.getLevel() === 'debug') { logger.debug(runtimeInfo); logger.debug(platformInfo); logger.debug(statsInfo); logger.debug(`compiler: ${sys.getCompilerExecutingPath()}`); logger.debug(`build: ${coreCompiler.buildId}`); } else if (flags.ci) { logger.info(runtimeInfo); logger.info(platformInfo); logger.info(statsInfo); } }; const startupCompilerLog = (coreCompiler, config) => { if (config.suppressLogs === true) { return; } const { logger } = config; const isDebug = logger.getLevel() === 'debug'; const isPrerelease = coreCompiler.version.includes('-'); const isDevBuild = coreCompiler.version.includes('-dev.'); if (isPrerelease && !isDevBuild) { logger.warn(logger.yellow(`This is a prerelease build, undocumented changes might happen at any time. Technical support is not available for prereleases, but any assistance testing is appreciated.`)); } if (config.devMode && !isDebug) { if (config.buildEs5) { logger.warn(`Generating ES5 during development is a very task expensive, initial and incremental builds will be much slower. Drop the '--es5' flag and use a modern browser for development.`); } if (!config.enableCache) { logger.warn(`Disabling cache during development will slow down incremental builds.`); } } }; const taskPrerender = async (coreCompiler, config) => { startupCompilerLog(coreCompiler, config); const hydrateAppFilePath = config.flags.unknownArgs[0]; if (typeof hydrateAppFilePath !== 'string') { config.logger.error(`Missing hydrate app script path`); return config.sys.exit(1); } const srcIndexHtmlPath = config.srcIndexHtml; const diagnostics = await runPrerenderTask(coreCompiler, config, hydrateAppFilePath, null, srcIndexHtmlPath); config.logger.printDiagnostics(diagnostics); if (diagnostics.some(d => d.level === 'error')) { return config.sys.exit(1); } }; const runPrerenderTask = async (coreCompiler, config, hydrateAppFilePath, componentGraph, srcIndexHtmlPath) => { const diagnostics = []; try { const prerenderer = await coreCompiler.createPrerenderer(config); const results = await prerenderer.start({ hydrateAppFilePath, componentGraph, srcIndexHtmlPath, }); diagnostics.push(...results.diagnostics); } catch (e) { catchError(diagnostics, e); } return diagnostics; }; const startCheckVersion = async (config, currentVersion) => { if (config.devMode && !config.flags.ci && !currentVersion.includes('-dev.') && isFunction(config.sys.checkVersion)) { return config.sys.checkVersion(config.logger, currentVersion); } return null; }; const printCheckVersionResults = async (versionChecker) => { if (versionChecker) { const checkVersionResults = await versionChecker; if (isFunction(checkVersionResults)) { checkVersionResults(); } } }; const taskWatch = async (coreCompiler, config) => { let devServer = null; let exitCode = 0; try { startupCompilerLog(coreCompiler, config); const versionChecker = startCheckVersion(config, coreCompiler.version); const compiler = await coreCompiler.createCompiler(config); const watcher = await compiler.createWatcher(); if (config.flags.serve) { const devServerPath = config.sys.getDevServerExecutingPath(); const { start } = await config.sys.dynamicImport(devServerPath); devServer = await start(config.devServer, config.logger, watcher); } config.sys.onProcessInterrupt(() => { config.logger.debug(`close watch`); compiler && compiler.destroy(); }); const rmVersionCheckerLog = watcher.on('buildFinish', async () => { // log the version check one time rmVersionCheckerLog(); printCheckVersionResults(versionChecker); }); if (devServer) { const rmDevServerLog = watcher.on('buildFinish', () => { // log the dev server url one time rmDevServerLog(); config.logger.info(`${config.logger.cyan(devServer.browserUrl)}\n`); }); } const closeResults = await watcher.start(); if (closeResults.exitCode > 0) { exitCode = closeResults.exitCode; } } catch (e) { exitCode = 1; config.logger.error(e); } if (devServer) { await devServer.close(); } if (exitCode > 0) { return config.sys.exit(exitCode); } }; const taskBuild = async (coreCompiler, config) => { if (config.flags.watch) { // watch build await taskWatch(coreCompiler, config); return; } // one-time build let exitCode = 0; try { startupCompilerLog(coreCompiler, config); const versionChecker = startCheckVersion(config, coreCompiler.version); const compiler = await coreCompiler.createCompiler(config); const results = await compiler.build(); await compiler.destroy(); if (results.hasError) { exitCode = 1; } else if (config.flags.prerender) { const prerenderDiagnostics = await runPrerenderTask(coreCompiler, config, results.hydrateAppFilePath, results.componentGraph, null); config.logger.printDiagnostics(prerenderDiagnostics); if (prerenderDiagnostics.some(d => d.level === 'error')) { exitCode = 1; } } await printCheckVersionResults(versionChecker); } catch (e) { exitCode = 1; config.logger.error(e); } if (exitCode > 0) { return config.sys.exit(exitCode); } }; const isOutputTargetDocs = (o) => o.type === DOCS_README || o.type === DOCS_JSON || o.type === DOCS_CUSTOM || o.type === DOCS_VSCODE; const DOCS_CUSTOM = 'docs-custom'; const DOCS_JSON = `docs-json`; const DOCS_README = `docs-readme`; const DOCS_VSCODE = `docs-vscode`; const taskDocs = async (coreCompiler, config) => { config.devServer = null; config.outputTargets = config.outputTargets.filter(isOutputTargetDocs); config.devMode = true; startupCompilerLog(coreCompiler, config); const compiler = await coreCompiler.createCompiler(config); await compiler.build(); await compiler.destroy(); }; const IS_DENO_ENV = typeof Deno !== 'undefined'; const IS_NODE_ENV = !IS_DENO_ENV && typeof global !== 'undefined' && typeof require === 'function' && !!global.process && typeof __filename === 'string' && (!global.origin || typeof global.origin !== 'string'); /** * Task to generate component boilerplate. */ const taskGenerate = async (coreCompiler, config) => { if (!IS_NODE_ENV) { config.logger.error(`"generate" command is currently only implemented for a NodeJS environment`); return config.sys.exit(1); } const path = coreCompiler.path; if (!config.configPath) { config.logger.error('Please run this command in your root directory (i. e. the one containing stencil.config.ts).'); return config.sys.exit(1); } const absoluteSrcDir = config.srcDir; if (!absoluteSrcDir) { config.logger.error(`Stencil's srcDir was not specified.`); return config.sys.exit(1); } const { prompt } = await import('../sys/node/prompts.js'); const input = config.flags.unknownArgs.find(arg => !arg.startsWith('-')) || (await prompt({ name: 'tagName', type: 'text', message: 'Component tag name (dash-case):' })).tagName; const { dir, base: componentName } = path.parse(input); const tagError = validateComponentTag(componentName); if (tagError) { config.logger.error(tagError); return config.sys.exit(1); } const extensionsToGenerate = ['tsx', ...(await chooseFilesToGenerate())]; const testFolder = extensionsToGenerate.some(isTest) ? 'test' : ''; const outDir = path.join(absoluteSrcDir, 'components', dir, componentName); await config.sys.createDir(path.join(outDir, testFolder), { recursive: true }); const writtenFiles = await Promise.all(extensionsToGenerate.map(extension => writeFileByExtension(coreCompiler, config, outDir, componentName, extension, extensionsToGenerate.includes('css')))).catch(error => config.logger.error(error)); if (!writtenFiles) { return config.sys.exit(1); } console.log(); console.log(`${config.logger.gray('$')} stencil generate ${input}`); console.log(); console.log(config.logger.bold('The following files have been generated:')); const absoluteRootDir = config.rootDir; writtenFiles.map(file => console.log(` - ${path.relative(absoluteRootDir, file)}`)); }; /** * Show a checkbox prompt to select the files to be generated. */ const chooseFilesToGenerate = async () => { const { prompt } = await import('../sys/node/prompts.js'); return (await prompt({ name: 'filesToGenerate', type: 'multiselect', message: 'Which additional files do you want to generate?', choices: [ { value: 'css', title: 'Stylesheet (.css)', selected: true }, { value: 'spec.tsx', title: 'Spec Test (.spec.tsx)', selected: true }, { value: 'e2e.ts', title: 'E2E Test (.e2e.ts)', selected: true }, ], })).filesToGenerate; }; /** * Get a file's boilerplate by its extension and write it to disk. */ const writeFileByExtension = async (coreCompiler, config, path, name, extension, withCss) => { if (isTest(extension)) { path = coreCompiler.path.join(path, 'test'); } const outFile = coreCompiler.path.join(path, `${name}.${extension}`); const boilerplate = getBoilerplateByExtension(name, extension, withCss); await config.sys.writeFile(outFile, boilerplate); return outFile; }; const isTest = (extension) => { return extension === 'e2e.ts' || extension === 'spec.tsx'; }; /** * Get the boilerplate for a file by its extension. */ const getBoilerplateByExtension = (tagName, extension, withCss) => { switch (extension) { case 'tsx': return getComponentBoilerplate(tagName, withCss); case 'css': return getStyleUrlBoilerplate(); case 'spec.tsx': return getSpecTestBoilerplate(tagName); case 'e2e.ts': return getE2eTestBoilerplate(tagName); default: throw new Error(`Unkown extension "${extension}".`); } }; /** * Get the boilerplate for a component. */ const getComponentBoilerplate = (tagName, hasStyle) => { const decorator = [`{`]; decorator.push(` tag: '${tagName}',`); if (hasStyle) { decorator.push(` styleUrl: '${tagName}.css',`); } decorator.push(` shadow: true,`); decorator.push(`}`); return `import { Component, Host, h } from '@stencil/core'; @Component(${decorator.join('\n')}) export class ${toPascalCase(tagName)} { render() { return ( <Host> <slot></slot> </Host> ); } } `; }; /** * Get the boilerplate for style. */ const getStyleUrlBoilerplate = () => `:host { display: block; } `; /** * Get the boilerplate for a spec test. */ const getSpecTestBoilerplate = (tagName) => `import { newSpecPage } from '@stencil/core/testing'; import { ${toPascalCase(tagName)} } from '../${tagName}'; describe('${tagName}', () => { it('renders', async () => { const page = await newSpecPage({ components: [${toPascalCase(tagName)}], html: \`<${tagName}></${tagName}>\`, }); expect(page.root).toEqualHtml(\` <${tagName}> <mock:shadow-root> <slot></slot> </mock:shadow-root> </${tagName}> \`); }); }); `; /** * Get the boilerplate for an E2E test. */ const getE2eTestBoilerplate = (name) => `import { newE2EPage } from '@stencil/core/testing'; describe('${name}', () => { it('renders', async () => { const page = await newE2EPage(); await page.setContent('<${name}></${name}>'); const element = await page.find('${name}'); expect(element).toHaveClass('hydrated'); }); }); `; /** * Convert a dash case string to pascal case. */ const toPascalCase = (str) => str.split('-').reduce((res, part) => res + part[0].toUpperCase() + part.substr(1), ''); const taskHelp = (sys, logger) => { const p = logger.dim(sys.details.platform === 'windows' ? '>' : '$'); console.log(` ${logger.bold('Build:')} ${logger.dim('Build components for development or production.')} ${p} ${logger.green('stencil build [--dev] [--watch] [--prerender] [--debug]')} ${logger.cyan('--dev')} ${logger.dim('.............')} Development build ${logger.cyan('--watch')} ${logger.dim('...........')} Rebuild when files update ${logger.cyan('--serve')} ${logger.dim('...........')} Start the dev-server ${logger.cyan('--prerender')} ${logger.dim('.......')} Prerender the application ${logger.cyan('--docs')} ${logger.dim('............')} Generate component readme.md docs ${logger.cyan('--config')} ${logger.dim('..........')} Set stencil config file ${logger.cyan('--stats')} ${logger.dim('...........')} Write stencil-stats.json file ${logger.cyan('--log')} ${logger.dim('.............')} Write stencil-build.log file ${logger.cyan('--debug')} ${logger.dim('...........')} Set the log level to debug ${logger.bold('Test:')} ${logger.dim('Run unit and end-to-end tests.')} ${p} ${logger.green('stencil test [--spec] [--e2e]')} ${logger.cyan('--spec')} ${logger.dim('............')} Run unit tests with Jest ${logger.cyan('--e2e')} ${logger.dim('.............')} Run e2e tests with Puppeteer ${logger.bold('Generate:')} ${logger.dim('Bootstrap components.')} ${p} ${logger.green('stencil generate')} or ${logger.green('stencil g')} ${logger.bold('Examples:')} ${p} ${logger.green('stencil build --dev --watch --serve')} ${p} ${logger.green('stencil build --prerender')} ${p} ${logger.green('stencil test --spec --e2e')} ${p} ${logger.green('stencil generate')} ${p} ${logger.green('stencil g my-component')} `); }; const taskInfo = (coreCompiler, sys, logger) => { const details = sys.details; const versions = coreCompiler.versions; console.log(``); console.log(`${logger.cyan(' System:')} ${sys.name} ${sys.version}`); console.log(`${logger.cyan(' Plaform:')} ${details.platform} (${details.release})`); console.log(`${logger.cyan(' CPU Model:')} ${details.cpuModel} (${sys.hardwareConcurrency} cpu${sys.hardwareConcurrency !== 1 ? 's' : ''})`); console.log(`${logger.cyan(' Compiler:')} ${sys.getCompilerExecutingPath()}`); console.log(`${logger.cyan(' Build:')} ${coreCompiler.buildId}`); console.log(`${logger.cyan(' Stencil:')} ${coreCompiler.version}${logger.emoji(' ' + coreCompiler.vermoji)}`); console.log(`${logger.cyan(' TypeScript:')} ${versions.typescript}`); console.log(`${logger.cyan(' Rollup:')} ${versions.rollup}`); console.log(`${logger.cyan(' Parse5:')} ${versions.parse5}`); console.log(`${logger.cyan(' Sizzle:')} ${versions.sizzle}`); console.log(`${logger.cyan(' Terser:')} ${versions.terser}`); console.log(``); }; const taskServe = async (config) => { config.suppressLogs = true; config.flags.serve = true; config.devServer.openBrowser = config.flags.open; config.devServer.reloadStrategy = null; config.devServer.initialLoadUrl = '/'; config.devServer.websocket = false; config.maxConcurrentWorkers = 1; config.devServer.root = isString(config.flags.root) ? config.flags.root : config.sys.getCurrentDirectory(); const devServerPath = config.sys.getDevServerExecutingPath(); const { start } = await config.sys.dynamicImport(devServerPath); const devServer = await start(config.devServer, config.logger); console.log(`${config.logger.cyan(' Root:')} ${devServer.root}`); console.log(`${config.logger.cyan(' Address:')} ${devServer.address}`); console.log(`${config.logger.cyan(' Port:')} ${devServer.port}`); console.log(`${config.logger.cyan(' Server:')} ${devServer.browserUrl}`); console.log(``); config.sys.onProcessInterrupt(() => { if (devServer) { config.logger.debug(`dev server close: ${devServer.browserUrl}`); devServer.close(); } }); }; const taskTest = async (config) => { if (!IS_NODE_ENV) { config.logger.error(`"test" command is currently only implemented for a NodeJS environment`); return config.sys.exit(1); } try { config.buildDocs = false; const testingRunOpts = { e2e: !!config.flags.e2e, screenshot: !!config.flags.screenshot, spec: !!config.flags.spec, updateScreenshot: !!config.flags.updateScreenshot, }; // always ensure we have jest modules installed const ensureModuleIds = ['@types/jest', 'jest', 'jest-cli']; if (testingRunOpts.e2e) { // if it's an e2e test, also make sure we're got // puppeteer modules installed and if browserExecutablePath is provided don't download Chromium use only puppeteer-core instead const puppeteer = config.testing.browserExecutablePath ? 'puppeteer-core' : 'puppeteer'; ensureModuleIds.push('@types/puppeteer', puppeteer); if (testingRunOpts.screenshot) { // ensure we've got pixelmatch for screenshots config.logger.warn(config.logger.yellow(`EXPERIMENTAL: screenshot visual diff testing is currently under heavy development and has not reached a stable status. However, any assistance testing would be appreciated.`)); } } // ensure we've got the required modules installed const diagnostics = await config.sys.lazyRequire.ensure(config.rootDir, ensureModuleIds); if (diagnostics.length > 0) { config.logger.printDiagnostics(diagnostics); return config.sys.exit(1); } // let's test! const { createTesting } = await import('../testing/index.js'); const testing = await createTesting(config); const passed = await testing.run(testingRunOpts); await testing.destroy(); if (!passed) { return config.sys.exit(1); } } catch (e) { config.logger.error(e); return config.sys.exit(1); } }; const run = async (init) => { const { args, logger, sys } = init; try { const flags = parseFlags(args, sys); const task = flags.task; if (flags.debug || flags.verbose) { logger.setLevel('debug'); } if (flags.ci) { logger.enableColors(false); } if (isFunction(sys.applyGlobalPatch)) { sys.applyGlobalPatch(sys.getCurrentDirectory()); } if (task === 'help' || flags.help) { taskHelp(sys, logger); return; } startupLog(logger, task); const findConfigResults = await findConfig({ sys, configPath: flags.config }); if (hasError(findConfigResults.diagnostics)) { logger.printDiagnostics(findConfigResults.diagnostics); return sys.exit(1); } const ensureDepsResults = await sys.ensureDependencies({ rootDir: findConfigResults.rootDir, logger, dependencies: dependencies, }); if (hasError(ensureDepsResults.diagnostics)) { logger.printDiagnostics(ensureDepsResults.diagnostics); return sys.exit(1); } const coreCompiler = await loadCoreCompiler(sys); if (task === 'version' || flags.version) { console.log(coreCompiler.version); return; } startupLogVersion(logger, task, coreCompiler); loadedCompilerLog(sys, logger, flags, coreCompiler); if (task === 'info') { taskInfo(coreCompiler, sys, logger); return; } const validated = await coreCompiler.loadConfig({ config: { flags, }, configPath: findConfigResults.configPath, logger, sys, }); if (validated.diagnostics.length > 0) { logger.printDiagnostics(validated.diagnostics); if (hasError(validated.diagnostics)) { return sys.exit(1); } } if (isFunction(sys.applyGlobalPatch)) { sys.applyGlobalPatch(validated.config.rootDir); } await sys.ensureResources({ rootDir: validated.config.rootDir, logger, dependencies: dependencies }); await runTask(coreCompiler, validated.config, task); } catch (e) { if (!shouldIgnoreError(e)) { logger.error(`uncaught cli error: ${e}${logger.getLevel() === 'debug' ? e.stack : ''}`); return sys.exit(1); } } }; const runTask = async (coreCompiler, config, task) => { config.flags = config.flags || {}; config.outputTargets = config.outputTargets || []; switch (task) { case 'build': await taskBuild(coreCompiler, config); break; case 'docs': await taskDocs(coreCompiler, config); break; case 'help': taskHelp(config.sys, config.logger); break; case 'generate': case 'g': await taskGenerate(coreCompiler, config); break; case 'prerender': await taskPrerender(coreCompiler, config); break; case 'serve': await taskServe(config); break; case 'test': await taskTest(config); break; case 'version': console.log(coreCompiler.version); break; default: config.logger.error(`${config.logger.emoji('❌ ')}Invalid stencil command, please see the options below:`); taskHelp(config.sys, config.logger); return config.sys.exit(1); } }; export { parseFlags, run, runTask };