@teambit/typescript 1.0.108 → 1.0.110

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.
@@ -1,442 +0,0 @@
1
- import ts from 'typescript';
2
- import { Slot, SlotRegistry } from '@teambit/harmony';
3
- import { CLIAspect, CLIMain, MainRuntime } from '@teambit/cli';
4
- import { Compiler } from '@teambit/compiler';
5
- import { Logger, LoggerAspect, LoggerMain } from '@teambit/logger';
6
- import { SchemaAspect, SchemaExtractor, SchemaMain } from '@teambit/schema';
7
- import { PackageJsonProps } from '@teambit/pkg';
8
- import { TypescriptConfigMutator } from '@teambit/typescript.modules.ts-config-mutator';
9
- import { WorkspaceAspect } from '@teambit/workspace';
10
- import type { Workspace } from '@teambit/workspace';
11
- import { DependencyResolverAspect, DependencyResolverMain } from '@teambit/dependency-resolver';
12
- import pMapSeries from 'p-map-series';
13
- import { TsserverClient, TsserverClientOpts } from '@teambit/ts-server';
14
- import AspectLoaderAspect, { AspectLoaderMain } from '@teambit/aspect-loader';
15
- import WatcherAspect, { WatcherMain, WatchOptions } from '@teambit/watcher';
16
- import type { Component, ComponentID } from '@teambit/component';
17
- import { BuilderAspect, BuilderMain } from '@teambit/builder';
18
- import EnvsAspect, { EnvsMain } from '@teambit/envs';
19
- import { ScopeMain, ScopeAspect } from '@teambit/scope';
20
- import { TypeScriptExtractor } from './typescript.extractor';
21
- import { TypeScriptCompilerOptions } from './compiler-options';
22
- import { TypescriptAspect } from './typescript.aspect';
23
- import { TypescriptCompiler } from './typescript.compiler';
24
- import { TypeScriptParser } from './typescript.parser';
25
- import { SchemaNodeTransformer, SchemaTransformer } from './schema-transformer';
26
- import { SchemaTransformerPlugin } from './schema-transformer.plugin';
27
- import {
28
- ExportDeclarationTransformer,
29
- TypeAliasTransformer,
30
- FunctionLikeTransformer,
31
- SetAccessorTransformer,
32
- GetAccessorTransformer,
33
- IndexSignatureTransformer,
34
- PropertyDeclarationTransformer,
35
- ParameterTransformer,
36
- VariableStatementTransformer,
37
- VariableDeclaration,
38
- SourceFileTransformer,
39
- ClassDeclarationTransformer,
40
- InterfaceDeclarationTransformer,
41
- EnumDeclarationTransformer,
42
- BindingElementTransformer,
43
- ExportAssignmentTransformer,
44
- ImportDeclarationTransformer,
45
- IntersectionTypeTransformer,
46
- UnionTypeTransformer,
47
- TypeReferenceTransformer,
48
- TypeLiteralTransformer,
49
- LiteralTypeTransformer,
50
- TypeQueryTransformer,
51
- ArrayTypeTransformer,
52
- TypeOperatorTransformer,
53
- KeywordTypeTransformer,
54
- TupleTypeTransformer,
55
- ParenthesizedTypeTransformer,
56
- TypePredicateTransformer,
57
- IndexedAccessTypeTransformer,
58
- TemplateLiteralTypeSpanTransformer,
59
- TemplateLiteralTypeTransformer,
60
- ThisTypeTransformer,
61
- ConditionalTypeTransformer,
62
- NamedTupleTransformer,
63
- ConstructorTransformer,
64
- ExpressionStatementTransformer,
65
- ModuleDeclarationTransformer,
66
- } from './transformers';
67
- import { CheckTypesCmd } from './cmds/check-types.cmd';
68
- import { TsconfigPathsPerEnv, TsconfigWriter } from './tsconfig-writer';
69
- import WriteTsconfigCmd from './cmds/write-tsconfig.cmd';
70
- import { RemoveTypesTask } from './remove-types-task';
71
-
72
- export type TsMode = 'build' | 'dev';
73
-
74
- export type SchemaTransformerSlot = SlotRegistry<SchemaTransformer[]>;
75
- export type APITransformerSlot = SlotRegistry<SchemaNodeTransformer[]>;
76
-
77
- export type TsConfigTransformContext = {
78
- // mode: TsMode;
79
- };
80
-
81
- export type TsconfigWriterOptions = {
82
- clean?: boolean;
83
- silent?: boolean; // no prompt
84
- dedupe?: boolean;
85
- dryRun?: boolean;
86
- dryRunWithTsconfig?: boolean;
87
- };
88
-
89
- export type TsConfigTransformer = (
90
- config: TypescriptConfigMutator,
91
- context: TsConfigTransformContext
92
- ) => TypescriptConfigMutator;
93
-
94
- export class TypescriptMain {
95
- constructor(
96
- private logger: Logger,
97
- readonly schemaTransformerSlot: SchemaTransformerSlot,
98
- readonly apiTransformerSlot: APITransformerSlot,
99
- readonly workspace: Workspace,
100
- readonly scope: ScopeMain,
101
- readonly depResolver: DependencyResolverMain,
102
- private envs: EnvsMain,
103
- private tsConfigWriter: TsconfigWriter,
104
- private aspectLoader: AspectLoaderMain
105
- ) {}
106
-
107
- private tsServer: TsserverClient;
108
- /**
109
- * create a new compiler.
110
- */
111
- createCompiler(
112
- options: TypeScriptCompilerOptions,
113
- transformers: TsConfigTransformer[] = [],
114
- tsModule = ts
115
- ): Compiler {
116
- const configMutator = new TypescriptConfigMutator(options);
117
- const transformerContext: TsConfigTransformContext = {};
118
- const afterMutation = runTransformersWithContext(configMutator.clone(), transformers, transformerContext);
119
- return new TypescriptCompiler(TypescriptAspect.id, this.logger, afterMutation.raw, tsModule);
120
- }
121
-
122
- /**
123
- * get TsserverClient instance if initiated already, otherwise, return undefined.
124
- */
125
- getTsserverClient(): TsserverClient | undefined {
126
- return this.tsServer;
127
- }
128
-
129
- registerSchemaTransformer(transformers: SchemaTransformer[]) {
130
- this.schemaTransformerSlot.register(transformers);
131
- return this;
132
- }
133
-
134
- registerApiTransformer(transformers: SchemaNodeTransformer[]) {
135
- this.apiTransformerSlot.register(transformers);
136
- return this;
137
- }
138
-
139
- /**
140
- * starts a tsserver process to communicate with its API.
141
- * @param projectPath absolute path of the project root directory
142
- * @param options TsserverClientOpts
143
- * @param files optionally, if check-types is enabled, provide files to open and type check.
144
- * @returns TsserverClient
145
- */
146
- async initTsserverClient(
147
- projectPath: string,
148
- options: TsserverClientOpts = {},
149
- files: string[] = []
150
- ): Promise<TsserverClient> {
151
- this.tsServer = new TsserverClient(projectPath, this.logger, options, files);
152
- await this.tsServer.init();
153
- return this.tsServer;
154
- }
155
-
156
- /**
157
- * starts a tsserver process to communicate with its API. use only when running on the workspace.
158
- * @param options TsserverClientOpts
159
- * @param files optionally, if check-types is enabled, provide files to open and type check.
160
- * @returns TsserverClient
161
- */
162
- async initTsserverClientFromWorkspace(
163
- options: TsserverClientOpts = {},
164
- files: string[] = []
165
- ): Promise<TsserverClient> {
166
- if (!this.workspace) {
167
- throw new Error(`initTsserverClientFromWorkspace: workspace was not found`);
168
- }
169
- return this.initTsserverClient(this.workspace.path, options, files);
170
- }
171
-
172
- /**
173
- * Create a compiler instance and run the cjs transformer for it
174
- * @param options
175
- * @param transformers
176
- * @param tsModule
177
- * @returns
178
- */
179
- createCjsCompiler(options: TypeScriptCompilerOptions, transformers: TsConfigTransformer[] = [], tsModule = ts) {
180
- return this.createCompiler(options, [this.getCjsTransformer(), ...transformers], tsModule);
181
- }
182
-
183
- /**
184
- * Create a compiler instance and run the esm transformer for it
185
- * @param options
186
- * @param transformers
187
- * @param tsModule
188
- * @returns
189
- */
190
- createEsmCompiler(options: TypeScriptCompilerOptions, transformers: TsConfigTransformer[] = [], tsModule = ts) {
191
- return this.createCompiler(options, [this.getEsmTransformer(), ...transformers], tsModule);
192
- }
193
-
194
- /**
195
- * Create a transformer that change the ts module to CommonJS
196
- * @returns
197
- */
198
- getCjsTransformer(): TsConfigTransformer {
199
- const cjsTransformer = (config: TypescriptConfigMutator) => {
200
- config.setModule('CommonJS');
201
- return config;
202
- };
203
- return cjsTransformer;
204
- }
205
-
206
- /**
207
- * Create a transformer that change the ts module to ES2020
208
- * @returns
209
- */
210
- getEsmTransformer(): TsConfigTransformer {
211
- const esmTransformer = (config: TypescriptConfigMutator) => {
212
- config.setTarget('ES2017');
213
- config.raw.tsconfig.compilerOptions.module = 'es2020';
214
- config.raw.tsconfig.compilerOptions.lib = ['es2021', 'dom', 'ESNext.String', 'dom.Iterable'];
215
- return config;
216
- };
217
- return esmTransformer;
218
- }
219
-
220
- /**
221
- * create an instance of a typescript semantic schema extractor.
222
- */
223
- createSchemaExtractor(tsconfig: any, tsserverPath?: string, contextPath?: string): SchemaExtractor {
224
- return new TypeScriptExtractor(
225
- tsconfig,
226
- this.schemaTransformerSlot,
227
- this.apiTransformerSlot,
228
- this,
229
- tsserverPath || this.workspace?.path || '',
230
- contextPath || this.workspace?.path || '',
231
- this.depResolver,
232
- this.workspace,
233
- this.scope,
234
- this.aspectLoader,
235
- this.logger
236
- );
237
- }
238
-
239
- /**
240
- * add the default package json properties to the component
241
- * :TODO @gilad why do we need this DSL? can't I just get the args here.
242
- */
243
- getCjsPackageJsonProps(): PackageJsonProps {
244
- return {
245
- main: 'dist/{main}.js',
246
- types: '{main}.ts',
247
- };
248
- }
249
-
250
- /**
251
- * add type: module to the package.json props and the default props
252
- * :TODO @gilad why do we need this DSL? can't I just get the args here.
253
- */
254
- getEsmPackageJsonProps(): PackageJsonProps {
255
- return {
256
- // main: 'dist-esm/{main}.js',
257
- main: 'dist/{main}.js',
258
- type: 'module',
259
- types: '{main}.ts',
260
- };
261
- }
262
-
263
- getSupportedFilesForTsserver(components: Component[]): string[] {
264
- const files = components
265
- .map((c) => c.filesystem.files)
266
- .flat()
267
- .map((f) => f.path);
268
- return files.filter((f) => f.endsWith('.ts') || f.endsWith('.tsx'));
269
- }
270
-
271
- async cleanTsconfigJson(options: TsconfigWriterOptions = {}) {
272
- const components = await this.workspace.list();
273
- const runtime = await this.envs.createEnvironment(components);
274
- const execContext = runtime.getEnvExecutionContext();
275
-
276
- const results = await new TsconfigWriter(this.workspace, this.logger).clean(execContext, options);
277
-
278
- return results;
279
- }
280
-
281
- async writeTsconfigJson(options: TsconfigWriterOptions = {}): Promise<{
282
- cleanResults?: string[];
283
- writeResults: TsconfigPathsPerEnv[];
284
- }> {
285
- const components = await this.workspace.list();
286
- const runtime = await this.envs.createEnvironment(components);
287
- const execContext = runtime.getEnvExecutionContext();
288
-
289
- let cleanResults: string[] | undefined;
290
- if (options.clean) {
291
- cleanResults = await this.tsConfigWriter.clean(execContext, options);
292
- }
293
-
294
- const writeResults = await this.tsConfigWriter.write(execContext, options);
295
-
296
- return { writeResults, cleanResults };
297
- }
298
-
299
- private async onPreWatch(componentIds: ComponentID[], watchOpts: WatchOptions) {
300
- const workspace = this.workspace;
301
- if (!workspace || !watchOpts.spawnTSServer) {
302
- return;
303
- }
304
- const { verbose, checkTypes } = watchOpts;
305
- const files = checkTypes ? this.getSupportedFilesForTsserver(await workspace.getMany(componentIds)) : [];
306
- const printTypeErrors = Boolean(checkTypes);
307
- await this.initTsserverClientFromWorkspace({ verbose, checkTypes, printTypeErrors }, files);
308
- }
309
-
310
- private async onComponentChange(component: Component, files: string[]) {
311
- if (!this.tsServer) {
312
- return {
313
- results: 'N/A',
314
- };
315
- }
316
- await pMapSeries(files, (file) => this.tsServer.onFileChange(file));
317
- return {
318
- results: 'succeed',
319
- };
320
- }
321
-
322
- static runtime = MainRuntime;
323
- static dependencies = [
324
- SchemaAspect,
325
- LoggerAspect,
326
- AspectLoaderAspect,
327
- WorkspaceAspect,
328
- CLIAspect,
329
- DependencyResolverAspect,
330
- EnvsAspect,
331
- WatcherAspect,
332
- ScopeAspect,
333
- BuilderAspect,
334
- ];
335
- static slots = [Slot.withType<SchemaTransformer[]>(), Slot.withType<SchemaNodeTransformer[]>()];
336
-
337
- static async provider(
338
- [schema, loggerExt, aspectLoader, workspace, cli, depResolver, envs, watcher, scope, builder]: [
339
- SchemaMain,
340
- LoggerMain,
341
- AspectLoaderMain,
342
- Workspace,
343
- CLIMain,
344
- DependencyResolverMain,
345
- EnvsMain,
346
- WatcherMain,
347
- ScopeMain,
348
- BuilderMain
349
- ],
350
- config,
351
- [schemaTransformerSlot, apiTransformerSlot]: [SchemaTransformerSlot, APITransformerSlot]
352
- ) {
353
- schema.registerParser(new TypeScriptParser());
354
- const logger = loggerExt.createLogger(TypescriptAspect.id);
355
-
356
- aspectLoader.registerPlugins([new SchemaTransformerPlugin(schemaTransformerSlot)]);
357
- const tsconfigWriter = new TsconfigWriter(workspace, logger);
358
- const tsMain = new TypescriptMain(
359
- logger,
360
- schemaTransformerSlot,
361
- apiTransformerSlot,
362
- workspace,
363
- scope,
364
- depResolver,
365
- envs,
366
- tsconfigWriter,
367
- aspectLoader
368
- );
369
- tsMain.registerSchemaTransformer([
370
- new ExportDeclarationTransformer(),
371
- new ExportAssignmentTransformer(),
372
- new FunctionLikeTransformer(),
373
- new ParameterTransformer(),
374
- new SetAccessorTransformer(),
375
- new GetAccessorTransformer(),
376
- new IndexSignatureTransformer(),
377
- new PropertyDeclarationTransformer(),
378
- new VariableStatementTransformer(),
379
- new VariableDeclaration(),
380
- new SourceFileTransformer(),
381
- new TypeAliasTransformer(),
382
- new ClassDeclarationTransformer(),
383
- new InterfaceDeclarationTransformer(),
384
- new EnumDeclarationTransformer(),
385
- new BindingElementTransformer(),
386
- new IntersectionTypeTransformer(),
387
- new UnionTypeTransformer(),
388
- new TypeReferenceTransformer(),
389
- new TypeLiteralTransformer(),
390
- new LiteralTypeTransformer(),
391
- new TypeQueryTransformer(),
392
- new ArrayTypeTransformer(),
393
- new TypeOperatorTransformer(),
394
- new KeywordTypeTransformer(),
395
- new TupleTypeTransformer(),
396
- new ParenthesizedTypeTransformer(),
397
- new TypePredicateTransformer(),
398
- new IndexedAccessTypeTransformer(),
399
- new TemplateLiteralTypeSpanTransformer(),
400
- new TemplateLiteralTypeTransformer(),
401
- new ThisTypeTransformer(),
402
- new ConditionalTypeTransformer(),
403
- new NamedTupleTransformer(),
404
- new ConstructorTransformer(),
405
- new ImportDeclarationTransformer(),
406
- new ExpressionStatementTransformer(),
407
- new ModuleDeclarationTransformer(),
408
- ]);
409
-
410
- if (workspace) {
411
- watcher.registerOnPreWatch(tsMain.onPreWatch.bind(tsMain));
412
- workspace.registerOnComponentChange(tsMain.onComponentChange.bind(tsMain));
413
- workspace.registerOnComponentAdd(tsMain.onComponentChange.bind(tsMain));
414
- }
415
-
416
- const removeTypesTask = new RemoveTypesTask();
417
- builder.registerSnapTasks([removeTypesTask]);
418
- builder.registerTagTasks([removeTypesTask]);
419
-
420
- const checkTypesCmd = new CheckTypesCmd(tsMain, workspace, logger);
421
- const writeTsconfigCmd = new WriteTsconfigCmd(tsMain);
422
- cli.register(checkTypesCmd, writeTsconfigCmd);
423
-
424
- return tsMain;
425
- }
426
- }
427
-
428
- TypescriptAspect.addRuntime(TypescriptMain);
429
-
430
- export function runTransformersWithContext(
431
- config: TypescriptConfigMutator,
432
- transformers: TsConfigTransformer[] = [],
433
- context: TsConfigTransformContext
434
- ): TypescriptConfigMutator {
435
- if (!Array.isArray(transformers)) return config;
436
- const newConfig = transformers.reduce((acc, transformer) => {
437
- return transformer(acc, context);
438
- }, config);
439
- return newConfig;
440
- }
441
-
442
- export default TypescriptMain;
@@ -1,221 +0,0 @@
1
- import ts from 'typescript';
2
- import { expect } from 'chai';
3
-
4
- import { TypeScriptParser } from './typescript.parser';
5
-
6
- describe('TypescriptParser', () => {
7
- describe('getExports', () => {
8
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export
9
- // https://www.typescriptlang.org/docs/handbook/modules.html#export
10
-
11
- const exampleArrowFunction = `
12
- export const arrow = () => { return 3; }
13
- arrow.textProperty = "propertyValue";
14
- `;
15
-
16
- const exampleFunction = `
17
- export function func() { return 3; }
18
- func.textProperty = "propertyValue";
19
- `;
20
-
21
- const exampleClass = `
22
- export class classy{ render() { return 3; } }
23
- classy.textProperty = "propertyValue";
24
- `;
25
-
26
- const exampleStatement = `
27
- function myFunction2 () { return 3; }
28
- const myVariable2 = 3;
29
- export { myFunction2, myVariable2 };
30
- `;
31
-
32
- const exampleRenamedStatement = `
33
- function myFunction2 () { return 3; }
34
- const myVariable2 = 3;
35
- export { myFunction2, myVariable2 as myVariable2Alias };
36
- `;
37
-
38
- const exampleReExport = `
39
- export { default as function1, function2 } from "bar.js";
40
- `;
41
-
42
- const exampleReExportDefault = `
43
- export { default, function2 } from "bar.js";
44
- `;
45
-
46
- const exampleRenamedReExportAll = `
47
- export * as ns from "mod";
48
- `;
49
-
50
- const exampleExportDefault = `
51
- const a: number = 1
52
- export default { a };
53
- `;
54
-
55
- it('should parse arrowFunctions', () => {
56
- const ast = ts.createSourceFile('example.tsx', exampleArrowFunction, ts.ScriptTarget.Latest);
57
- const exports = new TypeScriptParser().getExports(ast);
58
-
59
- const exportArrow = exports.find((x) => x.identifier === 'arrow');
60
-
61
- expect(exportArrow).to.exist;
62
- });
63
-
64
- it('should parse function exports', () => {
65
- const ast = ts.createSourceFile('example.tsx', exampleFunction, ts.ScriptTarget.Latest);
66
- const exports = new TypeScriptParser().getExports(ast);
67
-
68
- const exportFunction = exports.find((x) => x.identifier === 'func');
69
-
70
- expect(exportFunction).to.exist;
71
- });
72
-
73
- it('should parse classes', () => {
74
- const ast = ts.createSourceFile('example.tsx', exampleClass, ts.ScriptTarget.Latest);
75
- const exports = new TypeScriptParser().getExports(ast);
76
-
77
- const exportClass = exports.find((x) => x.identifier === 'classy');
78
-
79
- expect(exportClass).to.exist;
80
- });
81
-
82
- it('should parse declarations', () => {
83
- const ast = ts.createSourceFile('example.tsx', exampleStatement, ts.ScriptTarget.Latest);
84
- const exports = new TypeScriptParser().getExports(ast);
85
-
86
- const exportFunction = exports.find((x) => x.identifier === 'myFunction2');
87
- const exportVariable = exports.find((x) => x.identifier === 'myVariable2');
88
-
89
- expect(exportFunction).to.exist;
90
- expect(exportVariable).to.exist;
91
- });
92
-
93
- it('should parse renamed declarations', () => {
94
- const ast = ts.createSourceFile('example.tsx', exampleRenamedStatement, ts.ScriptTarget.Latest);
95
- const exports = new TypeScriptParser().getExports(ast);
96
-
97
- const exportFunction = exports.find((x) => x.identifier === 'myFunction2');
98
- const exportVariable = exports.find((x) => x.identifier === 'myVariable2Alias');
99
-
100
- expect(exportFunction).to.exist;
101
- expect(exportVariable).to.exist;
102
- });
103
-
104
- it('should parse re-exports', () => {
105
- const ast = ts.createSourceFile('example.tsx', exampleReExport, ts.ScriptTarget.Latest);
106
- const exports = new TypeScriptParser().getExports(ast);
107
-
108
- const exportFunction1 = exports.find((x) => x.identifier === 'function1');
109
- const exportFunction2 = exports.find((x) => x.identifier === 'function2');
110
-
111
- expect(exportFunction1).to.exist;
112
- expect(exportFunction2).to.exist;
113
- });
114
-
115
- it('should parse re-exports with default', () => {
116
- const ast = ts.createSourceFile('example.tsx', exampleReExportDefault, ts.ScriptTarget.Latest);
117
- const exports = new TypeScriptParser().getExports(ast);
118
-
119
- const exportFunction1 = exports.find((x) => x.identifier === 'default');
120
- const exportFunction2 = exports.find((x) => x.identifier === 'function2');
121
-
122
- expect(exportFunction1).not.to.exist;
123
- expect(exportFunction2).to.exist;
124
- });
125
-
126
- it('should parse renamed re-exports all', () => {
127
- const ast = ts.createSourceFile('example.tsx', exampleRenamedReExportAll, ts.ScriptTarget.Latest);
128
- const exports = new TypeScriptParser().getExports(ast);
129
-
130
- const exportFunction1 = exports.find((x) => x.identifier === 'ns');
131
-
132
- expect(exportFunction1).to.exist;
133
- });
134
-
135
- it('should parse default exports', () => {
136
- const ast = ts.createSourceFile('example.tsx', exampleExportDefault, ts.ScriptTarget.Latest);
137
- const exports = new TypeScriptParser().getExports(ast);
138
-
139
- expect(exports.length).to.equal(0);
140
- });
141
-
142
- describe('staticProperties', () => {
143
- it('should include staticProperties, when on arrowFunctions', () => {
144
- const ast = ts.createSourceFile('example.tsx', exampleArrowFunction, ts.ScriptTarget.Latest);
145
- const exports = new TypeScriptParser().getExports(ast);
146
-
147
- const exportArrow = exports.find((x) => x.identifier === 'arrow');
148
-
149
- expect(exportArrow?.staticProperties?.get('textProperty')).to.equal('propertyValue');
150
- });
151
-
152
- it('should include staticProperties, when on regular functions', () => {
153
- const ast = ts.createSourceFile('example.tsx', exampleFunction, ts.ScriptTarget.Latest);
154
- const exports = new TypeScriptParser().getExports(ast);
155
-
156
- const exportClass = exports.find((x) => x.identifier === 'func');
157
-
158
- expect(exportClass?.staticProperties?.get('textProperty')).to.equal('propertyValue');
159
- });
160
-
161
- it('should include staticProperties, when on classes', () => {
162
- const ast = ts.createSourceFile('example.tsx', exampleClass, ts.ScriptTarget.Latest);
163
- const exports = new TypeScriptParser().getExports(ast);
164
-
165
- const exportClass = exports.find((x) => x.identifier === 'classy');
166
-
167
- expect(exportClass?.staticProperties?.get('textProperty')).to.equal('propertyValue');
168
- });
169
- });
170
- });
171
-
172
- describe('collectStaticProperties', () => {
173
- const exampleFile = `
174
- export const hello = () => { return 3; }
175
-
176
- hello.text = "is";
177
- hello.count = 3;
178
- hello.nullish = null;
179
- hello.undef = undefined;
180
- hello.disable = false;
181
- hello.enable = true;
182
- hello.complextLiteral = \`what \${hello.text} it?\`;
183
- hello.nonAssignedProperty += 'value';
184
- `;
185
-
186
- it('should parse all primitive values', () => {
187
- const ast = ts.createSourceFile('example.tsx', exampleFile, ts.ScriptTarget.Latest);
188
- const staticProperties = new TypeScriptParser().parseStaticProperties(ast);
189
-
190
- expect(staticProperties).to.exist;
191
-
192
- const exportHello = staticProperties.get('hello');
193
- expect(exportHello).to.exist;
194
-
195
- expect(exportHello?.get('text')).to.equal('is');
196
- expect(exportHello?.get('count')).to.equal(3);
197
- expect(exportHello?.get('nullish')).to.equal(null);
198
- expect(exportHello?.get('undef')).to.equal(undefined);
199
- expect(exportHello?.get('disable')).to.equal(false);
200
- expect(exportHello?.get('enable')).to.equal(true);
201
-
202
- expect(exportHello?.has('complextLiteral')).to.be.false;
203
- });
204
-
205
- it('should skip non primitive values', () => {
206
- const ast = ts.createSourceFile('example.tsx', exampleFile, ts.ScriptTarget.Latest);
207
- const staticProperties = new TypeScriptParser().parseStaticProperties(ast);
208
- const exportHello = staticProperties.get('hello');
209
-
210
- expect(exportHello?.has('complextLiteral')).to.be.false;
211
- });
212
-
213
- it('should skip non assignment statements', () => {
214
- const ast = ts.createSourceFile('example.tsx', exampleFile, ts.ScriptTarget.Latest);
215
- const staticProperties = new TypeScriptParser().parseStaticProperties(ast);
216
- const exportHello = staticProperties.get('hello');
217
-
218
- expect(exportHello?.has('nonAssignedProperty')).to.be.false;
219
- });
220
- });
221
- });