@typed/vite-plugin 0.0.20 → 0.0.22

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,12 @@ 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
- : []),
251
+ serverExists &&
252
+ !isStaticBuild &&
253
+ vavite({
254
+ serverEntry: resolvedServerFilePath,
255
+ serveClientAssetsInDev: true,
256
+ }),
144
257
  ]
145
258
 
146
259
  const setupProject = () => {
@@ -148,9 +261,9 @@ export default function makePlugin({
148
261
  return
149
262
  }
150
263
 
151
- info(`Setting up TypeScript project...`)
264
+ info(`Setting up TypeScript project...`, logger)
152
265
  project = setupTsProject(tsConfigFilePath)
153
- info(`Setup TypeScript project.`)
266
+ info(`Setup TypeScript project.`, logger)
154
267
 
155
268
  // Setup transformer for virtual modules.
156
269
  transformers = {
@@ -169,7 +282,9 @@ export default function makePlugin({
169
282
 
170
283
  return {
171
284
  ...project.getCompilerOptions(),
172
- allowJs: true,
285
+ inlineSourceMap: false,
286
+ inlineSources: saveGeneratedModules,
287
+ sourceMap: true,
173
288
  }
174
289
  }
175
290
 
@@ -196,7 +311,7 @@ export default function makePlugin({
196
311
  const mod = devServer.moduleGraph.getModuleById(dependent)
197
312
 
198
313
  if (mod) {
199
- info(`reloading ${dependent}`)
314
+ info(`reloading ${dependent}`, logger)
200
315
 
201
316
  await devServer.reloadModule(mod)
202
317
  }
@@ -213,24 +328,32 @@ export default function makePlugin({
213
328
  }
214
329
  }
215
330
 
216
- const buildRenderModule = async (importer: string, id: string) => {
331
+ const buildRuntimeModule = async (importer: string, id: string) => {
217
332
  const moduleDirectory = resolve(dirname(importer), parseModulesFromId(id, importer))
218
333
  const relativeDirectory = relative(sourceDirectory, moduleDirectory)
219
334
  const isBrowser = id.startsWith(BROWSER_VIRTUAL_ENTRYPOINT_PREFIX)
220
335
  const moduleType = isBrowser ? 'browser' : 'runtime'
221
336
  const filePath = `${moduleDirectory}.${moduleType}.__generated__.ts`
222
-
223
- info(`Building ${moduleType} module for ${relativeDirectory}...`)
224
-
225
337
  const directory = await readDirectory(moduleDirectory)
226
338
  const moduleTree = readModules(project, directory)
227
339
 
340
+ addManifestEntry(
341
+ {
342
+ type: moduleType,
343
+ ...moduleTreeToJson(sourceDirectory, moduleTree),
344
+ },
345
+ relative(sourceDirectory, importer),
346
+ id,
347
+ )
348
+
228
349
  // Setup the TypeScript project if it hasn't been already
229
350
  setupProject()
230
351
 
231
352
  const sourceFile = makeRuntimeModule(project, moduleTree, importer, filePath, isBrowser)
232
353
 
233
- info(`Built ${moduleType} module for ${relativeDirectory}.`)
354
+ addDependents(sourceFile)
355
+
356
+ info(`Built ${moduleType} module for ${relativeDirectory}.`, logger)
234
357
 
235
358
  filePathToModule.set(filePath, sourceFile)
236
359
 
@@ -247,10 +370,8 @@ export default function makePlugin({
247
370
  const relativeHtmlFilePath = relative(sourceDirectory, htmlFilePath)
248
371
  let html = ''
249
372
 
250
- info(`Building html module for ${relativeHtmlFilePath}...`)
251
-
252
373
  // If there's a dev server, use it to transform the HTML for development
253
- if (devServer) {
374
+ if (!isStaticBuild && devServer) {
254
375
  html = (await readFile(htmlFilePath, 'utf-8')).toString()
255
376
  html = await devServer.transformIndexHtml(
256
377
  getRelativePath(sourceDirectory, htmlFilePath),
@@ -271,9 +392,21 @@ export default function makePlugin({
271
392
  serverOutputDirectory: resolvedServerOutputDirectory,
272
393
  clientOutputDirectory: resolvedClientOutputDirectory,
273
394
  devServer,
395
+ isStaticBuild,
274
396
  })
275
397
 
276
- info(`Built html module for ${relativeHtmlFilePath}.`)
398
+ addManifestEntry(
399
+ {
400
+ type: 'html',
401
+ filePath: relativeHtmlFilePath,
402
+ },
403
+ relative(sourceDirectory, importer),
404
+ id,
405
+ )
406
+
407
+ addDependents(sourceFile)
408
+
409
+ info(`Built html module for ${relativeHtmlFilePath}.`, logger)
277
410
 
278
411
  const filePath = sourceFile.getFilePath()
279
412
 
@@ -291,10 +424,7 @@ export default function makePlugin({
291
424
  const moduleName = parseModulesFromId(id, importer)
292
425
  const moduleDirectory = resolve(importDirectory, moduleName)
293
426
  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
-
427
+ const moduleType = id.startsWith(EXPRESS_VIRTUAL_ENTRYPOINT_PREFIX) ? 'express' : 'api'
298
428
  const directory = await readDirectory(moduleDirectory)
299
429
  const moduleTree = readApiModules(project, directory)
300
430
  const filePath = `${importDirectory}/${basename(
@@ -309,7 +439,18 @@ export default function makePlugin({
309
439
  id.startsWith(EXPRESS_VIRTUAL_ENTRYPOINT_PREFIX),
310
440
  )
311
441
 
312
- info(`Built ${moduleType} module for ${relativeDirectory}.`)
442
+ addManifestEntry(
443
+ {
444
+ type: moduleType,
445
+ ...apiModuleTreeToJson(sourceDirectory, moduleTree),
446
+ },
447
+ relative(sourceDirectory, importer),
448
+ id,
449
+ )
450
+
451
+ addDependents(sourceFile)
452
+
453
+ info(`Built ${moduleType} module for ${relativeDirectory}.`, logger)
313
454
 
314
455
  filePathToModule.set(filePath, sourceFile)
315
456
 
@@ -320,17 +461,32 @@ export default function makePlugin({
320
461
  return filePath
321
462
  }
322
463
 
323
- const virtualModulePlugin = {
464
+ const addDependents = (sourceFile: SourceFile) => {
465
+ const importer = sourceFile.getFilePath()
466
+ const imports = sourceFile
467
+ .getLiteralsReferencingOtherSourceFiles()
468
+ .map((i) => i.getLiteralValue())
469
+
470
+ for (const i of imports) {
471
+ const dependents = dependentsMap.get(i) ?? new Set()
472
+
473
+ dependents.add(importer)
474
+ dependentsMap.set(i, dependents)
475
+ }
476
+ }
477
+
478
+ const virtualModulePlugin: TypedVitePlugin = {
324
479
  name: PLUGIN_NAME,
480
+ resolvedOptions,
325
481
  config(config: UserConfig, env: ConfigEnv) {
482
+ isSsr = env.ssrBuild ?? false
483
+
326
484
  // Configure Build steps when running with vavite
327
485
  if (env.mode === 'multibuild') {
328
486
  const clientBuild: UserConfig['build'] = {
329
487
  outDir: resolvedClientOutputDirectory,
330
488
  rollupOptions: {
331
- input: buildClientInput(
332
- findHtmlFiles(sourceDirectory, htmlFileGlobs).map((p) => resolve(sourceDirectory, p)),
333
- ),
489
+ input: buildClientInput(resolvedOptions.htmlFiles),
334
490
  },
335
491
  }
336
492
 
@@ -338,7 +494,9 @@ export default function makePlugin({
338
494
  ssr: true,
339
495
  outDir: resolvedServerOutputDirectory,
340
496
  rollupOptions: {
341
- input: resolvedServerFilePath,
497
+ input: {
498
+ index: resolvedServerFilePath,
499
+ },
342
500
  },
343
501
  }
344
502
 
@@ -362,6 +520,24 @@ export default function makePlugin({
362
520
  }
363
521
  },
364
522
 
523
+ configResolved(resolvedConfig) {
524
+ logger = resolvedConfig.logger
525
+
526
+ const input = resolvedConfig.build.rollupOptions.input
527
+
528
+ if (!input) return
529
+
530
+ if (typeof input === 'string') {
531
+ manifest.entryFiles.push(parseEntryFile(sourceDirectory, input))
532
+ } else if (Array.isArray(input)) {
533
+ manifest.entryFiles.push(...input.map((i) => parseEntryFile(sourceDirectory, i)))
534
+ } else {
535
+ manifest.entryFiles.push(
536
+ ...Object.values(input).map((i) => parseEntryFile(sourceDirectory, i)),
537
+ )
538
+ }
539
+ },
540
+
365
541
  configureServer(server) {
366
542
  devServer = server
367
543
 
@@ -380,7 +556,7 @@ export default function makePlugin({
380
556
  handleFileChange(path, event)
381
557
  },
382
558
 
383
- closeBundle() {
559
+ async closeBundle() {
384
560
  if (project) {
385
561
  const diagnostics = project.getPreEmitDiagnostics()
386
562
 
@@ -388,6 +564,16 @@ export default function makePlugin({
388
564
  this.error(project.formatDiagnosticsWithColorAndContext(diagnostics))
389
565
  }
390
566
  }
567
+
568
+ if (Object.keys(manifest).length > 0) {
569
+ writeFileSync(
570
+ resolve(
571
+ isSsr ? resolvedServerOutputDirectory : resolvedClientOutputDirectory,
572
+ 'typed-manifest.json',
573
+ ),
574
+ JSON.stringify(manifest, null, 2) + EOL,
575
+ )
576
+ }
391
577
  },
392
578
 
393
579
  async resolveId(id: string, importer?: string) {
@@ -401,13 +587,17 @@ export default function makePlugin({
401
587
  ) {
402
588
  setupProject()
403
589
 
404
- return VIRTUAL_ID_PREFIX + (await buildRenderModule(importer, id))
590
+ const virtualId = VIRTUAL_ID_PREFIX + (await buildRuntimeModule(importer, id))
591
+
592
+ return virtualId
405
593
  }
406
594
 
407
595
  if (id.startsWith(HTML_VIRTUAL_ENTRYPOINT_PREFIX)) {
408
596
  setupProject()
409
597
 
410
- return VIRTUAL_ID_PREFIX + (await buildHtmlModule(importer, id))
598
+ const virtualId = VIRTUAL_ID_PREFIX + (await buildHtmlModule(importer, id))
599
+
600
+ return virtualId
411
601
  }
412
602
 
413
603
  if (
@@ -416,7 +606,13 @@ export default function makePlugin({
416
606
  ) {
417
607
  setupProject()
418
608
 
419
- return VIRTUAL_ID_PREFIX + (await buildApiModule(importer, id))
609
+ const virtualId = VIRTUAL_ID_PREFIX + (await buildApiModule(importer, id))
610
+
611
+ return virtualId
612
+ }
613
+
614
+ if (id === TYPED_CONFIG_IMPORT) {
615
+ return VIRTUAL_ID_PREFIX + TYPED_CONFIG_IMPORT
420
616
  }
421
617
 
422
618
  importer = importer.replace(VIRTUAL_ID_PREFIX, '')
@@ -434,24 +630,24 @@ export default function makePlugin({
434
630
  const sourceFile = filePathToModule.get(id) ?? project?.getSourceFile(id)
435
631
 
436
632
  if (sourceFile) {
437
- logDiagnostics(project, sourceFile, sourceDirectory, id)
633
+ logDiagnostics(project, sourceFile, sourceDirectory, id, logger)
438
634
 
439
- const text = sourceFile.getFullText()
440
- const output = ts.transpileModule(text, {
441
- fileName: id,
442
- compilerOptions: transpilerCompilerOptions(),
443
- transformers,
444
- })
635
+ return {
636
+ code: sourceFile.getFullText(),
637
+ }
638
+ }
445
639
 
640
+ if (id === TYPED_CONFIG_IMPORT) {
446
641
  return {
447
- code: output.outputText,
448
- map: output.sourceMapText,
642
+ code: Object.entries(resolvedOptions)
643
+ .map(([key, value]) => `export const ${key} = ${JSON.stringify(value)}`)
644
+ .join(EOL),
449
645
  }
450
646
  }
451
647
  },
452
648
 
453
649
  transform(text: string, id: string) {
454
- if (/.tsx?$/.test(id) || /.m?jsx?$/.test(id)) {
650
+ if (/.[c|m]?tsx?$/.test(id)) {
455
651
  const output = ts.transpileModule(text, {
456
652
  fileName: id,
457
653
  compilerOptions: transpilerCompilerOptions(),
@@ -464,7 +660,7 @@ export default function makePlugin({
464
660
  }
465
661
  }
466
662
  },
467
- } satisfies Plugin
663
+ }
468
664
 
469
665
  plugins.push(virtualModulePlugin)
470
666
 
@@ -476,21 +672,21 @@ function logDiagnostics(
476
672
  sourceFile: SourceFile,
477
673
  sourceDirectory: string,
478
674
  filePath: string,
675
+ logger: Logger | undefined,
479
676
  ) {
480
677
  const diagnostics = sourceFile.getPreEmitDiagnostics()
481
678
  const relativeFilePath = relative(sourceDirectory, filePath)
482
679
 
483
680
  if (diagnostics.length > 0) {
484
- info(sourceFile.getFullText())
485
- info(project.formatDiagnosticsWithColorAndContext(diagnostics))
486
- } else {
487
- info(`${relativeFilePath} module successfuly typed-checked.`)
681
+ info(`Type-checking errors found at ${relativeFilePath}`, logger)
682
+ info(`Source:` + EOL + sourceFile.getFullText(), logger)
683
+ info(project.formatDiagnosticsWithColorAndContext(diagnostics), logger)
488
684
  }
489
685
  }
490
686
 
491
687
  function findRelativeFile(importer: string, id: string) {
492
688
  const dir = dirname(importer)
493
- const tsPath = resolve(dir, id.replace(/.js(x)?$/, '.ts$1'))
689
+ const tsPath = resolve(dir, id.replace(/.([c|m])?js(x)?$/, '.$1ts$2'))
494
690
 
495
691
  if (existsSync(tsPath)) {
496
692
  return tsPath
@@ -530,15 +726,10 @@ function findHtmlFiles(directory: string, htmlFileGlobs?: readonly string[]): re
530
726
  }
531
727
 
532
728
  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
729
+ return htmlFilePaths.reduce(
730
+ (acc, htmlFilePath) => ({ ...acc, [basename(htmlFilePath, '.html')]: htmlFilePath }),
731
+ {},
732
+ )
542
733
  }
543
734
 
544
735
  function getRelativePath(from: string, to: string) {
@@ -551,8 +742,76 @@ function getRelativePath(from: string, to: string) {
551
742
  return path
552
743
  }
553
744
 
554
- function info(message: string) {
555
- const date = new Date()
745
+ function info(message: string, logger: Logger | undefined) {
746
+ if (logger) {
747
+ logger.info(`[${PLUGIN_NAME}]: ${message}`)
748
+ } else {
749
+ console.info(`[${PLUGIN_NAME}]:`, `${message}`)
750
+ }
751
+ }
752
+
753
+ function parseEntryFile(sourceDirectory: string, filePath: string): EntryFile {
754
+ if (filePath.endsWith('.html')) {
755
+ return parseHtmlEntryFile(sourceDirectory, filePath)
756
+ }
757
+
758
+ return parseTsEntryFile(sourceDirectory, filePath)
759
+ }
760
+
761
+ function parseHtmlEntryFile(sourceDirectory: string, filePath: string): EntryFile {
762
+ const content = readFileSync(filePath, 'utf-8').toString()
763
+
764
+ return {
765
+ type: 'html',
766
+ filePath: relative(sourceDirectory, filePath),
767
+ imports: parseHtmlImports(sourceDirectory, content),
768
+ basePath: parseBasePath(content),
769
+ }
770
+ }
771
+
772
+ function parseHtmlImports(sourceDirectory: string, content: string) {
773
+ const imports: string[] = []
774
+
775
+ const matches = content.match(/<script[^>]*src="([^"]*)"[^>]*>/g)
776
+
777
+ if (matches) {
778
+ for (const match of matches) {
779
+ // If script is not type=module then skip
780
+ if (!match.includes('type="module"')) {
781
+ continue
782
+ }
783
+
784
+ const src = match.match(/src="([^"]*)"/)?.[1]
556
785
 
557
- console.info(`[${PLUGIN_NAME}] ${date.toISOString()};`, `${message}`)
786
+ if (src) {
787
+ const fullPath = join(sourceDirectory, src)
788
+ const relativePath = relative(sourceDirectory, fullPath)
789
+
790
+ imports.push(relativePath)
791
+ }
792
+ }
793
+ }
794
+
795
+ return imports
796
+ }
797
+
798
+ function parseBasePath(content: string) {
799
+ const baseTag = content.match(/<base[^>]*>/)?.[0]
800
+
801
+ if (baseTag) {
802
+ const href = baseTag.match(/href="([^"]*)"/)?.[1]
803
+
804
+ if (href) {
805
+ return href
806
+ }
807
+ }
808
+
809
+ return '/'
810
+ }
811
+
812
+ function parseTsEntryFile(sourceDirectory: string, filePath: string): EntryFile {
813
+ return {
814
+ type: 'ts',
815
+ filePath: relative(sourceDirectory, filePath),
816
+ }
558
817
  }