PK›¶z[½$@@admin-reset.jsnuÕIw¶“'use strict'; const _ = require('lodash'); const inquirer = require('inquirer'); const strapi = require('../index'); const promptQuestions = [ { type: 'input', name: 'email', message: 'User email?' }, { type: 'password', name: 'password', message: 'New password?' }, { type: 'confirm', name: 'confirm', message: "Do you really want to reset this user's password?", }, ]; /** * Reset user's password * @param {Object} cmdOptions - command options * @param {string} cmdOptions.email - user's email * @param {string} cmdOptions.password - user's new password */ module.exports = async function(cmdOptions = {}) { const { email, password } = cmdOptions; if (_.isEmpty(email) && _.isEmpty(password) && process.stdin.isTTY) { const inquiry = await inquirer.prompt(promptQuestions); if (!inquiry.confirm) { process.exit(0); } return changePassword(inquiry); } if (_.isEmpty(email) || _.isEmpty(password)) { console.error('Missing required options `email` or `password`'); process.exit(1); } return changePassword({ email, password }); }; async function changePassword({ email, password }) { const app = await strapi().load(); await app.admin.services.user.resetPasswordByEmail(email, password); console.log(`Successfully reset user's password`); process.exit(0); } PK›¶z[Ō vn««build.jsnuÕIw¶“'use strict'; const { green } = require('chalk'); // eslint-disable-next-line node/no-extraneous-require const strapiAdmin = require('strapi-admin'); const { getConfigUrls } = require('strapi-utils'); const loadConfiguration = require('../core/app-configuration'); const ee = require('../utils/ee'); const addSlash = require('../utils/addSlash'); /** * `$ strapi build` */ module.exports = async ({ clean, optimization }) => { const dir = process.cwd(); const config = loadConfiguration(dir); const { serverUrl, adminPath } = getConfigUrls(config.get('server'), true); console.log(`Building your admin UI with ${green(config.environment)} configuration ...`); if (clean) { await strapiAdmin.clean({ dir }); } ee({ dir }); return strapiAdmin .build({ dir, // front end build env is always production for now env: 'production', optimize: optimization, options: { backend: serverUrl, publicPath: addSlash(adminPath), features: ee.isEE ? ee.features.getEnabled() : [], }, }) .then(() => { process.exit(); }) .catch(err => { console.error(err); process.exit(1); }); }; PK›¶z[ļ‘<•configurationDump.jsnuÕIw¶“'use strict'; const fs = require('fs'); const strapi = require('../index'); const CHUNK_SIZE = 100; /** * Will dump configurations to a file or stdout * @param {string} file filepath to use as output */ module.exports = async function({ file: filePath, pretty }) { const output = filePath ? fs.createWriteStream(filePath) : process.stdout; const app = await strapi().load(); const count = await app.query('core_store').count(); const exportData = []; const pageCount = Math.ceil(count / CHUNK_SIZE); for (let page = 0; page < pageCount; page++) { const results = await app .query('core_store') .find({ _limit: CHUNK_SIZE, _start: page * CHUNK_SIZE, _sort: 'key' }); results .filter(result => result.key.startsWith('plugin_')) .forEach(result => { exportData.push({ key: result.key, value: result.value, type: result.type, environment: result.environment, tag: result.tag, }); }); } output.write(JSON.stringify(exportData, null, pretty ? 2 : null)); output.write('\n'); output.end(); // log success only when writting to file if (filePath) { console.log(`Successfully exported ${exportData.length} configuration entries`); } process.exit(0); }; PK›¶z[£6)m¢¢configurationRestore.jsnuÕIw¶“'use strict'; const fs = require('fs'); const _ = require('lodash'); const strapi = require('../index'); /** * Will restore configurations. It reads from a file or stdin * @param {string} file filepath to use as input * @param {string} strategy import strategy. one of (replace, merge, keep, default: replace) */ module.exports = async function({ file: filePath, strategy = 'replace' }) { const input = filePath ? fs.readFileSync(filePath) : await readStdin(process.stdin); const app = await strapi().load(); let dataToImport; try { dataToImport = JSON.parse(input); } catch (error) { throw new Error(`Invalid input data: ${error.message}. Expected a valid JSON array.`); } if (!Array.isArray(dataToImport)) { throw new Error(`Invalid input data. Expected a valid JSON array.`); } const importer = createImporter(app.db, strategy); for (const config of dataToImport) { await importer.import(config); } console.log( `Successfully imported configuration with ${strategy} strategy. Statistics: ${importer.printStatistics()}.` ); process.exit(0); }; const readStdin = () => { const { stdin } = process; let result = ''; if (stdin.isTTY) return Promise.resolve(result); return new Promise((resolve, reject) => { stdin.setEncoding('utf8'); stdin.on('readable', () => { let chunk; while ((chunk = stdin.read())) { result += chunk; } }); stdin.on('end', () => { resolve(result); }); stdin.on('error', reject); }); }; const createImporter = (db, strategy) => { switch (strategy) { case 'replace': return createReplaceImporter(db); case 'merge': return createMergeImporter(db); case 'keep': return createKeepImporter(db); default: throw new Error(`No importer available for strategy "${strategy}"`); } }; /** * Replace importer. Will replace the keys that already exist and create the new ones * @param {Object} db - DatabaseManager instance */ const createReplaceImporter = db => { const stats = { created: 0, replaced: 0, }; return { printStatistics() { return `${stats.created} created, ${stats.replaced} replaced`; }, async import(conf) { const matching = await db.query('core_store').count({ key: conf.key }); if (matching > 0) { stats.replaced += 1; await db.query('core_store').update({ key: conf.key }, conf); } else { stats.created += 1; await db.query('core_store').create(conf); } }, }; }; /** * Merge importer. Will merge the keys that already exist with their new value and create the new ones * @param {Object} db - DatabaseManager instance */ const createMergeImporter = db => { const stats = { created: 0, merged: 0, }; return { printStatistics() { return `${stats.created} created, ${stats.merged} merged`; }, async import(conf) { const existingConf = await db.query('core_store').find({ key: conf.key }); if (existingConf) { stats.merged += 1; await db.query('core_store').update({ key: conf.key }, _.merge(existingConf, conf)); } else { stats.created += 1; await db.query('core_store').create(conf); } }, }; }; /** * Merge importer. Will keep the keys that already exist without changing them and create the new ones * @param {Object} db - DatabaseManager instance */ const createKeepImporter = db => { const stats = { created: 0, untouched: 0, }; return { printStatistics() { return `${stats.created} created, ${stats.untouched} untouched`; }, async import(conf) { const matching = await db.query('core_store').count({ key: conf.key }); if (matching > 0) { stats.untouched += 1; // if configuration already exists do not overwrite it return; } stats.created += 1; await db.query('core_store').create(conf); }, }; }; PK›¶z[O#zś console.jsnuÕIw¶“'use strict'; const REPL = require('repl'); const strapi = require('../index'); /** * `$ strapi console` */ module.exports = () => { // Now load up the Strapi framework for real. const app = strapi(); app.start(() => { const repl = REPL.start(app.config.info.name + ' > ' || 'strapi > '); // eslint-disable-line prefer-template repl.on('exit', function(err) { if (err) { app.log.error(err); process.exit(1); } app.server.destroy(); process.exit(0); }); }); }; PK›¶z[£DÜn¢¢ develop.jsnuÕIw¶“'use strict'; const path = require('path'); const cluster = require('cluster'); const fs = require('fs-extra'); const chokidar = require('chokidar'); const execa = require('execa'); const { logger } = require('strapi-utils'); const loadConfiguration = require('../core/app-configuration'); const strapi = require('../index'); /** * `$ strapi develop` * */ module.exports = async function({ build, watchAdmin, polling, browser }) { const dir = process.cwd(); const config = loadConfiguration(dir); const adminWatchIgnoreFiles = config.get('server.admin.watchIgnoreFiles', []); const serveAdminPanel = config.get('server.admin.serveAdminPanel', true); const buildExists = fs.existsSync(path.join(dir, 'build')); // Don't run the build process if the admin is in watch mode if (build && !watchAdmin && serveAdminPanel && !buildExists) { try { execa.shellSync('npm run -s build -- --no-optimization', { stdio: 'inherit', }); } catch (err) { process.exit(1); } } try { if (cluster.isMaster) { if (watchAdmin) { try { execa('npm', ['run', '-s', 'strapi', 'watch-admin', '--', '--browser', browser], { stdio: 'inherit', }); } catch (err) { process.exit(1); } } cluster.on('message', (worker, message) => { switch (message) { case 'reload': logger.info('The server is restarting\n'); worker.send('isKilled'); break; case 'kill': worker.kill(); cluster.fork(); break; case 'stop': worker.kill(); process.exit(1); default: return; } }); cluster.fork(); } if (cluster.isWorker) { const strapiInstance = strapi({ dir, autoReload: true, serveAdminPanel: watchAdmin ? false : true, }); watchFileChanges({ dir, strapiInstance, watchIgnoreFiles: adminWatchIgnoreFiles, polling, }); process.on('message', message => { switch (message) { case 'isKilled': strapiInstance.server.destroy(() => { process.send('kill'); }); break; default: // Do nothing. } }); return strapiInstance.start(); } } catch (e) { logger.error(e); process.exit(1); } }; /** * Init file watching to auto restart strapi app * @param {Object} options - Options object * @param {string} options.dir - This is the path where the app is located, the watcher will watch the files under this folder * @param {Strapi} options.strapi - Strapi instance * @param {array} options.watchIgnoreFiles - Array of custom file paths that should not be watched */ function watchFileChanges({ dir, strapiInstance, watchIgnoreFiles, polling }) { const restart = () => { if (strapiInstance.reload.isWatching && !strapiInstance.reload.isReloading) { strapiInstance.reload.isReloading = true; strapiInstance.reload(); } }; const watcher = chokidar.watch(dir, { ignoreInitial: true, usePolling: polling, ignored: [ /(^|[/\\])\../, // dot files /tmp/, '**/admin', '**/admin/**', 'extensions/**/admin', 'extensions/**/admin/**', '**/documentation', '**/documentation/**', '**/node_modules', '**/node_modules/**', '**/plugins.json', '**/index.html', '**/public', '**/public/**', '**/*.db*', '**/exports/**', ...watchIgnoreFiles, ], }); watcher .on('add', path => { strapiInstance.log.info(`File created: ${path}`); restart(); }) .on('change', path => { strapiInstance.log.info(`File changed: ${path}`); restart(); }) .on('unlink', path => { strapiInstance.log.info(`File deleted: ${path}`); restart(); }); } PK›¶z[vč8Œ generate.jsnuÕIw¶“'use strict'; /** * Module dependencies */ // Node.js core. const path = require('path'); // Master of ceremonies for generators. const generate = require('strapi-generate'); // Logger. const { logger } = require('strapi-utils'); // Local Strapi dependencies. const packageJSON = require('../../package.json'); /** * `$ strapi generate` * * Scaffolding for the application in our working directory. */ module.exports = function(id, cliArguments) { // Build initial scope. const scope = { rootPath: process.cwd(), strapiRoot: path.resolve(__dirname, '..'), id: id, args: cliArguments, strapiPackageJSON: packageJSON, }; scope.generatorType = process.argv[2].split(':')[1]; // Show usage if no generator type is defined. if (!scope.generatorType) { return logger.error('Write `$ strapi generate:something` instead.'); } return generate(scope, { // Log and exit the REPL in case there is an error // while we were trying to generate the requested generator. error(msg) { logger.error(msg); process.exit(1); }, // Log and exit the REPL in case of success // but first make sure we have all the info we need. success() { if (!scope.outputPath && scope.filename && scope.destDir) { scope.outputPath = scope.destDir + scope.filename; } if (scope.generatorType !== 'new') { logger.info( `Generated a new ${scope.generatorType} \`${scope.name}\` at \`${scope.filePath}\`.` ); } process.exit(0); }, }); }; PK›¶z[)¦čč install.jsnuÕIw¶“'use strict'; const { join } = require('path'); const { existsSync } = require('fs-extra'); const ora = require('ora'); const execa = require('execa'); const findPackagePath = require('../load/package-path'); module.exports = async plugins => { const loader = ora(); const dir = process.cwd(); const version = require(join(dir, 'package.json')).dependencies.strapi; const pluginArgs = plugins.map(name => `strapi-plugin-${name}@${version}`); try { loader.start(`Installing dependencies`); const useYarn = existsSync(join(dir, 'yarn.lock')); if (useYarn) { await execa('yarn', ['add', ...pluginArgs]); } else { await execa('npm', ['install', '--save', ...pluginArgs]); } loader.succeed(); // check if rebuild is necessary let shouldRebuild = false; for (let name of plugins) { let pkgPath = findPackagePath(`strapi-plugin-${name}`); if (existsSync(join(pkgPath, 'admin', 'src', 'index.js'))) { shouldRebuild = true; } } if (shouldRebuild) { loader.start(`Rebuilding admin UI`); await execa('npm', ['run', 'build']); loader.succeed(); } } catch (err) { loader.clear(); console.error(err.message); process.exit(1); } }; PK›¶z[GԼʭ­new.jsnuÕIw¶“'use strict'; /** * `$ strapi new` * * Generate a new Strapi application. */ module.exports = function(...args) { return require('strapi-generate-new')(...args); }; PK›¶z[GŲeõyystart.jsnuÕIw¶“'use strict'; const strapi = require('../index'); /** * `$ strapi start` */ module.exports = () => strapi().start(); PK›¶z[ubĻ9 uninstall.jsnuÕIw¶“'use strict'; const { join } = require('path'); const { existsSync, removeSync } = require('fs-extra'); const ora = require('ora'); const execa = require('execa'); const inquirer = require('inquirer'); const findPackagePath = require('../load/package-path'); module.exports = async (plugins, { deleteFiles }) => { const answers = await inquirer.prompt([ { type: 'confirm', name: 'deleteFiles', message: `Do you want to delete the plugin generated files in the extensions folder ?`, default: true, when: !deleteFiles, }, ]); const loader = ora(); const dir = process.cwd(); const pluginArgs = plugins.map(name => `strapi-plugin-${name}`); try { // verify should rebuild before removing the pacakge let shouldRebuild = false; for (let name of plugins) { let pkgPath = findPackagePath(`strapi-plugin-${name}`); if (existsSync(join(pkgPath, 'admin', 'src', 'index.js'))) { shouldRebuild = true; } } loader.start(`Uninstalling dependencies`); const useYarn = existsSync(join(dir, 'yarn.lock')); if (useYarn) { await execa('yarn', ['remove', ...pluginArgs]); } else { await execa('npm', ['remove', ...pluginArgs]); } loader.succeed(); if (deleteFiles === true || answers.deleteFiles === true) { loader.start('Deleting old files'); for (let name of plugins) { const pluginDir = join(dir, 'extensions', name); if (existsSync(pluginDir)) { removeSync(pluginDir); } } loader.succeed(); } if (shouldRebuild) { loader.start(`Rebuilding admin UI`); await execa('npm', ['run', 'build']); loader.succeed(); } } catch (err) { loader.clear(); console.error(err.message); process.exit(1); } }; PK›¶z[į’į4%% watchAdmin.jsnuÕIw¶“'use strict'; // eslint-disable-next-line node/no-extraneous-require const strapiAdmin = require('strapi-admin'); const { getConfigUrls, getAbsoluteServerUrl } = require('strapi-utils'); const loadConfiguration = require('../core/app-configuration'); const ee = require('../utils/ee'); const addSlash = require('../utils/addSlash'); module.exports = async function({ browser }) { const dir = process.cwd(); const config = loadConfiguration(dir); const { adminPath } = getConfigUrls(config.get('server'), true); const adminPort = config.get('server.admin.port', 8000); const adminHost = config.get('server.admin.host', 'localhost'); const adminWatchIgnoreFiles = config.get('server.admin.watchIgnoreFiles', []); ee({ dir }); strapiAdmin.watchAdmin({ dir, port: adminPort, host: adminHost, browser, options: { backend: getAbsoluteServerUrl(config, true), publicPath: addSlash(adminPath), watchIgnoreFiles: adminWatchIgnoreFiles, features: ee.isEE ? ee.features.getEnabled() : [], }, }); }; PK›¶z[½$@@admin-reset.jsnuÕIw¶“PK›¶z[Ō vn««~build.jsnuÕIw¶“PK›¶z[ļ‘<•a configurationDump.jsnuÕIw¶“PK›¶z[£6)m¢¢³configurationRestore.jsnuÕIw¶“PK›¶z[O#zś œconsole.jsnuÕIw¶“PK›¶z[£DÜn¢¢ å!develop.jsnuÕIw¶“PK›¶z[vč8Œ Į1generate.jsnuÕIw¶“PK›¶z[)¦čč 8install.jsnuÕIw¶“PK›¶z[GԼʭ­;=new.jsnuÕIw¶“PK›¶z[GŲeõyy>start.jsnuÕIw¶“PK›¶z[ubĻ9 Ļ>uninstall.jsnuÕIw¶“PK›¶z[į’į4%% )FwatchAdmin.jsnuÕIw¶“PK ‘‹J