slicejs-web-framework 3.4.4 → 3.5.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 (110) hide show
  1. package/Slice/Components/Structural/Controller/Controller.js +135 -0
  2. package/Slice/Components/Structural/EventManager/EventManager.js +289 -4
  3. package/Slice/Components/Structural/EventManager/EventManagerDebugger.js +368 -30
  4. package/Slice/Components/Structural/LeakInspector/LeakInspector.js +296 -0
  5. package/Slice/Components/Structural/StylesManager/ThemeManager/ThemeManager.js +56 -0
  6. package/Slice/Slice.js +14 -1
  7. package/Slice/tests/event-emitters.test.js +79 -0
  8. package/Slice/tests/event-registry.test.js +141 -0
  9. package/Slice/tests/leak-orphans.test.js +131 -0
  10. package/api/{middleware → framework}/securityMiddleware.js +18 -74
  11. package/api/framework/server.js +333 -0
  12. package/api/index.js +5 -279
  13. package/api/tests/public-env-resolver.test.js +1 -1
  14. package/package.json +4 -2
  15. package/sliceConfig.schema.json +10 -1
  16. package/src/App/index.html +31 -1
  17. package/src/manifest.json +15 -0
  18. package/src/robots.txt +4 -0
  19. package/src/sitemap.xml +8 -0
  20. package/src/sliceConfig.json +5 -1
  21. package/types/index.d.ts +12 -0
  22. package/slicejs-cli/.github/workflows/ci.yml +0 -43
  23. package/slicejs-cli/LICENSE +0 -21
  24. package/slicejs-cli/assets/Slice.js-logo.png +0 -0
  25. package/slicejs-cli/client.js +0 -740
  26. package/slicejs-cli/commands/Print.js +0 -164
  27. package/slicejs-cli/commands/Validations.js +0 -92
  28. package/slicejs-cli/commands/build/build.js +0 -40
  29. package/slicejs-cli/commands/buildProduction/buildProduction.js +0 -577
  30. package/slicejs-cli/commands/bundle/bundle.js +0 -236
  31. package/slicejs-cli/commands/createComponent/VisualComponentTemplate.js +0 -55
  32. package/slicejs-cli/commands/createComponent/createComponent.js +0 -128
  33. package/slicejs-cli/commands/deleteComponent/deleteComponent.js +0 -81
  34. package/slicejs-cli/commands/doctor/doctor.js +0 -516
  35. package/slicejs-cli/commands/getComponent/getComponent.js +0 -695
  36. package/slicejs-cli/commands/init/init.js +0 -473
  37. package/slicejs-cli/commands/listComponents/listComponents.js +0 -172
  38. package/slicejs-cli/commands/startServer/startServer.js +0 -240
  39. package/slicejs-cli/commands/startServer/watchServer.js +0 -66
  40. package/slicejs-cli/commands/types/types.js +0 -583
  41. package/slicejs-cli/commands/utils/LocalCliDelegation.js +0 -53
  42. package/slicejs-cli/commands/utils/PackageManager.js +0 -148
  43. package/slicejs-cli/commands/utils/PathHelper.js +0 -75
  44. package/slicejs-cli/commands/utils/VersionChecker.js +0 -169
  45. package/slicejs-cli/commands/utils/bundling/BundleGenerator.js +0 -2525
  46. package/slicejs-cli/commands/utils/bundling/DependencyAnalyzer.js +0 -933
  47. package/slicejs-cli/commands/utils/loadConfig.js +0 -31
  48. package/slicejs-cli/commands/utils/sliceScripts.js +0 -48
  49. package/slicejs-cli/commands/utils/updateManager.js +0 -471
  50. package/slicejs-cli/package.json +0 -71
  51. package/slicejs-cli/playwright.config.js +0 -51
  52. package/slicejs-cli/pnpm-lock.yaml +0 -1629
  53. package/slicejs-cli/tests/build-command-integration.test.js +0 -87
  54. package/slicejs-cli/tests/build-mangling-e2e.test.js +0 -290
  55. package/slicejs-cli/tests/build-production-e2e.test.js +0 -140
  56. package/slicejs-cli/tests/builder-edge-cases.test.js +0 -322
  57. package/slicejs-cli/tests/bundle-generate-e2e.test.js +0 -115
  58. package/slicejs-cli/tests/bundle-generator.test.js +0 -691
  59. package/slicejs-cli/tests/bundle-v2-register-output.test.js +0 -470
  60. package/slicejs-cli/tests/bundling-dependency-edges.test.js +0 -127
  61. package/slicejs-cli/tests/bundling-imports-unit.test.js +0 -267
  62. package/slicejs-cli/tests/client-launcher-contract.test.js +0 -211
  63. package/slicejs-cli/tests/commands-component-crud.test.js +0 -128
  64. package/slicejs-cli/tests/commands-doctor.test.js +0 -152
  65. package/slicejs-cli/tests/commands-version-checker.test.js +0 -37
  66. package/slicejs-cli/tests/component-registry-parse.test.js +0 -34
  67. package/slicejs-cli/tests/dependency-analyzer.test.js +0 -24
  68. package/slicejs-cli/tests/e2e/bundles.spec.js +0 -91
  69. package/slicejs-cli/tests/e2e/dependency-scenarios.spec.js +0 -56
  70. package/slicejs-cli/tests/e2e/fixtures/components/Service/FetchManager/FetchManager.js +0 -136
  71. package/slicejs-cli/tests/e2e/fixtures/components/Service/IndexedDbManager/IndexedDbManager.js +0 -149
  72. package/slicejs-cli/tests/e2e/fixtures/components/Service/LocalStorageManager/LocalStorageManager.js +0 -45
  73. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Button/Button.css +0 -106
  74. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Button/Button.html +0 -5
  75. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Button/Button.js +0 -158
  76. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Link/Link.js +0 -33
  77. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Loading/Loading.css +0 -56
  78. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Loading/Loading.html +0 -83
  79. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Loading/Loading.js +0 -164
  80. package/slicejs-cli/tests/e2e/fixtures/components/Visual/MultiRoute/MultiRoute.js +0 -167
  81. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Navbar/Navbar.css +0 -116
  82. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Navbar/Navbar.html +0 -44
  83. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Navbar/Navbar.js +0 -180
  84. package/slicejs-cli/tests/e2e/fixtures/components/Visual/NotFound/NotFound.js +0 -20
  85. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Route/Route.js +0 -181
  86. package/slicejs-cli/tests/e2e/fixtures/components/registry.json +0 -12
  87. package/slicejs-cli/tests/e2e/fixtures/vendor-components.mjs +0 -65
  88. package/slicejs-cli/tests/e2e/navigation.spec.js +0 -44
  89. package/slicejs-cli/tests/e2e/render.spec.js +0 -34
  90. package/slicejs-cli/tests/e2e/serve.mjs +0 -264
  91. package/slicejs-cli/tests/e2e/shared-deps.spec.js +0 -61
  92. package/slicejs-cli/tests/e2e/unminified.spec.js +0 -33
  93. package/slicejs-cli/tests/e2e-serve.test.js +0 -148
  94. package/slicejs-cli/tests/fixtures/components.js +0 -8
  95. package/slicejs-cli/tests/fixtures/sliceConfig.json +0 -74
  96. package/slicejs-cli/tests/getcomponent.test.js +0 -435
  97. package/slicejs-cli/tests/helpers/setup.js +0 -102
  98. package/slicejs-cli/tests/init-command-contract.test.js +0 -101
  99. package/slicejs-cli/tests/init-e2e.test.js +0 -82
  100. package/slicejs-cli/tests/init-project-isolation.test.js +0 -98
  101. package/slicejs-cli/tests/local-cli-delegation.test.js +0 -81
  102. package/slicejs-cli/tests/package-manager.test.js +0 -127
  103. package/slicejs-cli/tests/path-helper.test.js +0 -206
  104. package/slicejs-cli/tests/perf-budget.test.js +0 -84
  105. package/slicejs-cli/tests/postinstall-command.test.js +0 -103
  106. package/slicejs-cli/tests/property-mangling-regression.test.js +0 -182
  107. package/slicejs-cli/tests/types-breakage.test.js +0 -491
  108. package/slicejs-cli/tests/types-generator-errors.test.js +0 -361
  109. package/slicejs-cli/tests/types-generator.test.js +0 -348
  110. /package/api/{utils → framework}/publicEnvResolver.js +0 -0
@@ -1,361 +0,0 @@
1
- import { test, describe, before } from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import fs from 'node:fs';
4
- import path from 'node:path';
5
- import { createTestProject, cleanupTestProject } from './helpers/setup.js';
6
-
7
- import {
8
- ensureEditorConfigForTypes,
9
- extractStaticPropsFromSource,
10
- generateTypesFile,
11
- generateDeclarationContent
12
- } from '../commands/types/types.js';
13
-
14
- describe('parseComponentsRegistry', () => {
15
- let parseComponentsRegistry;
16
-
17
- before(async () => {
18
- const types = await import('../commands/types/types.js');
19
- parseComponentsRegistry = types.parseComponentsRegistry;
20
- });
21
-
22
- test('parses valid components.js content', () => {
23
- const content = 'const components = {"Button": "Visual", "FetchManager": "Service"};\nexport default components;\n';
24
- const result = parseComponentsRegistry(content, '/fake/path/components.js');
25
- assert.deepEqual(result, { Button: 'Visual', FetchManager: 'Service' });
26
- });
27
-
28
- test('parses components.js with newlines and whitespace', () => {
29
- const content = 'const components = {\n "Button": "Visual",\n "FetchManager": "Service"\n};\nexport default components;\n';
30
- const result = parseComponentsRegistry(content, '/fake/path/components.js');
31
- assert.deepEqual(result, { Button: 'Visual', FetchManager: 'Service' });
32
- });
33
-
34
- test('throws on content that does not match expected format', () => {
35
- const content = 'export default {};\n';
36
- assert.throws(
37
- () => parseComponentsRegistry(content, '/project/src/Components/components.js'),
38
- /Invalid format in.*components.js.*Expected: const components/
39
- );
40
- });
41
-
42
- test('throws on completely unrelated content', () => {
43
- assert.throws(
44
- () => parseComponentsRegistry('not javascript at all!!!', '/project/src/Components/components.js'),
45
- /Invalid format in/
46
- );
47
- });
48
-
49
- test('throws on malformed JSON inside matched pattern', () => {
50
- const content = 'const components = {"Button": "Visual", invalid};\nexport default components;\n';
51
- assert.throws(
52
- () => parseComponentsRegistry(content, '/project/src/Components/components.js'),
53
- /Failed to parse components registry/
54
- );
55
- });
56
-
57
- test('throws on empty object literal but JSON valid', () => {
58
- const content = 'const components = {};\nexport default components;\n';
59
- const result = parseComponentsRegistry(content, '/fake/path/components.js');
60
- assert.deepEqual(result, {});
61
- });
62
- });
63
-
64
- describe('extractStaticPropsFromSource errors', () => {
65
- test('returns null when source has a syntax error', () => {
66
- const source = 'export default class Broken extends HTMLElement {';
67
- const result = extractStaticPropsFromSource(source, '/test/Broken.js');
68
- assert.equal(result, null);
69
- });
70
-
71
- test('returns null when source has no static props', () => {
72
- const source = `
73
- export default class Button extends HTMLElement {
74
- constructor() { super(); }
75
- connectedCallback() {}
76
- }
77
- `;
78
- const result = extractStaticPropsFromSource(source, '/test/Button.js');
79
- assert.equal(result, null);
80
- });
81
-
82
- test('returns null for an empty static props object', () => {
83
- const source = `
84
- export default class Button extends HTMLElement {
85
- static props = {};
86
- }
87
- `;
88
- const result = extractStaticPropsFromSource(source, '/test/Button.js');
89
- assert.equal(result, null);
90
- });
91
-
92
- test('returns null when there is no class at all', () => {
93
- const source = 'const x = 42;';
94
- const result = extractStaticPropsFromSource(source, '/test/NotClass.js');
95
- assert.equal(result, null);
96
- });
97
-
98
- test('parses static props with simple types', () => {
99
- const source = `
100
- export default class Button extends HTMLElement {
101
- static props = {
102
- label: { type: 'string' },
103
- count: { type: 'number' },
104
- active: { type: 'boolean' }
105
- };
106
- }
107
- `;
108
- const result = extractStaticPropsFromSource(source, '/test/Button.js');
109
- assert.deepEqual(result, {
110
- label: { type: 'string', required: false },
111
- count: { type: 'number', required: false },
112
- active: { type: 'boolean', required: false }
113
- });
114
- });
115
- });
116
-
117
- describe('generateTypesFile error scenarios', () => {
118
- test('throws when components.js does not exist', async () => {
119
- const tmpRoot = await createTestProject();
120
- try {
121
- const componentsPath = path.join(tmpRoot, 'src', 'Components', 'components.js');
122
- fs.unlinkSync(componentsPath);
123
- const outputFile = path.join(tmpRoot, 'src', 'slice-build.generated.d.ts');
124
- await assert.rejects(
125
- () => generateTypesFile({ projectRoot: tmpRoot, outputPath: outputFile }),
126
- /Cannot read components registry/
127
- );
128
- } finally {
129
- await cleanupTestProject(tmpRoot);
130
- }
131
- });
132
-
133
- test('throws when components.js has invalid format', async () => {
134
- const tmpRoot = await createTestProject({ visualComponents: ['Button'] });
135
- try {
136
- const componentsPath = path.join(tmpRoot, 'src', 'Components', 'components.js');
137
- fs.writeFileSync(componentsPath, 'export default {};\n', 'utf8');
138
- const outputFile = path.join(tmpRoot, 'src', 'slice-build.generated.d.ts');
139
- await assert.rejects(
140
- () => generateTypesFile({ projectRoot: tmpRoot, outputPath: outputFile }),
141
- /Invalid format in/
142
- );
143
- } finally {
144
- await cleanupTestProject(tmpRoot);
145
- }
146
- });
147
-
148
- test('throws when components.js has malformed JSON', async () => {
149
- const tmpRoot = await createTestProject({ visualComponents: ['Button'] });
150
- try {
151
- const componentsPath = path.join(tmpRoot, 'src', 'Components', 'components.js');
152
- fs.writeFileSync(componentsPath, 'const components = {"Button": "Visual", invalid};\nexport default components;\n', 'utf8');
153
- const outputFile = path.join(tmpRoot, 'src', 'slice-build.generated.d.ts');
154
- await assert.rejects(
155
- () => generateTypesFile({ projectRoot: tmpRoot, outputPath: outputFile }),
156
- /Failed to parse components registry/
157
- );
158
- } finally {
159
- await cleanupTestProject(tmpRoot);
160
- }
161
- });
162
-
163
- test('continues when a component JS file has parse error (Babel failure)', async () => {
164
- const tmpRoot = await createTestProject();
165
- const srcDir = path.join(tmpRoot, 'src');
166
- try {
167
- const visualDir = path.join(srcDir, 'Components', 'Visual', 'Button');
168
- const outputFile = path.join(srcDir, 'slice-build.generated.d.ts');
169
- fs.mkdirSync(visualDir, { recursive: true });
170
- fs.writeFileSync(
171
- path.join(visualDir, 'Button.js'),
172
- 'export default class Button extends HTMLElement { static props = { value: { type: "string" } }; }',
173
- 'utf8'
174
- );
175
- fs.mkdirSync(path.join(srcDir, 'Components', 'Visual', 'Broken'), { recursive: true });
176
- fs.writeFileSync(
177
- path.join(srcDir, 'Components', 'Visual', 'Broken', 'Broken.js'),
178
- 'export default class Broken extends HTMLElement { ',
179
- 'utf8'
180
- );
181
- fs.writeFileSync(
182
- path.join(srcDir, 'Components', 'components.js'),
183
- 'const components = {"Button": "Visual", "Broken": "Visual"};\nexport default components;\n',
184
- 'utf8'
185
- );
186
- const result = await generateTypesFile({ projectRoot: tmpRoot, outputPath: outputFile });
187
- assert.equal(result.componentsProcessed, 2);
188
- assert.equal(fs.existsSync(result.outputPath), true);
189
- } finally {
190
- await cleanupTestProject(tmpRoot);
191
- }
192
- });
193
-
194
- test('skips component when JS file is missing', async () => {
195
- const tmpRoot = await createTestProject();
196
- const srcDir = path.join(tmpRoot, 'src');
197
- try {
198
- const visualDir = path.join(srcDir, 'Components', 'Visual', 'Button');
199
- const outputFile = path.join(srcDir, 'slice-build.generated.d.ts');
200
- fs.mkdirSync(visualDir, { recursive: true });
201
- fs.writeFileSync(
202
- path.join(visualDir, 'Button.js'),
203
- 'export default class Button extends HTMLElement { static props = { value: { type: "string" } }; }',
204
- 'utf8'
205
- );
206
- fs.writeFileSync(
207
- path.join(srcDir, 'Components', 'components.js'),
208
- 'const components = {"Button": "Visual", "MissingComp": "Visual"};\nexport default components;\n',
209
- 'utf8'
210
- );
211
- const result = await generateTypesFile({ projectRoot: tmpRoot, outputPath: outputFile });
212
- assert.equal(result.componentsProcessed, 1);
213
- } finally {
214
- await cleanupTestProject(tmpRoot);
215
- }
216
- });
217
-
218
- test('handles an empty registry gracefully', async () => {
219
- const tmpRoot = await createTestProject();
220
- const srcDir = path.join(tmpRoot, 'src');
221
- try {
222
- const outputFile = path.join(srcDir, 'slice-build.generated.d.ts');
223
- fs.writeFileSync(
224
- path.join(srcDir, 'Components', 'components.js'),
225
- 'const components = {};\nexport default components;\n',
226
- 'utf8'
227
- );
228
- const result = await generateTypesFile({ projectRoot: tmpRoot, outputPath: outputFile });
229
- assert.equal(result.componentsProcessed, 0);
230
- assert.equal(fs.existsSync(result.outputPath), true);
231
- const content = fs.readFileSync(result.outputPath, 'utf8');
232
- assert.match(content, /SliceBuildApi/);
233
- } finally {
234
- await cleanupTestProject(tmpRoot);
235
- }
236
- });
237
-
238
- test('component without static props gets dynamic fallback', async () => {
239
- const tmpRoot = await createTestProject();
240
- const srcDir = path.join(tmpRoot, 'src');
241
- try {
242
- const visualDir = path.join(srcDir, 'Components', 'Visual', 'NoProps');
243
- const outputFile = path.join(srcDir, 'slice-build.generated.d.ts');
244
- fs.mkdirSync(visualDir, { recursive: true });
245
- fs.writeFileSync(
246
- path.join(visualDir, 'NoProps.js'),
247
- 'export default class NoProps extends HTMLElement { connectedCallback() {} }',
248
- 'utf8'
249
- );
250
- fs.writeFileSync(
251
- path.join(srcDir, 'Components', 'components.js'),
252
- 'const components = {"NoProps": "Visual"};\nexport default components;\n',
253
- 'utf8'
254
- );
255
- const result = await generateTypesFile({ projectRoot: tmpRoot, outputPath: outputFile });
256
- assert.equal(result.componentsProcessed, 1);
257
- const content = fs.readFileSync(result.outputPath, 'utf8');
258
- assert.match(content, /export interface NoPropsProps/);
259
- assert.match(content, /\[key: string\]: unknown;/);
260
- } finally {
261
- await cleanupTestProject(tmpRoot);
262
- }
263
- });
264
- });
265
-
266
- describe('generateDeclarationContent edge cases', () => {
267
- test('handles empty props map', () => {
268
- const content = generateDeclarationContent({});
269
- assert.match(content, /SliceComponentName = keyof SliceComponentPropsMap;/);
270
- assert.match(content, /export interface SliceComponentPropsMap/);
271
- });
272
-
273
- test('handles component with no props', () => {
274
- const content = generateDeclarationContent({ Button: {} });
275
- assert.match(content, /export interface ButtonProps/);
276
- assert.match(content, /\[key: string\]: unknown;/);
277
- });
278
-
279
- test('handles allowed values with mixed types', () => {
280
- const content = generateDeclarationContent({
281
- Input: {
282
- value: { type: 'string', required: false, allowedValues: ['a', 'b'] },
283
- size: { type: 'number', required: false, allowedValues: [1, 2, 3] }
284
- }
285
- });
286
- assert.match(content, /value\?: 'a' \| 'b';/);
287
- assert.match(content, /size\?: 1 \| 2 \| 3;/);
288
- });
289
- });
290
-
291
- describe('ensureEditorConfigForTypes robustness', () => {
292
- test('returns tsconfig_exists when tsconfig.json is present', async () => {
293
- const tmpRoot = await createTestProject();
294
- const outputFile = path.join(tmpRoot, 'src', 'slice-build.generated.d.ts');
295
- try {
296
- fs.writeFileSync(outputFile, 'export {};\n', 'utf8');
297
- fs.writeFileSync(path.join(tmpRoot, 'tsconfig.json'), '{}', 'utf8');
298
- const result = await ensureEditorConfigForTypes({ projectRoot: tmpRoot, outputPath: outputFile });
299
- assert.equal(result.mode, 'tsconfig_exists');
300
- assert.equal(fs.existsSync(path.join(tmpRoot, 'jsconfig.json')), false);
301
- } finally {
302
- await cleanupTestProject(tmpRoot);
303
- }
304
- });
305
-
306
- test('resets jsconfig when file is unreadable', async () => {
307
- const tmpRoot = await createTestProject();
308
- const outputFile = path.join(tmpRoot, 'src', 'slice-build.generated.d.ts');
309
- try {
310
- fs.writeFileSync(outputFile, 'export {};\n', 'utf8');
311
- const jsconfigPath = path.join(tmpRoot, 'jsconfig.json');
312
- fs.writeFileSync(jsconfigPath, '{', 'utf8');
313
- const result = await ensureEditorConfigForTypes({ projectRoot: tmpRoot, outputPath: outputFile });
314
- assert.equal(result.mode, 'reset_jsconfig');
315
- assert.equal(result.reason, 'invalid_json');
316
- assert.equal(fs.existsSync(jsconfigPath), true);
317
- const parsed = JSON.parse(fs.readFileSync(jsconfigPath, 'utf8'));
318
- assert.ok(parsed.compilerOptions);
319
- assert.ok(Array.isArray(parsed.include));
320
- } finally {
321
- await cleanupTestProject(tmpRoot);
322
- }
323
- });
324
-
325
- test('returns jsconfig_already_has_include when config is already correct', async () => {
326
- const tmpRoot = await createTestProject();
327
- const outputFile = path.join(tmpRoot, 'src', 'slice-build.generated.d.ts');
328
- try {
329
- fs.writeFileSync(outputFile, 'export {};\n', 'utf8');
330
- const result = await ensureEditorConfigForTypes({ projectRoot: tmpRoot, outputPath: outputFile });
331
- assert.equal(result.mode, 'created_jsconfig');
332
- const result2 = await ensureEditorConfigForTypes({ projectRoot: tmpRoot, outputPath: outputFile });
333
- assert.equal(result2.mode, 'updated_jsconfig');
334
- assert.equal(result2.includeAdded, false);
335
- } finally {
336
- await cleanupTestProject(tmpRoot);
337
- }
338
- });
339
-
340
- test('preserves existing compilerOptions when updating jsconfig', async () => {
341
- const tmpRoot = await createTestProject();
342
- const outputFile = path.join(tmpRoot, 'src', 'slice-build.generated.d.ts');
343
- const jsconfigPath = path.join(tmpRoot, 'jsconfig.json');
344
- try {
345
- fs.writeFileSync(outputFile, 'export {};\n', 'utf8');
346
- fs.writeFileSync(
347
- jsconfigPath,
348
- JSON.stringify({ compilerOptions: { strict: true, customOption: true }, include: ['src/Components/**/*.js'] }),
349
- 'utf8'
350
- );
351
- const result = await ensureEditorConfigForTypes({ projectRoot: tmpRoot, outputPath: outputFile });
352
- assert.equal(result.mode, 'updated_jsconfig');
353
- const parsed = JSON.parse(fs.readFileSync(jsconfigPath, 'utf8'));
354
- assert.equal(parsed.compilerOptions.strict, true);
355
- assert.equal(parsed.compilerOptions.customOption, true);
356
- assert.equal(parsed.compilerOptions.checkJs, true);
357
- } finally {
358
- await cleanupTestProject(tmpRoot);
359
- }
360
- });
361
- });