@typed/vite-plugin 0.0.20 → 0.0.21

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,6 +1,7 @@
1
- import { existsSync } from 'fs'
1
+ import { existsSync, readFileSync, writeFileSync } from 'fs'
2
2
  import { readFile } from 'fs/promises'
3
- import { basename, dirname, relative, resolve } from 'path'
3
+ import { EOL } from 'os'
4
+ import { basename, dirname, join, relative, resolve } from 'path'
4
5
 
5
6
  import effectTransformer from '@effect/language-service/transformer'
6
7
  import {
@@ -11,12 +12,16 @@ import {
11
12
  readModules,
12
13
  readApiModules,
13
14
  makeApiModule,
15
+ type ApiModuleTreeJson,
16
+ type ModuleTreeJsonWithFallback,
17
+ moduleTreeToJson,
18
+ apiModuleTreeToJson,
14
19
  } from '@typed/compiler'
15
20
  import glob from 'fast-glob'
16
21
  import { Project, SourceFile, ts, type CompilerOptions } from 'ts-morph'
17
22
  // @ts-expect-error Unable to resolve types w/ NodeNext
18
23
  import vavite from 'vavite'
19
- import type { ConfigEnv, Plugin, PluginOption, UserConfig, ViteDevServer } from 'vite'
24
+ import type { ConfigEnv, Logger, Plugin, PluginOption, UserConfig, ViteDevServer } from 'vite'
20
25
  import compression from 'vite-plugin-compression'
21
26
  import tsconfigPaths from 'vite-tsconfig-paths'
22
27
 
@@ -66,17 +71,28 @@ export interface PluginOptions {
66
71
  * If true, will configure the plugin to save all the generated files to disk
67
72
  */
68
73
  readonly saveGeneratedModules?: boolean
74
+
75
+ /**
76
+ * If true, will configure the plugin to operate in a static build mode.
77
+ */
78
+ readonly isStaticBuild?: boolean
69
79
  }
70
80
 
71
81
  const cwd = process.cwd()
72
82
 
73
- const PLUGIN_NAME = '@typed/vite-plugin'
83
+ export const PLUGIN_NAME = '@typed/vite-plugin'
84
+
85
+ export interface TypedVitePlugin extends Plugin {
86
+ readonly name: typeof PLUGIN_NAME
87
+ readonly resolvedOptions: ResolvedOptions
88
+ }
74
89
 
75
90
  const RUNTIME_VIRTUAL_ENTRYPOINT_PREFIX = 'runtime'
76
91
  const BROWSER_VIRTUAL_ENTRYPOINT_PREFIX = 'browser'
77
92
  const HTML_VIRTUAL_ENTRYPOINT_PREFIX = 'html'
78
93
  const API_VIRTUAL_ENTRYPOINT_PREFIX = 'api'
79
94
  const EXPRESS_VIRTUAL_ENTRYPOINT_PREFIX = 'express'
95
+ const TYPED_CONFIG_IMPORT = 'typed:config'
80
96
 
81
97
  const PREFIXES = [
82
98
  RUNTIME_VIRTUAL_ENTRYPOINT_PREFIX,
@@ -88,6 +104,76 @@ const PREFIXES = [
88
104
 
89
105
  const VIRTUAL_ID_PREFIX = '\0'
90
106
 
107
+ export interface Manifest {
108
+ readonly entryFiles: EntryFile[]
109
+
110
+ readonly modules: {
111
+ [importer: string]: Record<string, ManifestEntry>
112
+ }
113
+ }
114
+
115
+ export interface ClientManifest extends Manifest {
116
+ readonly entryFiles: HtmlEntryFile[]
117
+
118
+ readonly modules: {
119
+ [importer: string]: Record<string, ManifestEntry>
120
+ }
121
+ }
122
+
123
+ export type EntryFile = HtmlEntryFile | TsEntryFile
124
+
125
+ export interface HtmlEntryFile {
126
+ readonly type: 'html'
127
+ readonly filePath: string
128
+ readonly imports: string[]
129
+ readonly basePath: string
130
+ }
131
+
132
+ export interface TsEntryFile {
133
+ readonly type: 'ts'
134
+ readonly filePath: string
135
+ }
136
+
137
+ export type ManifestEntry =
138
+ | ApiManifestEntry
139
+ | ExpressManifestEntry
140
+ | HtmlManifestEntry
141
+ | RuntimeManifestEntry
142
+ | BrowserManifestEntry
143
+
144
+ export interface ApiManifestEntry extends ApiModuleTreeJson {
145
+ readonly type: 'api'
146
+ }
147
+
148
+ export interface ExpressManifestEntry extends ApiModuleTreeJson {
149
+ readonly type: 'express'
150
+ }
151
+
152
+ export interface HtmlManifestEntry {
153
+ readonly type: 'html'
154
+ readonly filePath: string
155
+ }
156
+
157
+ export interface BrowserManifestEntry extends ModuleTreeJsonWithFallback {
158
+ readonly type: 'browser'
159
+ }
160
+
161
+ export interface RuntimeManifestEntry extends ModuleTreeJsonWithFallback {
162
+ readonly type: 'runtime'
163
+ }
164
+
165
+ export interface ResolvedOptions {
166
+ readonly sourceDirectory: string
167
+ readonly tsConfig: string
168
+ readonly serverFilePath: string
169
+ readonly clientOutputDirectory: string
170
+ readonly serverOutputDirectory: string
171
+ readonly htmlFiles: readonly string[]
172
+ readonly debug: boolean
173
+ readonly saveGeneratedModules: boolean
174
+ readonly isStaticBuild: boolean
175
+ }
176
+
91
177
  export default function makePlugin({
92
178
  sourceDirectory: directory,
93
179
  tsConfig,
@@ -97,6 +183,7 @@ export default function makePlugin({
97
183
  htmlFileGlobs,
98
184
  debug = false,
99
185
  saveGeneratedModules = false,
186
+ isStaticBuild = false,
100
187
  }: PluginOptions): PluginOption[] {
101
188
  // Resolved options
102
189
  const sourceDirectory = resolve(cwd, directory)
@@ -120,10 +207,38 @@ export default function makePlugin({
120
207
  debug: debug ? defaultIncludeExcludeTs : {},
121
208
  }
122
209
 
210
+ const resolvedOptions: ResolvedOptions = {
211
+ sourceDirectory,
212
+ tsConfig: tsConfigFilePath,
213
+ serverFilePath: resolvedServerFilePath,
214
+ serverOutputDirectory: resolvedServerOutputDirectory,
215
+ clientOutputDirectory: resolvedClientOutputDirectory,
216
+ htmlFiles: findHtmlFiles(sourceDirectory, htmlFileGlobs).map((p) =>
217
+ resolve(sourceDirectory, p),
218
+ ),
219
+ debug,
220
+ saveGeneratedModules,
221
+ isStaticBuild,
222
+ }
223
+
123
224
  const dependentsMap = new Map<string, Set<string>>()
124
225
  const filePathToModule = new Map<string, SourceFile>()
226
+ const manifest: Manifest = {
227
+ entryFiles: [],
228
+ modules: {},
229
+ }
230
+
231
+ const addManifestEntry = (entry: ManifestEntry, importer: string, id: string) => {
232
+ if (!manifest.modules[importer]) {
233
+ manifest.modules[importer] = {}
234
+ }
235
+
236
+ manifest.modules[importer][id] = entry
237
+ }
125
238
 
126
239
  let devServer: ViteDevServer
240
+ let logger: Logger
241
+ let isSsr = false
127
242
  let project: Project
128
243
  let transformers: ts.CustomTransformers
129
244
 
@@ -133,14 +248,6 @@ export default function makePlugin({
133
248
  tsconfigPaths({
134
249
  projects: [tsConfigFilePath],
135
250
  }),
136
- ...(serverExists
137
- ? [
138
- vavite({
139
- serverEntry: resolvedServerFilePath,
140
- serveClientAssetsInDev: true,
141
- }),
142
- ]
143
- : []),
144
251
  ]
145
252
 
146
253
  const setupProject = () => {
@@ -148,9 +255,9 @@ export default function makePlugin({
148
255
  return
149
256
  }
150
257
 
151
- info(`Setting up TypeScript project...`)
258
+ info(`Setting up TypeScript project...`, logger)
152
259
  project = setupTsProject(tsConfigFilePath)
153
- info(`Setup TypeScript project.`)
260
+ info(`Setup TypeScript project.`, logger)
154
261
 
155
262
  // Setup transformer for virtual modules.
156
263
  transformers = {
@@ -169,7 +276,9 @@ export default function makePlugin({
169
276
 
170
277
  return {
171
278
  ...project.getCompilerOptions(),
172
- allowJs: true,
279
+ inlineSourceMap: false,
280
+ inlineSources: saveGeneratedModules,
281
+ sourceMap: true,
173
282
  }
174
283
  }
175
284
 
@@ -196,7 +305,7 @@ export default function makePlugin({
196
305
  const mod = devServer.moduleGraph.getModuleById(dependent)
197
306
 
198
307
  if (mod) {
199
- info(`reloading ${dependent}`)
308
+ info(`reloading ${dependent}`, logger)
200
309
 
201
310
  await devServer.reloadModule(mod)
202
311
  }
@@ -213,24 +322,32 @@ export default function makePlugin({
213
322
  }
214
323
  }
215
324
 
216
- const buildRenderModule = async (importer: string, id: string) => {
325
+ const buildRuntimeModule = async (importer: string, id: string) => {
217
326
  const moduleDirectory = resolve(dirname(importer), parseModulesFromId(id, importer))
218
327
  const relativeDirectory = relative(sourceDirectory, moduleDirectory)
219
328
  const isBrowser = id.startsWith(BROWSER_VIRTUAL_ENTRYPOINT_PREFIX)
220
329
  const moduleType = isBrowser ? 'browser' : 'runtime'
221
330
  const filePath = `${moduleDirectory}.${moduleType}.__generated__.ts`
222
-
223
- info(`Building ${moduleType} module for ${relativeDirectory}...`)
224
-
225
331
  const directory = await readDirectory(moduleDirectory)
226
332
  const moduleTree = readModules(project, directory)
227
333
 
334
+ addManifestEntry(
335
+ {
336
+ type: moduleType,
337
+ ...moduleTreeToJson(sourceDirectory, moduleTree),
338
+ },
339
+ relative(sourceDirectory, importer),
340
+ id,
341
+ )
342
+
228
343
  // Setup the TypeScript project if it hasn't been already
229
344
  setupProject()
230
345
 
231
346
  const sourceFile = makeRuntimeModule(project, moduleTree, importer, filePath, isBrowser)
232
347
 
233
- info(`Built ${moduleType} module for ${relativeDirectory}.`)
348
+ addDependents(sourceFile)
349
+
350
+ info(`Built ${moduleType} module for ${relativeDirectory}.`, logger)
234
351
 
235
352
  filePathToModule.set(filePath, sourceFile)
236
353
 
@@ -247,10 +364,8 @@ export default function makePlugin({
247
364
  const relativeHtmlFilePath = relative(sourceDirectory, htmlFilePath)
248
365
  let html = ''
249
366
 
250
- info(`Building html module for ${relativeHtmlFilePath}...`)
251
-
252
367
  // If there's a dev server, use it to transform the HTML for development
253
- if (devServer) {
368
+ if (!isStaticBuild && devServer) {
254
369
  html = (await readFile(htmlFilePath, 'utf-8')).toString()
255
370
  html = await devServer.transformIndexHtml(
256
371
  getRelativePath(sourceDirectory, htmlFilePath),
@@ -271,9 +386,21 @@ export default function makePlugin({
271
386
  serverOutputDirectory: resolvedServerOutputDirectory,
272
387
  clientOutputDirectory: resolvedClientOutputDirectory,
273
388
  devServer,
389
+ isStaticBuild,
274
390
  })
275
391
 
276
- info(`Built html module for ${relativeHtmlFilePath}.`)
392
+ addManifestEntry(
393
+ {
394
+ type: 'html',
395
+ filePath: relativeHtmlFilePath,
396
+ },
397
+ relative(sourceDirectory, importer),
398
+ id,
399
+ )
400
+
401
+ addDependents(sourceFile)
402
+
403
+ info(`Built html module for ${relativeHtmlFilePath}.`, logger)
277
404
 
278
405
  const filePath = sourceFile.getFilePath()
279
406
 
@@ -291,10 +418,7 @@ export default function makePlugin({
291
418
  const moduleName = parseModulesFromId(id, importer)
292
419
  const moduleDirectory = resolve(importDirectory, moduleName)
293
420
  const relativeDirectory = relative(sourceDirectory, moduleDirectory)
294
- const moduleType = id.startsWith(EXPRESS_VIRTUAL_ENTRYPOINT_PREFIX) ? 'express' : 'API'
295
-
296
- info(`Building ${moduleType} module for ${relativeDirectory}...`)
297
-
421
+ const moduleType = id.startsWith(EXPRESS_VIRTUAL_ENTRYPOINT_PREFIX) ? 'express' : 'api'
298
422
  const directory = await readDirectory(moduleDirectory)
299
423
  const moduleTree = readApiModules(project, directory)
300
424
  const filePath = `${importDirectory}/${basename(
@@ -309,7 +433,18 @@ export default function makePlugin({
309
433
  id.startsWith(EXPRESS_VIRTUAL_ENTRYPOINT_PREFIX),
310
434
  )
311
435
 
312
- info(`Built ${moduleType} module for ${relativeDirectory}.`)
436
+ addManifestEntry(
437
+ {
438
+ type: moduleType,
439
+ ...apiModuleTreeToJson(sourceDirectory, moduleTree),
440
+ },
441
+ relative(sourceDirectory, importer),
442
+ id,
443
+ )
444
+
445
+ addDependents(sourceFile)
446
+
447
+ info(`Built ${moduleType} module for ${relativeDirectory}.`, logger)
313
448
 
314
449
  filePathToModule.set(filePath, sourceFile)
315
450
 
@@ -320,17 +455,32 @@ export default function makePlugin({
320
455
  return filePath
321
456
  }
322
457
 
323
- const virtualModulePlugin = {
458
+ const addDependents = (sourceFile: SourceFile) => {
459
+ const importer = sourceFile.getFilePath()
460
+ const imports = sourceFile
461
+ .getLiteralsReferencingOtherSourceFiles()
462
+ .map((i) => i.getLiteralValue())
463
+
464
+ for (const i of imports) {
465
+ const dependents = dependentsMap.get(i) ?? new Set()
466
+
467
+ dependents.add(importer)
468
+ dependentsMap.set(i, dependents)
469
+ }
470
+ }
471
+
472
+ const virtualModulePlugin: TypedVitePlugin = {
324
473
  name: PLUGIN_NAME,
474
+ resolvedOptions,
325
475
  config(config: UserConfig, env: ConfigEnv) {
476
+ isSsr = env.ssrBuild ?? false
477
+
326
478
  // Configure Build steps when running with vavite
327
479
  if (env.mode === 'multibuild') {
328
480
  const clientBuild: UserConfig['build'] = {
329
481
  outDir: resolvedClientOutputDirectory,
330
482
  rollupOptions: {
331
- input: buildClientInput(
332
- findHtmlFiles(sourceDirectory, htmlFileGlobs).map((p) => resolve(sourceDirectory, p)),
333
- ),
483
+ input: buildClientInput(resolvedOptions.htmlFiles),
334
484
  },
335
485
  }
336
486
 
@@ -338,7 +488,9 @@ export default function makePlugin({
338
488
  ssr: true,
339
489
  outDir: resolvedServerOutputDirectory,
340
490
  rollupOptions: {
341
- input: resolvedServerFilePath,
491
+ input: {
492
+ index: resolvedServerFilePath,
493
+ },
342
494
  },
343
495
  }
344
496
 
@@ -360,6 +512,35 @@ export default function makePlugin({
360
512
 
361
513
  return
362
514
  }
515
+
516
+ if (serverExists) {
517
+ config.plugins?.push(
518
+ vavite({
519
+ serverEntry: resolvedServerFilePath,
520
+ serveClientAssetsInDev: true,
521
+ }),
522
+ )
523
+ } else {
524
+ // TODO: Add vavite plugins without reloader
525
+ }
526
+ },
527
+
528
+ configResolved(resolvedConfig) {
529
+ logger = resolvedConfig.logger
530
+
531
+ const input = resolvedConfig.build.rollupOptions.input
532
+
533
+ if (!input) return
534
+
535
+ if (typeof input === 'string') {
536
+ manifest.entryFiles.push(parseEntryFile(sourceDirectory, input))
537
+ } else if (Array.isArray(input)) {
538
+ manifest.entryFiles.push(...input.map((i) => parseEntryFile(sourceDirectory, i)))
539
+ } else {
540
+ manifest.entryFiles.push(
541
+ ...Object.values(input).map((i) => parseEntryFile(sourceDirectory, i)),
542
+ )
543
+ }
363
544
  },
364
545
 
365
546
  configureServer(server) {
@@ -380,7 +561,7 @@ export default function makePlugin({
380
561
  handleFileChange(path, event)
381
562
  },
382
563
 
383
- closeBundle() {
564
+ async closeBundle() {
384
565
  if (project) {
385
566
  const diagnostics = project.getPreEmitDiagnostics()
386
567
 
@@ -388,6 +569,16 @@ export default function makePlugin({
388
569
  this.error(project.formatDiagnosticsWithColorAndContext(diagnostics))
389
570
  }
390
571
  }
572
+
573
+ if (Object.keys(manifest).length > 0) {
574
+ writeFileSync(
575
+ resolve(
576
+ isSsr ? resolvedServerOutputDirectory : resolvedClientOutputDirectory,
577
+ 'typed-manifest.json',
578
+ ),
579
+ JSON.stringify(manifest, null, 2) + EOL,
580
+ )
581
+ }
391
582
  },
392
583
 
393
584
  async resolveId(id: string, importer?: string) {
@@ -401,13 +592,17 @@ export default function makePlugin({
401
592
  ) {
402
593
  setupProject()
403
594
 
404
- return VIRTUAL_ID_PREFIX + (await buildRenderModule(importer, id))
595
+ const virtualId = VIRTUAL_ID_PREFIX + (await buildRuntimeModule(importer, id))
596
+
597
+ return virtualId
405
598
  }
406
599
 
407
600
  if (id.startsWith(HTML_VIRTUAL_ENTRYPOINT_PREFIX)) {
408
601
  setupProject()
409
602
 
410
- return VIRTUAL_ID_PREFIX + (await buildHtmlModule(importer, id))
603
+ const virtualId = VIRTUAL_ID_PREFIX + (await buildHtmlModule(importer, id))
604
+
605
+ return virtualId
411
606
  }
412
607
 
413
608
  if (
@@ -416,7 +611,13 @@ export default function makePlugin({
416
611
  ) {
417
612
  setupProject()
418
613
 
419
- return VIRTUAL_ID_PREFIX + (await buildApiModule(importer, id))
614
+ const virtualId = VIRTUAL_ID_PREFIX + (await buildApiModule(importer, id))
615
+
616
+ return virtualId
617
+ }
618
+
619
+ if (id === TYPED_CONFIG_IMPORT) {
620
+ return VIRTUAL_ID_PREFIX + TYPED_CONFIG_IMPORT
420
621
  }
421
622
 
422
623
  importer = importer.replace(VIRTUAL_ID_PREFIX, '')
@@ -434,24 +635,24 @@ export default function makePlugin({
434
635
  const sourceFile = filePathToModule.get(id) ?? project?.getSourceFile(id)
435
636
 
436
637
  if (sourceFile) {
437
- logDiagnostics(project, sourceFile, sourceDirectory, id)
638
+ logDiagnostics(project, sourceFile, sourceDirectory, id, logger)
438
639
 
439
- const text = sourceFile.getFullText()
440
- const output = ts.transpileModule(text, {
441
- fileName: id,
442
- compilerOptions: transpilerCompilerOptions(),
443
- transformers,
444
- })
640
+ return {
641
+ code: sourceFile.getFullText(),
642
+ }
643
+ }
445
644
 
645
+ if (id === TYPED_CONFIG_IMPORT) {
446
646
  return {
447
- code: output.outputText,
448
- map: output.sourceMapText,
647
+ code: Object.entries(resolvedOptions)
648
+ .map(([key, value]) => `export const ${key} = ${JSON.stringify(value)}`)
649
+ .join(EOL),
449
650
  }
450
651
  }
451
652
  },
452
653
 
453
654
  transform(text: string, id: string) {
454
- if (/.tsx?$/.test(id) || /.m?jsx?$/.test(id)) {
655
+ if (/.[c|m]?tsx?$/.test(id)) {
455
656
  const output = ts.transpileModule(text, {
456
657
  fileName: id,
457
658
  compilerOptions: transpilerCompilerOptions(),
@@ -464,7 +665,7 @@ export default function makePlugin({
464
665
  }
465
666
  }
466
667
  },
467
- } satisfies Plugin
668
+ }
468
669
 
469
670
  plugins.push(virtualModulePlugin)
470
671
 
@@ -476,21 +677,21 @@ function logDiagnostics(
476
677
  sourceFile: SourceFile,
477
678
  sourceDirectory: string,
478
679
  filePath: string,
680
+ logger: Logger | undefined,
479
681
  ) {
480
682
  const diagnostics = sourceFile.getPreEmitDiagnostics()
481
683
  const relativeFilePath = relative(sourceDirectory, filePath)
482
684
 
483
685
  if (diagnostics.length > 0) {
484
- info(sourceFile.getFullText())
485
- info(project.formatDiagnosticsWithColorAndContext(diagnostics))
486
- } else {
487
- info(`${relativeFilePath} module successfuly typed-checked.`)
686
+ info(`Type-checking errors found at ${relativeFilePath}`, logger)
687
+ info(`Source:` + EOL + sourceFile.getFullText(), logger)
688
+ info(project.formatDiagnosticsWithColorAndContext(diagnostics), logger)
488
689
  }
489
690
  }
490
691
 
491
692
  function findRelativeFile(importer: string, id: string) {
492
693
  const dir = dirname(importer)
493
- const tsPath = resolve(dir, id.replace(/.js(x)?$/, '.ts$1'))
694
+ const tsPath = resolve(dir, id.replace(/.([c|m])?js(x)?$/, '.$1ts$2'))
494
695
 
495
696
  if (existsSync(tsPath)) {
496
697
  return tsPath
@@ -530,15 +731,10 @@ function findHtmlFiles(directory: string, htmlFileGlobs?: readonly string[]): re
530
731
  }
531
732
 
532
733
  function buildClientInput(htmlFilePaths: readonly string[]) {
533
- const input: Record<string, string> = {}
534
-
535
- for (const htmlFilePath of htmlFilePaths) {
536
- const htmlFile = basename(htmlFilePath, '.html')
537
-
538
- input[htmlFile] = htmlFilePath
539
- }
540
-
541
- return input
734
+ return htmlFilePaths.reduce(
735
+ (acc, htmlFilePath) => ({ ...acc, [basename(htmlFilePath, '.html')]: htmlFilePath }),
736
+ {},
737
+ )
542
738
  }
543
739
 
544
740
  function getRelativePath(from: string, to: string) {
@@ -551,8 +747,76 @@ function getRelativePath(from: string, to: string) {
551
747
  return path
552
748
  }
553
749
 
554
- function info(message: string) {
555
- const date = new Date()
750
+ function info(message: string, logger: Logger | undefined) {
751
+ if (logger) {
752
+ logger.info(`[${PLUGIN_NAME}]: ${message}`)
753
+ } else {
754
+ console.info(`[${PLUGIN_NAME}]:`, `${message}`)
755
+ }
756
+ }
757
+
758
+ function parseEntryFile(sourceDirectory: string, filePath: string): EntryFile {
759
+ if (filePath.endsWith('.html')) {
760
+ return parseHtmlEntryFile(sourceDirectory, filePath)
761
+ }
762
+
763
+ return parseTsEntryFile(sourceDirectory, filePath)
764
+ }
765
+
766
+ function parseHtmlEntryFile(sourceDirectory: string, filePath: string): EntryFile {
767
+ const content = readFileSync(filePath, 'utf-8').toString()
768
+
769
+ return {
770
+ type: 'html',
771
+ filePath: relative(sourceDirectory, filePath),
772
+ imports: parseHtmlImports(sourceDirectory, content),
773
+ basePath: parseBasePath(content),
774
+ }
775
+ }
776
+
777
+ function parseHtmlImports(sourceDirectory: string, content: string) {
778
+ const imports: string[] = []
779
+
780
+ const matches = content.match(/<script[^>]*src="([^"]*)"[^>]*>/g)
781
+
782
+ if (matches) {
783
+ for (const match of matches) {
784
+ // If script is not type=module then skip
785
+ if (!match.includes('type="module"')) {
786
+ continue
787
+ }
556
788
 
557
- console.info(`[${PLUGIN_NAME}] ${date.toISOString()};`, `${message}`)
789
+ const src = match.match(/src="([^"]*)"/)?.[1]
790
+
791
+ if (src) {
792
+ const fullPath = join(sourceDirectory, src)
793
+ const relativePath = relative(sourceDirectory, fullPath)
794
+
795
+ imports.push(relativePath)
796
+ }
797
+ }
798
+ }
799
+
800
+ return imports
801
+ }
802
+
803
+ function parseBasePath(content: string) {
804
+ const baseTag = content.match(/<base[^>]*>/)?.[0]
805
+
806
+ if (baseTag) {
807
+ const href = baseTag.match(/href="([^"]*)"/)?.[1]
808
+
809
+ if (href) {
810
+ return href
811
+ }
812
+ }
813
+
814
+ return '/'
815
+ }
816
+
817
+ function parseTsEntryFile(sourceDirectory: string, filePath: string): EntryFile {
818
+ return {
819
+ type: 'ts',
820
+ filePath: relative(sourceDirectory, filePath),
821
+ }
558
822
  }