@strapi/strapi 4.13.5 → 4.13.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -29
- package/lib/commands/actions/develop/action.js +12 -17
- package/lib/commands/actions/plugin/build-command/action.js +137 -0
- package/lib/commands/actions/plugin/build-command/command.js +17 -0
- package/lib/commands/actions/ts/generate-types/action.js +2 -2
- package/lib/commands/builders/packages.js +252 -0
- package/lib/commands/builders/tasks/dts.js +199 -0
- package/lib/commands/builders/tasks/index.js +29 -0
- package/lib/commands/builders/tasks/vite.js +144 -0
- package/lib/commands/builders/typescript.js +2 -2
- package/lib/commands/index.js +1 -0
- package/lib/commands/utils/helpers.js +53 -1
- package/lib/commands/utils/logger.js +97 -0
- package/lib/commands/utils/pkg.js +421 -0
- package/lib/compile.d.ts +13 -0
- package/lib/compile.js +8 -4
- package/lib/index.d.ts +1 -0
- package/lib/services/entity-service/types/params/filters/operators.d.ts +1 -0
- package/lib/types/core/strapi/index.d.ts +2 -2
- package/package.json +22 -17
package/README.md
CHANGED
|
@@ -1,23 +1,15 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<a href="https://strapi.io">
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
width="318px"
|
|
8
|
-
/>
|
|
9
|
-
<img
|
|
10
|
-
src="https://strapi.io/assets/strapi-logo-light.svg"
|
|
11
|
-
alt="Strapi logo"
|
|
12
|
-
width="318px"
|
|
13
|
-
/>
|
|
14
|
-
</picture>
|
|
2
|
+
<a href="https://strapi.io/#gh-light-mode-only">
|
|
3
|
+
<img src="https://strapi.io/assets/strapi-logo-dark.svg" width="318px" alt="Strapi logo" />
|
|
4
|
+
</a>
|
|
5
|
+
<a href="https://strapi.io/#gh-dark-mode-only">
|
|
6
|
+
<img src="https://strapi.io/assets/strapi-logo-light.svg" width="318px" alt="Strapi logo" />
|
|
15
7
|
</a>
|
|
16
8
|
</p>
|
|
17
9
|
|
|
18
|
-
<h3 align="center">
|
|
19
|
-
<p align="center">The
|
|
20
|
-
<p align="center"><a href="https://strapi.io/demo">Try live demo</a></p>
|
|
10
|
+
<h3 align="center">Open-source headless CMS, self-hosted or Cloud you’re in control.</h3>
|
|
11
|
+
<p align="center">The leading open-source headless CMS, 100% JavaScript/TypeScript, flexible and fully customizable.</p>
|
|
12
|
+
<p align="center"><a href="https://cloud.strapi.io/signups?source=github1">Cloud</a> · <a href="https://strapi.io/demo">Try live demo</a></p>
|
|
21
13
|
<br />
|
|
22
14
|
|
|
23
15
|
<p align="center">
|
|
@@ -39,18 +31,22 @@
|
|
|
39
31
|
|
|
40
32
|
<p align="center">
|
|
41
33
|
<a href="https://strapi.io">
|
|
42
|
-
<img src="https://raw.githubusercontent.com/strapi/strapi/
|
|
34
|
+
<img src="https://raw.githubusercontent.com/strapi/strapi/main/public/assets/admin-demo.gif" alt="Administration panel" />
|
|
43
35
|
</a>
|
|
44
36
|
</p>
|
|
45
37
|
|
|
46
38
|
<br>
|
|
47
39
|
|
|
48
|
-
Strapi is a free and open-source headless CMS
|
|
40
|
+
Strapi Community Edition is a free and open-source headless CMS enabling you to manage any content, anywhere.
|
|
49
41
|
|
|
50
|
-
- **
|
|
51
|
-
- **
|
|
52
|
-
- **
|
|
53
|
-
- **Customizable
|
|
42
|
+
- **Self-hosted or Cloud**: You can host and scale Strapi projects the way you want. You can save time by deploying to [Strapi Cloud](https://cloud.strapi.io/signups?source=github1) or deploy to the hosting platform you want**: AWS, Azure, Google Cloud, DigitalOcean.
|
|
43
|
+
- **Modern Admin Pane**: Elegant, entirely customizable and a fully extensible admin panel.
|
|
44
|
+
- **Multi-database support**: You can choose the database you prefer: PostgreSQL, MySQL, MariaDB, and SQLite.
|
|
45
|
+
- **Customizable**: You can quickly build your logic by fully customizing APIs, routes, or plugins to fit your needs perfectly.
|
|
46
|
+
- **Blazing Fast and Robust**: Built on top of Node.js and TypeScript, Strapi delivers reliable and solid performance.
|
|
47
|
+
- **Front-end Agnostic**: Use any front-end framework (React, Next.js, Vue, Angular, etc.), mobile apps or even IoT.
|
|
48
|
+
- **Secure by default**: Reusable policies, CORS, CSP, P3P, Xframe, XSS, and more.
|
|
49
|
+
- **Powerful CLI**: Scaffold projects and APIs on the fly.
|
|
54
50
|
|
|
55
51
|
## Getting Started
|
|
56
52
|
|
|
@@ -115,13 +111,13 @@ Strapi only supports maintenance and LTS versions of Node.js. Please refer to th
|
|
|
115
111
|
|
|
116
112
|
## Features
|
|
117
113
|
|
|
118
|
-
- **
|
|
119
|
-
- **
|
|
120
|
-
- **
|
|
121
|
-
- **
|
|
122
|
-
- **
|
|
123
|
-
|
|
124
|
-
|
|
114
|
+
- **Content Types Builder**: Build the most flexible publishing experience for your content managers, by giving them the freedom to create any page on the go with [fields](https://docs.strapi.io/user-docs/content-manager/writing-content#filling-up-fields), components and [Dynamic Zones](https://docs.strapi.io/user-docs/content-manager/writing-content#dynamic-zones).
|
|
115
|
+
- **Media Library**: Upload your images, videos, audio or documents to the media library. Easily find the right asset, edit and reuse it.
|
|
116
|
+
- **Internationalization**: The Internationalization (i18n) plugin allows Strapi users to create, manage and distribute localized content in different languages, called "locales
|
|
117
|
+
- **Role Based Access Control**: Create an unlimited number of custom roles and permissions for admin and end users.
|
|
118
|
+
- **GraphQL or REST**: Consume the API using REST or GraphQL
|
|
119
|
+
|
|
120
|
+
You can unlock additional features such as SSO, Audit Logs, Review Workflows in [Strapi Cloud](https://cloud.strapi.io/login?source=github1) or [Strapi Enterprise](https://strapi.io/enterprise?source=github1).
|
|
125
121
|
|
|
126
122
|
**[See more on our website](https://strapi.io/overview)**.
|
|
127
123
|
|
|
@@ -48,7 +48,7 @@ module.exports = async ({ build, watchAdmin, polling, browser }) => {
|
|
|
48
48
|
|
|
49
49
|
const primaryProcess = async ({ distDir, appDir, build, isTSProject, watchAdmin, browser }) => {
|
|
50
50
|
if (isTSProject) {
|
|
51
|
-
await buildTypeScript({ srcDir: appDir, distDir,
|
|
51
|
+
await buildTypeScript({ srcDir: appDir, distDir, ignoreDiagnostics: true });
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
const config = loadConfiguration({ appDir, distDir });
|
|
@@ -84,7 +84,7 @@ const primaryProcess = async ({ distDir, appDir, build, isTSProject, watchAdmin,
|
|
|
84
84
|
switch (message) {
|
|
85
85
|
case 'reload':
|
|
86
86
|
if (isTSProject) {
|
|
87
|
-
await buildTypeScript({ srcDir: appDir, distDir,
|
|
87
|
+
await buildTypeScript({ srcDir: appDir, distDir, ignoreDiagnostics: true });
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
console.info('The server is restarting\n');
|
|
@@ -113,21 +113,16 @@ const workerProcess = async ({ appDir, distDir, watchAdmin, polling, isTSProject
|
|
|
113
113
|
serveAdminPanel: !watchAdmin,
|
|
114
114
|
}).load();
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
pwd: appDir,
|
|
127
|
-
rootDir: undefined,
|
|
128
|
-
logger: { silent: true, debug: false },
|
|
129
|
-
artifacts: { contentTypes: true, components: true },
|
|
130
|
-
});
|
|
116
|
+
await tsUtils.generators.generate({
|
|
117
|
+
strapi: strapiInstance,
|
|
118
|
+
pwd: appDir,
|
|
119
|
+
rootDir: undefined,
|
|
120
|
+
logger: { silent: true, debug: false },
|
|
121
|
+
artifacts: { contentTypes: true, components: true },
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
if (isTSProject) {
|
|
125
|
+
await buildTypeScript({ srcDir: appDir, distDir, ignoreDiagnostics: false });
|
|
131
126
|
}
|
|
132
127
|
|
|
133
128
|
const adminWatchIgnoreFiles = strapiInstance.config.get('admin.watchIgnoreFiles', []);
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs/promises');
|
|
4
|
+
const boxen = require('boxen');
|
|
5
|
+
const chalk = require('chalk');
|
|
6
|
+
const ora = require('ora');
|
|
7
|
+
const { createLogger } = require('../../../utils/logger');
|
|
8
|
+
const { notifyExperimentalCommand } = require('../../../utils/helpers');
|
|
9
|
+
const {
|
|
10
|
+
loadPkg,
|
|
11
|
+
validatePkg,
|
|
12
|
+
validateExportsOrdering,
|
|
13
|
+
getExportExtensionMap,
|
|
14
|
+
} = require('../../../utils/pkg');
|
|
15
|
+
const { createBuildContext, createBuildTasks } = require('../../../builders/packages');
|
|
16
|
+
const { buildTaskHandlers } = require('../../../builders/tasks');
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
* @param {object} args
|
|
21
|
+
* @param {boolean} args.force
|
|
22
|
+
* @param {boolean} args.debug
|
|
23
|
+
*/
|
|
24
|
+
module.exports = async ({ force, debug }) => {
|
|
25
|
+
const logger = createLogger({ debug, timestamp: false });
|
|
26
|
+
try {
|
|
27
|
+
/**
|
|
28
|
+
* Notify users this is an experimental command and get them to approve first
|
|
29
|
+
* this can be opted out by setting the argument --yes
|
|
30
|
+
*/
|
|
31
|
+
await notifyExperimentalCommand({ force });
|
|
32
|
+
|
|
33
|
+
const cwd = process.cwd();
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Load the closest package.json and then verify the structure against what we expect.
|
|
37
|
+
*/
|
|
38
|
+
const packageJsonLoader = ora('Verifying package.json \n').start();
|
|
39
|
+
|
|
40
|
+
const rawPkg = await loadPkg({ cwd, logger }).catch((err) => {
|
|
41
|
+
packageJsonLoader.fail();
|
|
42
|
+
logger.error(err.message);
|
|
43
|
+
logger.debug(`Path checked – ${cwd}`);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const validatedPkg = await validatePkg({
|
|
48
|
+
pkg: rawPkg,
|
|
49
|
+
}).catch((err) => {
|
|
50
|
+
packageJsonLoader.fail();
|
|
51
|
+
logger.error(err.message);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Validate the exports of the package incl. the order of the
|
|
57
|
+
* exports within the exports map if applicable
|
|
58
|
+
*/
|
|
59
|
+
const packageJson = await validateExportsOrdering({ pkg: validatedPkg, logger }).catch(
|
|
60
|
+
(err) => {
|
|
61
|
+
packageJsonLoader.fail();
|
|
62
|
+
logger.error(err.message);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
packageJsonLoader.succeed('Verified package.json');
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* We create tasks based on the exports of the package.json
|
|
71
|
+
* their handlers are then ran in the order of the exports map
|
|
72
|
+
* and results are logged to see gradual progress.
|
|
73
|
+
*/
|
|
74
|
+
|
|
75
|
+
const buildContextLoader = ora('Creating build context \n').start();
|
|
76
|
+
|
|
77
|
+
const extMap = getExportExtensionMap();
|
|
78
|
+
|
|
79
|
+
const ctx = await createBuildContext({
|
|
80
|
+
cwd,
|
|
81
|
+
extMap,
|
|
82
|
+
logger,
|
|
83
|
+
pkg: packageJson,
|
|
84
|
+
}).catch((err) => {
|
|
85
|
+
buildContextLoader.fail();
|
|
86
|
+
logger.error(err.message);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
logger.debug('Build context: \n', ctx);
|
|
91
|
+
|
|
92
|
+
const buildTasks = await createBuildTasks(ctx);
|
|
93
|
+
|
|
94
|
+
buildContextLoader.succeed('Created build context');
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* If the distPath already exists, clean it
|
|
98
|
+
*/
|
|
99
|
+
try {
|
|
100
|
+
logger.debug(`Cleaning dist folder: ${ctx.distPath}`);
|
|
101
|
+
await fs.rm(ctx.distPath, { recursive: true, force: true });
|
|
102
|
+
logger.debug('Cleaned dist folder');
|
|
103
|
+
} catch {
|
|
104
|
+
// do nothing, it will fail if the folder does not exist
|
|
105
|
+
logger.debug('There was no dist folder to clean');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
for (const task of buildTasks) {
|
|
109
|
+
/**
|
|
110
|
+
* @type {import('../../../builders/tasks').TaskHandler<any>}
|
|
111
|
+
*/
|
|
112
|
+
const handler = buildTaskHandlers[task.type];
|
|
113
|
+
handler.print(ctx, task);
|
|
114
|
+
|
|
115
|
+
await handler.run(ctx, task).catch((err) => {
|
|
116
|
+
if (err instanceof Error) {
|
|
117
|
+
logger.error(err.message);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
process.exit(1);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
} catch (err) {
|
|
124
|
+
logger.error(
|
|
125
|
+
'There seems to be an unexpected error, try again with --debug for more information \n'
|
|
126
|
+
);
|
|
127
|
+
console.log(
|
|
128
|
+
chalk.red(
|
|
129
|
+
boxen(err.stack, {
|
|
130
|
+
padding: 1,
|
|
131
|
+
align: 'left',
|
|
132
|
+
})
|
|
133
|
+
)
|
|
134
|
+
);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { forceOption } = require('../../../utils/commander');
|
|
4
|
+
const { getLocalScript } = require('../../../utils/helpers');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* `$ strapi plugin:build`
|
|
8
|
+
* @param {import('../../../../types/core/commands').AddCommandOptions} options
|
|
9
|
+
*/
|
|
10
|
+
module.exports = ({ command }) => {
|
|
11
|
+
command
|
|
12
|
+
.command('plugin:build')
|
|
13
|
+
.description('Bundle your strapi plugin for publishing.')
|
|
14
|
+
.addOption(forceOption)
|
|
15
|
+
.option('-d, --debug', 'Enable debugging mode with verbose logs', false)
|
|
16
|
+
.action(getLocalScript('plugin/build-command'));
|
|
17
|
+
};
|
|
@@ -10,7 +10,7 @@ module.exports = async ({ debug, silent, verbose, outDir }) => {
|
|
|
10
10
|
process.exit(1);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
const appContext = await strapi.compile();
|
|
13
|
+
const appContext = await strapi.compile({ ignoreDiagnostics: true });
|
|
14
14
|
const app = await strapi(appContext).register();
|
|
15
15
|
|
|
16
16
|
await tsUtils.generators.generate({
|
|
@@ -25,5 +25,5 @@ module.exports = async ({ debug, silent, verbose, outDir }) => {
|
|
|
25
25
|
artifacts: { contentTypes: true, components: true },
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
-
app.destroy();
|
|
28
|
+
await app.destroy();
|
|
29
29
|
};
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const browserslistToEsbuild = require('browserslist-to-esbuild');
|
|
5
|
+
|
|
6
|
+
const { parseExports } = require('../utils/pkg');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {Object} BuildContextArgs
|
|
10
|
+
* @property {string} cwd
|
|
11
|
+
* @property {import('../utils/pkg').ExtMap} extMap
|
|
12
|
+
* @property {import('../utils/logger').Logger} logger
|
|
13
|
+
* @property {import('../utils/pkg').PackageJson} pkg
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @typedef {Object} Targets
|
|
18
|
+
* @property {string[]} node
|
|
19
|
+
* @property {string[]} web
|
|
20
|
+
* @property {string[]} *
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {Object} BuildContext
|
|
25
|
+
* @property {string} cwd
|
|
26
|
+
* @property {import('../utils/pkg').Export[]} exports
|
|
27
|
+
* @property {string[]} external
|
|
28
|
+
* @property {import('../utils/pkg').ExtMap} extMap
|
|
29
|
+
* @property {import('../utils/logger').Logger} logger
|
|
30
|
+
* @property {import('../utils/pkg').PackageJson} pkg
|
|
31
|
+
* @property {Targets} targets
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
const DEFAULT_BROWSERS_LIST_CONFIG = [
|
|
35
|
+
'last 3 major versions',
|
|
36
|
+
'Firefox ESR',
|
|
37
|
+
'last 2 Opera versions',
|
|
38
|
+
'not dead',
|
|
39
|
+
'node 16.0.0',
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @description Create a build context for the pipeline we're creating,
|
|
44
|
+
* this is shared among tasks so they all use the same settings for core pieces
|
|
45
|
+
* such as a target, distPath, externals etc.
|
|
46
|
+
*
|
|
47
|
+
* @type {(args: BuildContextArgs) => Promise<BuildContext>}
|
|
48
|
+
*/
|
|
49
|
+
const createBuildContext = async ({ cwd, extMap, logger, pkg }) => {
|
|
50
|
+
const targets = {
|
|
51
|
+
'*': browserslistToEsbuild(pkg.browserslist ?? DEFAULT_BROWSERS_LIST_CONFIG),
|
|
52
|
+
node: browserslistToEsbuild(['node 16.0.0']),
|
|
53
|
+
web: ['esnext'],
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const exports = parseExports({ extMap, pkg }).reduce((acc, x) => {
|
|
57
|
+
const { _path: exportPath, ...exportEntry } = x;
|
|
58
|
+
|
|
59
|
+
return { ...acc, [exportPath]: exportEntry };
|
|
60
|
+
}, {});
|
|
61
|
+
|
|
62
|
+
const external = [
|
|
63
|
+
...(pkg.dependencies ? Object.keys(pkg.dependencies) : []),
|
|
64
|
+
...(pkg.peerDependencies ? Object.keys(pkg.peerDependencies) : []),
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
const outputPaths = Object.values(exports)
|
|
68
|
+
.flatMap((exportEntry) => {
|
|
69
|
+
return [exportEntry.import, exportEntry.require].filter(Boolean);
|
|
70
|
+
})
|
|
71
|
+
.map((p) => path.resolve(cwd, p));
|
|
72
|
+
|
|
73
|
+
const distPath = findCommonDirPath(outputPaths);
|
|
74
|
+
|
|
75
|
+
if (distPath === cwd) {
|
|
76
|
+
throw new Error(
|
|
77
|
+
'all output files must share a common parent directory which is not the root package directory'
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (!distPath) {
|
|
82
|
+
throw new Error("could not detect 'dist' path");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
logger,
|
|
87
|
+
cwd,
|
|
88
|
+
pkg,
|
|
89
|
+
exports,
|
|
90
|
+
external,
|
|
91
|
+
distPath,
|
|
92
|
+
targets,
|
|
93
|
+
extMap,
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* @type {(containerPath: string, itemPath: string) => boolean}
|
|
99
|
+
*/
|
|
100
|
+
const pathContains = (containerPath, itemPath) => {
|
|
101
|
+
return !path.relative(containerPath, itemPath).startsWith('..');
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @type {(filePaths: string[]) => string | undefined}
|
|
106
|
+
*/
|
|
107
|
+
const findCommonDirPath = (filePaths) => {
|
|
108
|
+
/**
|
|
109
|
+
* @type {string | undefined}
|
|
110
|
+
*/
|
|
111
|
+
let commonPath;
|
|
112
|
+
|
|
113
|
+
for (const filePath of filePaths) {
|
|
114
|
+
let dirPath = path.dirname(filePath);
|
|
115
|
+
|
|
116
|
+
if (!commonPath) {
|
|
117
|
+
commonPath = dirPath;
|
|
118
|
+
// eslint-disable-next-line no-continue
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
while (dirPath !== commonPath) {
|
|
123
|
+
dirPath = path.dirname(dirPath);
|
|
124
|
+
|
|
125
|
+
if (dirPath === commonPath) {
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (pathContains(dirPath, commonPath)) {
|
|
130
|
+
commonPath = dirPath;
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (dirPath === '.') return undefined;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return commonPath;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* @typedef {import('./tasks/vite').ViteTask | import('./tasks/dts').DtsTask} BuildTask
|
|
143
|
+
*/
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* @description Create the build tasks for the pipeline, this
|
|
147
|
+
* comes from the exports map we've created in the build context.
|
|
148
|
+
* But handles each export line uniquely with space to add more
|
|
149
|
+
* as the standard develops.
|
|
150
|
+
*
|
|
151
|
+
* @type {(args: BuildContext) => Promise<BuildTask[]>}
|
|
152
|
+
*/
|
|
153
|
+
const createBuildTasks = async (ctx) => {
|
|
154
|
+
/**
|
|
155
|
+
* @type {BuildTask[]}
|
|
156
|
+
*/
|
|
157
|
+
const tasks = [];
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* @type {import('./tasks/dts').DtsTask}
|
|
161
|
+
*/
|
|
162
|
+
const dtsTask = {
|
|
163
|
+
type: 'build:dts',
|
|
164
|
+
entries: [],
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @type {Record<string, import('./tasks/vite').ViteTask>}
|
|
169
|
+
*/
|
|
170
|
+
const viteTasks = {};
|
|
171
|
+
|
|
172
|
+
const createViteTask = (format, runtime, { output, ...restEntry }) => {
|
|
173
|
+
const buildId = `${format}:${output}`;
|
|
174
|
+
|
|
175
|
+
if (viteTasks[buildId]) {
|
|
176
|
+
viteTasks[buildId].entries.push(restEntry);
|
|
177
|
+
|
|
178
|
+
if (output !== viteTasks[buildId].output) {
|
|
179
|
+
ctx.logger.warn(
|
|
180
|
+
'Multiple entries with different outputs for the same format are not supported. The first output will be used.'
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
} else {
|
|
184
|
+
viteTasks[buildId] = {
|
|
185
|
+
type: 'build:js',
|
|
186
|
+
format,
|
|
187
|
+
output,
|
|
188
|
+
runtime,
|
|
189
|
+
entries: [restEntry],
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
const exps = Object.entries(ctx.exports).map(([exportPath, exportEntry]) => ({
|
|
195
|
+
...exportEntry,
|
|
196
|
+
_path: exportPath,
|
|
197
|
+
}));
|
|
198
|
+
|
|
199
|
+
for (const exp of exps) {
|
|
200
|
+
if (exp.types) {
|
|
201
|
+
const importId = path.join(ctx.pkg.name, exp._path);
|
|
202
|
+
|
|
203
|
+
dtsTask.entries.push({
|
|
204
|
+
importId,
|
|
205
|
+
exportPath: exp._path,
|
|
206
|
+
sourcePath: exp.source,
|
|
207
|
+
targetPath: exp.types,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* @type {keyof Target}
|
|
213
|
+
*/
|
|
214
|
+
// eslint-disable-next-line no-nested-ternary
|
|
215
|
+
const runtime = exp._path.includes('strapi-admin')
|
|
216
|
+
? 'web'
|
|
217
|
+
: exp._path.includes('strapi-server')
|
|
218
|
+
? 'node'
|
|
219
|
+
: '*';
|
|
220
|
+
|
|
221
|
+
if (exp.require) {
|
|
222
|
+
/**
|
|
223
|
+
* register CJS task
|
|
224
|
+
*/
|
|
225
|
+
createViteTask('cjs', runtime, {
|
|
226
|
+
path: exp._path,
|
|
227
|
+
entry: exp.source,
|
|
228
|
+
output: exp.require,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (exp.import) {
|
|
233
|
+
/**
|
|
234
|
+
* register ESM task
|
|
235
|
+
*/
|
|
236
|
+
createViteTask('es', runtime, {
|
|
237
|
+
path: exp._path,
|
|
238
|
+
entry: exp.source,
|
|
239
|
+
output: exp.import,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
tasks.push(dtsTask, ...Object.values(viteTasks));
|
|
245
|
+
|
|
246
|
+
return tasks;
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
module.exports = {
|
|
250
|
+
createBuildContext,
|
|
251
|
+
createBuildTasks,
|
|
252
|
+
};
|