76 lines
2.7 KiB
JavaScript
76 lines
2.7 KiB
JavaScript
/* ============================================================================
|
|||
|
|
SEED RUNNER
|
||
|
|
----------------------------------------------------------------------------
|
||
|
|
Boots Strapi far enough to use the document service, runs src/seed, and
|
||
|
|
shuts it down again. It does NOT start a server: nothing listens on a port,
|
||
|
|
so it is safe to run while `pnpm dev:cms` is up - both talk to the same
|
||
|
|
PostgreSQL database.
|
||
|
|
|
||
|
|
`compileStrapi()` is Strapi's own TypeScript build step. It compiles
|
||
|
|
src/** (the seed included) into dist/, which is why this file is plain
|
||
|
|
CommonJS JavaScript and everything it calls is TypeScript.
|
||
|
|
|
||
|
|
Usage:
|
||
|
|
pnpm seed
|
||
|
|
pnpm seed --demo
|
||
|
|
pnpm seed --demo --clean
|
||
|
|
========================================================================= */
|
||
|
|
|
||
|
|
'use strict';
|
||
|
|
|
||
|
|
const { compileStrapi, createStrapi } = require('@strapi/strapi');
|
||
|
|
|
||
|
|
async function main() {
|
||
|
|
const appContext = await compileStrapi();
|
||
|
|
const app = await createStrapi(appContext).load();
|
||
|
|
|
||
|
|
/* Required from dist, not from src: the file below is TypeScript, and what
|
||
|
|
`compileStrapi()` just produced is the JavaScript for it. */
|
||
|
|
const { runSeed, parseSeedOptions } = require('../dist/src/seed');
|
||
|
|
|
||
|
|
try {
|
||
|
|
await runSeed(app, parseSeedOptions(process.argv.slice(2)));
|
||
|
|
} finally {
|
||
|
|
await shutdown(app);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Shut Strapi down without letting the shutdown fail the run.
|
||
|
|
*
|
||
|
|
* Knex tears its connection pool down by aborting every acquisition still
|
||
|
|
* pending on it, and each abort rejects a promise that nothing is waiting on -
|
||
|
|
* so it arrives as an unhandled rejection reading "aborted" rather than as an
|
||
|
|
* error this function could simply catch. Everything the seed wrote is
|
||
|
|
* committed long before this point, so those are absorbed for the length of
|
||
|
|
* the shutdown and nothing else is: a seed that worked must not report itself
|
||
|
|
* as a seed that failed, and a real error must still say so.
|
||
|
|
*/
|
||
|
|
async function shutdown(app) {
|
||
|
|
const absorbAbort = (reason) => {
|
||
|
|
const message = reason instanceof Error ? reason.message : String(reason);
|
||
|
|
if (message !== 'aborted') {
|
||
|
|
console.warn(`[seed] while shutting down: ${message}`);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
process.on('unhandledRejection', absorbAbort);
|
||
|
|
|
||
|
|
try {
|
||
|
|
await app.destroy();
|
||
|
|
} catch (error) {
|
||
|
|
const message = error instanceof Error ? error.message : String(error);
|
||
|
|
console.warn(`[seed] Strapi did not shut down cleanly (${message}). The data is written.`);
|
||
|
|
} finally {
|
||
|
|
process.off('unhandledRejection', absorbAbort);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
main()
|
||
|
|
.then(() => process.exit(0))
|
||
|
|
.catch((error) => {
|
||
|
|
console.error(error instanceof Error ? error.message : error);
|
||
|
|
if (error instanceof Error && error.stack) console.error(error.stack);
|
||
|
|
process.exit(1);
|
||
|
|
});
|