@redocly/cli 1.0.0-beta.98 → 1.0.0-rc.1

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.
Files changed (100) hide show
  1. package/bin/cli.js +1 -1
  2. package/lib/__mocks__/@redocly/openapi-core.d.ts +96 -0
  3. package/lib/__mocks__/@redocly/openapi-core.js +79 -0
  4. package/lib/__mocks__/documents.d.ts +92 -0
  5. package/lib/__mocks__/documents.js +63 -0
  6. package/lib/__mocks__/fs.d.ts +9 -0
  7. package/lib/__mocks__/fs.js +9 -0
  8. package/lib/__mocks__/perf_hooks.d.ts +4 -0
  9. package/lib/__mocks__/perf_hooks.js +6 -0
  10. package/lib/__mocks__/redoc.d.ts +7 -0
  11. package/lib/__mocks__/redoc.js +5 -0
  12. package/lib/__mocks__/utils.d.ts +26 -4
  13. package/lib/__mocks__/utils.js +8 -3
  14. package/lib/__tests__/commands/build-docs.test.d.ts +1 -0
  15. package/lib/__tests__/commands/build-docs.test.js +59 -0
  16. package/lib/__tests__/commands/bundle.test.js +66 -30
  17. package/lib/__tests__/commands/join.test.d.ts +1 -0
  18. package/lib/__tests__/commands/join.test.js +85 -0
  19. package/lib/__tests__/commands/lint.test.d.ts +1 -0
  20. package/lib/__tests__/commands/lint.test.js +149 -0
  21. package/lib/__tests__/commands/push-region.test.js +5 -4
  22. package/lib/__tests__/commands/push.test.js +254 -39
  23. package/lib/__tests__/fetch-with-timeout.test.d.ts +1 -0
  24. package/lib/__tests__/fetch-with-timeout.test.js +38 -0
  25. package/lib/__tests__/fixtures/config.d.ts +22 -0
  26. package/lib/__tests__/fixtures/config.js +24 -0
  27. package/lib/__tests__/utils.test.js +429 -1
  28. package/lib/__tests__/wrapper.test.d.ts +1 -0
  29. package/lib/__tests__/wrapper.test.js +57 -0
  30. package/lib/commands/build-docs/index.d.ts +3 -0
  31. package/lib/commands/build-docs/index.js +50 -0
  32. package/{src/commands/preview-docs/preview-server/default.hbs → lib/commands/build-docs/template.hbs} +2 -3
  33. package/lib/commands/build-docs/types.d.ts +23 -0
  34. package/lib/commands/build-docs/types.js +2 -0
  35. package/lib/commands/build-docs/utils.d.ts +7 -0
  36. package/lib/commands/build-docs/utils.js +99 -0
  37. package/lib/commands/bundle.d.ts +11 -12
  38. package/lib/commands/bundle.js +26 -24
  39. package/lib/commands/join.d.ts +12 -3
  40. package/lib/commands/join.js +295 -109
  41. package/lib/commands/lint.d.ts +11 -8
  42. package/lib/commands/lint.js +49 -19
  43. package/lib/commands/login.d.ts +5 -3
  44. package/lib/commands/login.js +2 -2
  45. package/lib/commands/preview-docs/index.d.ts +6 -6
  46. package/lib/commands/preview-docs/index.js +30 -20
  47. package/lib/commands/preview-docs/preview-server/oauth2-redirect.html +1 -1
  48. package/lib/commands/preview-docs/preview-server/preview-server.js +5 -4
  49. package/lib/commands/preview-docs/preview-server/server.d.ts +1 -1
  50. package/lib/commands/push.d.ts +21 -10
  51. package/lib/commands/push.js +110 -63
  52. package/lib/commands/split/__tests__/index.test.js +23 -8
  53. package/lib/commands/split/index.d.ts +5 -3
  54. package/lib/commands/split/index.js +15 -24
  55. package/lib/commands/split/types.d.ts +11 -11
  56. package/lib/commands/split/types.js +19 -19
  57. package/lib/commands/stats.d.ts +7 -4
  58. package/lib/commands/stats.js +13 -12
  59. package/lib/fetch-with-timeout.d.ts +2 -0
  60. package/lib/fetch-with-timeout.js +30 -0
  61. package/lib/index.js +194 -40
  62. package/lib/js-utils.d.ts +1 -0
  63. package/lib/js-utils.js +9 -3
  64. package/lib/types.d.ts +17 -1
  65. package/lib/update-version-notifier.d.ts +3 -0
  66. package/lib/update-version-notifier.js +105 -0
  67. package/lib/utils.d.ts +39 -5
  68. package/lib/utils.js +273 -37
  69. package/lib/wrapper.d.ts +4 -0
  70. package/lib/wrapper.js +52 -0
  71. package/package.json +18 -8
  72. package/README.md +0 -39
  73. package/src/__mocks__/utils.ts +0 -11
  74. package/src/__tests__/commands/bundle.test.ts +0 -120
  75. package/src/__tests__/commands/push-region.test.ts +0 -51
  76. package/src/__tests__/commands/push.test.ts +0 -158
  77. package/src/__tests__/utils.test.ts +0 -50
  78. package/src/assert-node-version.ts +0 -8
  79. package/src/commands/bundle.ts +0 -178
  80. package/src/commands/join.ts +0 -488
  81. package/src/commands/lint.ts +0 -110
  82. package/src/commands/login.ts +0 -21
  83. package/src/commands/preview-docs/index.ts +0 -188
  84. package/src/commands/preview-docs/preview-server/hot.js +0 -42
  85. package/src/commands/preview-docs/preview-server/oauth2-redirect.html +0 -21
  86. package/src/commands/preview-docs/preview-server/preview-server.ts +0 -155
  87. package/src/commands/preview-docs/preview-server/server.ts +0 -91
  88. package/src/commands/push.ts +0 -357
  89. package/src/commands/split/__tests__/fixtures/spec.json +0 -70
  90. package/src/commands/split/__tests__/fixtures/webhooks.json +0 -88
  91. package/src/commands/split/__tests__/index.test.ts +0 -96
  92. package/src/commands/split/index.ts +0 -349
  93. package/src/commands/split/types.ts +0 -73
  94. package/src/commands/stats.ts +0 -115
  95. package/src/index.ts +0 -316
  96. package/src/js-utils.ts +0 -12
  97. package/src/types.ts +0 -13
  98. package/src/utils.ts +0 -300
  99. package/tsconfig.json +0 -9
  100. package/tsconfig.tsbuildinfo +0 -1
@@ -1,120 +0,0 @@
1
- import { lint, bundle, getTotals, getMergedConfig } from '@redocly/openapi-core';
2
-
3
- import { handleBundle } from '../../commands/bundle';
4
- import SpyInstance = jest.SpyInstance;
5
-
6
- jest.mock('@redocly/openapi-core');
7
- jest.mock('../../utils');
8
-
9
- (getMergedConfig as jest.Mock).mockImplementation(config => config)
10
-
11
- describe('bundle', () => {
12
- let processExitMock: SpyInstance;
13
- let exitCb: any;
14
-
15
- beforeEach(() => {
16
- processExitMock = jest.spyOn(process, 'exit').mockImplementation();
17
- jest.spyOn(process, 'once').mockImplementation((_e, cb) => {
18
- exitCb = cb;
19
- return process.on(_e, cb);
20
- });
21
- jest.spyOn(process.stderr, 'write').mockImplementation(() => true);
22
- });
23
-
24
- afterEach(() => {
25
- (lint as jest.Mock).mockClear();
26
- (bundle as jest.Mock).mockClear();
27
- (getTotals as jest.Mock).mockClear();
28
- });
29
-
30
- it('bundles definitions w/o linting', async () => {
31
- const entrypoints = ['foo.yaml', 'bar.yaml'];
32
-
33
- await handleBundle(
34
- {
35
- entrypoints,
36
- ext: 'yaml',
37
- format: 'codeframe',
38
- },
39
- '1.0.0',
40
- );
41
-
42
- expect(lint).toBeCalledTimes(0);
43
- expect(bundle).toBeCalledTimes(entrypoints.length);
44
- });
45
-
46
- it('exits with code 0 when bundles definitions', async () => {
47
- const entrypoints = ['foo.yaml', 'bar.yaml', 'foobar.yaml'];
48
-
49
- await handleBundle(
50
- {
51
- entrypoints,
52
- ext: 'yaml',
53
- format: 'codeframe',
54
- },
55
- '1.0.0',
56
- );
57
-
58
- exitCb?.();
59
- expect(processExitMock).toHaveBeenCalledWith(0);
60
- });
61
-
62
- it('bundles definitions w/ linting', async () => {
63
- const entrypoints = ['foo.yaml', 'bar.yaml', 'foobar.yaml'];
64
-
65
- await handleBundle(
66
- {
67
- entrypoints,
68
- ext: 'yaml',
69
- format: 'codeframe',
70
- lint: true,
71
- },
72
- '1.0.0',
73
- );
74
-
75
- expect(lint).toBeCalledTimes(entrypoints.length);
76
- expect(bundle).toBeCalledTimes(entrypoints.length);
77
- });
78
-
79
- it('exits with code 0 when bundles definitions w/linting w/o errors', async () => {
80
- const entrypoints = ['foo.yaml', 'bar.yaml', 'foobar.yaml'];
81
-
82
- await handleBundle(
83
- {
84
- entrypoints,
85
- ext: 'yaml',
86
- format: 'codeframe',
87
- lint: true,
88
- },
89
- '1.0.0',
90
- );
91
-
92
- exitCb?.();
93
- expect(processExitMock).toHaveBeenCalledWith(0);
94
- });
95
-
96
- it('exits with code 1 when bundles definitions w/linting w/errors', async () => {
97
- const entrypoints = ['foo.yaml'];
98
-
99
- (getTotals as jest.Mock).mockReturnValue({
100
- errors: 1,
101
- warnings: 0,
102
- ignored: 0
103
- });
104
-
105
- await handleBundle(
106
- {
107
- entrypoints,
108
- ext: 'yaml',
109
- format: 'codeframe',
110
- lint: true,
111
- },
112
- '1.0.0',
113
- );
114
-
115
- expect(lint).toBeCalledTimes(entrypoints.length);
116
- exitCb?.();
117
- expect(processExitMock).toHaveBeenCalledWith(1);
118
- });
119
-
120
- });
@@ -1,51 +0,0 @@
1
- import { getMergedConfig } from '@redocly/openapi-core';
2
- import { handlePush } from '../../commands/push';
3
- import { promptClientToken } from '../../commands/login';
4
-
5
- jest.mock('fs');
6
- jest.mock('node-fetch', () => ({
7
- default: jest.fn(() => ({
8
- ok: true,
9
- json: jest.fn().mockResolvedValue({}),
10
- })),
11
- }));
12
- jest.mock('@redocly/openapi-core');
13
- jest.mock('../../commands/login');
14
- jest.mock('../../utils');
15
-
16
- (getMergedConfig as jest.Mock).mockImplementation((config) => config);
17
-
18
- const mockPromptClientToken = promptClientToken as jest.MockedFunction<typeof promptClientToken>;
19
-
20
- describe('push-with-region', () => {
21
- const redoclyClient = require('@redocly/openapi-core').__redoclyClient;
22
- redoclyClient.isAuthorizedWithRedoclyByRegion = jest.fn().mockResolvedValue(false);
23
-
24
- beforeAll(() => {
25
- jest.spyOn(process.stdout, 'write').mockImplementation(() => true);
26
- });
27
-
28
- it('should call login with default domain when region is US', async () => {
29
- redoclyClient.domain = 'redoc.ly';
30
- await handlePush({
31
- upsert: true,
32
- entrypoint: 'spec.json',
33
- destination: '@org/my-api@1.0.0',
34
- branchName: 'test',
35
- });
36
- expect(mockPromptClientToken).toBeCalledTimes(1);
37
- expect(mockPromptClientToken).toHaveBeenCalledWith(redoclyClient.domain);
38
- });
39
-
40
- it('should call login with EU domain when region is EU', async () => {
41
- redoclyClient.domain = 'eu.redocly.com';
42
- await handlePush({
43
- upsert: true,
44
- entrypoint: 'spec.json',
45
- destination: '@org/my-api@1.0.0',
46
- branchName: 'test',
47
- });
48
- expect(mockPromptClientToken).toBeCalledTimes(1);
49
- expect(mockPromptClientToken).toHaveBeenCalledWith(redoclyClient.domain);
50
- });
51
- });
@@ -1,158 +0,0 @@
1
- import { Config, getMergedConfig } from '@redocly/openapi-core';
2
- import {
3
- getApiEntrypoint,
4
- getDestinationProps,
5
- handlePush,
6
- transformPush,
7
- } from '../../commands/push';
8
-
9
- jest.mock('fs');
10
- jest.mock('node-fetch', () => ({
11
- default: jest.fn(() => ({
12
- ok: true,
13
- json: jest.fn().mockResolvedValue({}),
14
- })),
15
- }));
16
- jest.mock('@redocly/openapi-core');
17
- jest.mock('../../utils');
18
-
19
- (getMergedConfig as jest.Mock).mockImplementation((config) => config);
20
-
21
- describe('push', () => {
22
- const redoclyClient = require('@redocly/openapi-core').__redoclyClient;
23
-
24
- beforeEach(() => {
25
- jest.spyOn(process.stdout, 'write').mockImplementation(() => true);
26
- });
27
-
28
- it('pushes definition', async () => {
29
- await handlePush({
30
- upsert: true,
31
- entrypoint: 'spec.json',
32
- destination: '@org/my-api@1.0.0',
33
- branchName: 'test',
34
- 'public': true
35
- });
36
-
37
- expect(redoclyClient.registryApi.prepareFileUpload).toBeCalledTimes(1);
38
- expect(redoclyClient.registryApi.pushApi).toBeCalledTimes(1);
39
- expect(redoclyClient.registryApi.pushApi).toHaveBeenLastCalledWith({
40
- branch: 'test',
41
- filePaths: ['filePath'],
42
- isUpsert: true,
43
- isPublic: true,
44
- name: 'my-api',
45
- organizationId: 'org',
46
- rootFilePath: 'filePath',
47
- version: '1.0.0',
48
- });
49
- });
50
- });
51
-
52
- describe('transformPush', () => {
53
- it('should adapt the existing syntax', () => {
54
- const cb = jest.fn();
55
- transformPush(cb)({
56
- maybeEntrypointOrAliasOrDestination: 'openapi.yaml',
57
- maybeDestination: '@testing_org/main@v1',
58
- });
59
- expect(cb).toBeCalledWith({
60
- entrypoint: 'openapi.yaml',
61
- destination: '@testing_org/main@v1',
62
- });
63
- });
64
- it('should adapt the existing syntax (including branchName)', () => {
65
- const cb = jest.fn();
66
- transformPush(cb)({
67
- maybeEntrypointOrAliasOrDestination: 'openapi.yaml',
68
- maybeDestination: '@testing_org/main@v1',
69
- maybeBranchName: 'other',
70
- });
71
- expect(cb).toBeCalledWith({
72
- entrypoint: 'openapi.yaml',
73
- destination: '@testing_org/main@v1',
74
- branchName: 'other',
75
- });
76
- });
77
- it('should use --branch option firstly', () => {
78
- const cb = jest.fn();
79
- transformPush(cb)({
80
- maybeEntrypointOrAliasOrDestination: 'openapi.yaml',
81
- maybeDestination: '@testing_org/main@v1',
82
- maybeBranchName: 'other',
83
- branch: 'priority-branch',
84
- });
85
- expect(cb).toBeCalledWith({
86
- entrypoint: 'openapi.yaml',
87
- destination: '@testing_org/main@v1',
88
- branchName: 'priority-branch',
89
- });
90
- });
91
- it('should work for a destination only', () => {
92
- const cb = jest.fn();
93
- transformPush(cb)({
94
- maybeEntrypointOrAliasOrDestination: '@testing_org/main@v1',
95
- });
96
- expect(cb).toBeCalledWith({
97
- destination: '@testing_org/main@v1',
98
- });
99
- });
100
- it('should accept aliases for the old syntax', () => {
101
- const cb = jest.fn();
102
- transformPush(cb)({
103
- maybeEntrypointOrAliasOrDestination: 'alias',
104
- maybeDestination: '@testing_org/main@v1',
105
- });
106
- expect(cb).toBeCalledWith({
107
- destination: '@testing_org/main@v1',
108
- entrypoint: 'alias',
109
- });
110
- });
111
- it('should accept no arguments at all', () => {
112
- const cb = jest.fn();
113
- transformPush(cb)({});
114
- expect(cb).toBeCalledWith({});
115
- });
116
- });
117
-
118
- describe('getDestinationProps', () => {
119
- it('should get valid destination props for the full destination syntax', () => {
120
- expect(getDestinationProps('@testing_org/main@v1', 'org-from-config')).toEqual([
121
- 'testing_org',
122
- 'main',
123
- 'v1',
124
- ]);
125
- });
126
- it('should fallback the organizationId from a config for the short destination syntax', () => {
127
- expect(getDestinationProps('main@v1', 'org-from-config')).toEqual([
128
- 'org-from-config',
129
- 'main',
130
- 'v1',
131
- ]);
132
- });
133
- it('should fallback the organizationId from a config if no destination provided', () => {
134
- expect(getDestinationProps(undefined, 'org-from-config')).toEqual(['org-from-config']);
135
- });
136
- it('should return empty organizationId if there is no one found', () => {
137
- expect(getDestinationProps('main@v1', undefined)).toEqual([, 'main', 'v1']);
138
- });
139
- });
140
-
141
- describe('getApiEntrypoint', () => {
142
- let config: Config = {
143
- apis: {
144
- 'main@v1': {
145
- root: 'openapi.yaml',
146
- },
147
- main: {
148
- root: 'latest.yaml',
149
- },
150
- },
151
- } as unknown as Config;
152
- it('should resolve the correct api for a valid name & version', () => {
153
- expect(getApiEntrypoint({ name: 'main', version: 'v1', config })).toEqual('openapi.yaml');
154
- });
155
- it('should resolve the latest version of api if there is no matching version', () => {
156
- expect(getApiEntrypoint({ name: 'main', version: 'latest', config })).toEqual('latest.yaml');
157
- });
158
- });
@@ -1,50 +0,0 @@
1
- import { isSubdir, pathToFilename } from '../utils';
2
-
3
- jest.mock("os");
4
-
5
- describe('isSubdir', () => {
6
- it('can correctly determine if subdir', () => {
7
- (
8
- [
9
- ['/foo', '/foo', false],
10
- ['/foo', '/bar', false],
11
- ['/foo', '/foobar', false],
12
- ['/foo', '/foo/bar', true],
13
- ['/foo', '/foo/../bar', false],
14
- ['/foo', '/foo/./bar', true],
15
- ['/bar/../foo', '/foo/bar', true],
16
- ['/foo', './bar', false],
17
- ['/foo', '/foo/..bar', true],
18
- ] as [string, string, boolean][]
19
- ).forEach(([parent, child, expectRes]) => {
20
- expect(isSubdir(parent, child)).toBe(expectRes);
21
- });
22
- });
23
-
24
- it('can correctly determine if subdir for windows-based paths', () => {
25
- const os = require('os');
26
- os.platform.mockImplementation(() => 'win32');
27
-
28
- (
29
- [
30
- ['C:/Foo', 'C:/Foo/Bar', true],
31
- ['C:\\Foo', 'C:\\Bar', false],
32
- ['C:\\Foo', 'D:\\Foo\\Bar', false],
33
- ] as [string, string, boolean][]
34
- ).forEach(([parent, child, expectRes]) => {
35
- expect(isSubdir(parent, child)).toBe(expectRes);
36
- });
37
- });
38
-
39
- afterEach(() => {
40
- jest.resetModules()
41
- })
42
- });
43
-
44
-
45
- describe('pathToFilename', () => {
46
- it('should use correct path separator', () => {
47
- const processedPath = pathToFilename('/user/createWithList', '_');
48
- expect(processedPath).toEqual('user_createWithList');
49
- });
50
- });
@@ -1,8 +0,0 @@
1
- import * as path from 'path';
2
- import { exitWithError } from './utils';
3
-
4
- try {
5
- require('assert-node-version')(path.join(__dirname, '../'));
6
- } catch (err) {
7
- exitWithError(err.message);
8
- }
@@ -1,178 +0,0 @@
1
- import {
2
- formatProblems,
3
- getTotals,
4
- loadConfig,
5
- getMergedConfig,
6
- OutputFormat,
7
- lint,
8
- bundle,
9
- } from '@redocly/openapi-core';
10
- import {
11
- dumpBundle,
12
- getExecutionTime,
13
- getFallbackEntryPointsOrExit,
14
- getOutputFileName,
15
- handleError,
16
- printUnusedWarnings,
17
- saveBundle,
18
- printLintTotals,
19
- } from '../utils';
20
- import { OutputExtensions, Totals } from '../types';
21
- import { performance } from 'perf_hooks';
22
- import { blue, gray, green, red, yellow } from 'colorette';
23
- import { writeFileSync } from 'fs';
24
-
25
- export async function handleBundle(
26
- argv: {
27
- entrypoints: string[];
28
- output?: string;
29
- ext: OutputExtensions;
30
- 'max-problems'?: number;
31
- 'skip-rule'?: string[];
32
- 'skip-preprocessor'?: string[];
33
- 'skip-decorator'?: string[];
34
- dereferenced?: boolean;
35
- force?: boolean;
36
- config?: string;
37
- lint?: boolean;
38
- format: OutputFormat;
39
- metafile?: string;
40
- extends?: string[];
41
- 'remove-unused-components'?: boolean;
42
- },
43
- version: string,
44
- ) {
45
- const config = await loadConfig(argv.config, argv.extends);
46
- const removeUnusedComponents =
47
- argv['remove-unused-components'] &&
48
- !config.rawConfig.lint?.decorators?.hasOwnProperty('remove-unused-components');
49
- const entrypoints = await getFallbackEntryPointsOrExit(argv.entrypoints, config);
50
- const totals: Totals = { errors: 0, warnings: 0, ignored: 0 };
51
- const maxProblems = argv['max-problems'];
52
-
53
- for (const { path, alias } of entrypoints) {
54
- try {
55
- const startedAt = performance.now();
56
- const resolvedConfig = getMergedConfig(config, alias);
57
- resolvedConfig.lint.skipRules(argv['skip-rule']);
58
- resolvedConfig.lint.skipPreprocessors(argv['skip-preprocessor']);
59
- resolvedConfig.lint.skipDecorators(argv['skip-decorator']);
60
-
61
- if (argv.lint) {
62
- if (config.lint.recommendedFallback) {
63
- process.stderr.write(
64
- `No configurations were defined in extends -- using built in ${blue(
65
- 'recommended',
66
- )} configuration by default.\n${red(
67
- 'Warning! This default behavior is going to be deprecated soon.',
68
- )}\n\n`,
69
- );
70
- }
71
- const results = await lint({
72
- ref: path,
73
- config: resolvedConfig,
74
- });
75
- const fileLintTotals = getTotals(results);
76
-
77
- totals.errors += fileLintTotals.errors;
78
- totals.warnings += fileLintTotals.warnings;
79
- totals.ignored += fileLintTotals.ignored;
80
-
81
- formatProblems(results, {
82
- format: argv.format || 'codeframe',
83
- totals: fileLintTotals,
84
- version,
85
- maxProblems,
86
- });
87
- printLintTotals(fileLintTotals, 2);
88
- }
89
-
90
- process.stderr.write(gray(`bundling ${path}...\n`));
91
-
92
- const {
93
- bundle: result,
94
- problems,
95
- ...meta
96
- } = await bundle({
97
- config: resolvedConfig,
98
- ref: path,
99
- dereference: argv.dereferenced,
100
- removeUnusedComponents,
101
- });
102
-
103
- const fileTotals = getTotals(problems);
104
- const { outputFile, ext } = getOutputFileName(
105
- path,
106
- entrypoints.length,
107
- argv.output,
108
- argv.ext,
109
- );
110
-
111
- if (fileTotals.errors === 0 || argv.force) {
112
- if (!argv.output) {
113
- const output = dumpBundle(result.parsed, argv.ext || 'yaml', argv.dereferenced);
114
- process.stdout.write(output);
115
- } else {
116
- const output = dumpBundle(result.parsed, ext, argv.dereferenced);
117
- saveBundle(outputFile, output);
118
- }
119
- }
120
-
121
- totals.errors += fileTotals.errors;
122
- totals.warnings += fileTotals.warnings;
123
- totals.ignored += fileTotals.ignored;
124
-
125
- formatProblems(problems, {
126
- format: argv.format,
127
- maxProblems,
128
- totals: fileTotals,
129
- version,
130
- });
131
-
132
- if (argv.metafile) {
133
- if (entrypoints.length > 1) {
134
- process.stderr.write(
135
- yellow(`[WARNING] "--metafile" cannot be used with multiple entrypoints. Skipping...`),
136
- );
137
- }
138
- {
139
- writeFileSync(argv.metafile, JSON.stringify(meta), 'utf-8');
140
- }
141
- }
142
-
143
- const elapsed = getExecutionTime(startedAt);
144
- if (fileTotals.errors > 0) {
145
- if (argv.force) {
146
- process.stderr.write(
147
- `❓ Created a bundle for ${blue(path)} at ${blue(outputFile)} with errors ${green(
148
- elapsed,
149
- )}.\n${yellow('Errors ignored because of --force')}.\n`,
150
- );
151
- } else {
152
- process.stderr.write(
153
- `❌ Errors encountered while bundling ${blue(
154
- path,
155
- )}: bundle not created (use --force to ignore errors).\n`,
156
- );
157
- }
158
- } else {
159
- process.stderr.write(
160
- `📦 Created a bundle for ${blue(path)} at ${blue(outputFile)} ${green(elapsed)}.\n`,
161
- );
162
- }
163
-
164
- const removedCount = meta.visitorsData?.['remove-unused-components']?.removedCount;
165
- if (removedCount) {
166
- process.stderr.write(gray(`🧹 Removed ${removedCount} unused components.\n`));
167
- }
168
- } catch (e) {
169
- handleError(e, path);
170
- }
171
- }
172
-
173
- printUnusedWarnings(config.lint);
174
-
175
- // defer process exit to allow STDOUT pipe to flush
176
- // see https://github.com/nodejs/node-v0.x-archive/issues/3737#issuecomment-19156072
177
- process.once('exit', () => process.exit(totals.errors === 0 || argv.force ? 0 : 1));
178
- }