@tinloof/typed-svg-sprite 0.0.1 → 0.1.0

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.
@@ -33,13 +33,14 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.generateIconComponent = generateIconComponent;
36
+ exports.generateReactIconComponent = generateReactIconComponent;
37
+ exports.generateAstroIconComponent = generateAstroIconComponent;
37
38
  const fs = __importStar(require("fs"));
38
39
  const path = __importStar(require("path"));
39
40
  /**
40
41
  * Generate React Icon component file
41
42
  */
42
- function generateIconComponent(options) {
43
+ function generateReactIconComponent(options) {
43
44
  const { outputFile, typesFileRelativePath, verbose = true } = options;
44
45
  try {
45
46
  const projectRoot = process.cwd();
@@ -48,54 +49,127 @@ function generateIconComponent(options) {
48
49
  const normalizedImportPath = typesFileRelativePath
49
50
  .replace(/\\/g, "/")
50
51
  .replace(/\.tsx?$/, "");
51
- const content = `// Auto-generated by typed-svg-sprite
52
- // Do not edit this file manually
53
-
54
- import { IconHref } from "${normalizedImportPath}";
55
-
56
- export interface IconProps extends React.SVGProps<SVGSVGElement> {
57
- /** The icon href (import from generated/icons.ts) */
58
- href: IconHref;
59
- /** Size shorthand for width and height */
60
- size?: number | string;
61
- }
62
-
63
- export function Icon({
64
- href,
65
- size = 24,
66
- width,
67
- height,
68
- className = "",
69
- viewBox = "0 0 24 24",
70
- fill = "currentColor",
71
- ...props
72
- }: IconProps) {
73
- return (
74
- <svg
75
- className={className}
76
- width={width || size}
77
- height={height || size}
78
- viewBox={viewBox}
79
- fill={fill}
80
- aria-hidden="true"
81
- {...props}
82
- >
83
- <use href={href} />
84
- </svg>
85
- );
86
- }
52
+ const content = `// Auto-generated by typed-svg-sprite
53
+ // Do not edit this file manually
54
+
55
+ import type { IconHref } from "${normalizedImportPath}";
56
+
57
+ export interface IconProps extends React.SVGProps<SVGSVGElement> {
58
+ /** The icon href (import from generated/icons.ts) */
59
+ href: IconHref;
60
+ /** Size shorthand for width and height */
61
+ size?: number | string;
62
+ }
63
+
64
+ export function Icon({
65
+ href,
66
+ size = 24,
67
+ width,
68
+ height,
69
+ className = "",
70
+ viewBox = "0 0 24 24",
71
+ fill = "currentColor",
72
+ ...props
73
+ }: IconProps) {
74
+ return (
75
+ <svg
76
+ className={className}
77
+ width={width || size}
78
+ height={height || size}
79
+ viewBox={viewBox}
80
+ fill={fill}
81
+ aria-hidden="true"
82
+ {...props}
83
+ >
84
+ <use href={href} />
85
+ </svg>
86
+ );
87
+ }
88
+ `;
89
+ // Write component file
90
+ const outputDir = path.dirname(absoluteOutputFile);
91
+ fs.mkdirSync(outputDir, { recursive: true });
92
+ fs.writeFileSync(absoluteOutputFile, content, "utf8");
93
+ if (verbose) {
94
+ console.log(`[svg-sprite] ✅ Generated React Icon component → ${outputFile}`);
95
+ }
96
+ }
97
+ catch (error) {
98
+ if (verbose) {
99
+ console.error("[svg-sprite] Error generating React Icon component:", error);
100
+ }
101
+ throw error;
102
+ }
103
+ }
104
+ /**
105
+ * Generate Astro Icon component file
106
+ */
107
+ function generateAstroIconComponent(options) {
108
+ const { outputFile, typesFileRelativePath, verbose = true } = options;
109
+ try {
110
+ const projectRoot = process.cwd();
111
+ const absoluteOutputFile = path.resolve(projectRoot, outputFile);
112
+ // Normalize the import path (ensure it uses / separator)
113
+ const normalizedImportPath = typesFileRelativePath
114
+ .replace(/\\/g, "/")
115
+ .replace(/\.tsx?$/, "");
116
+ const content = `---
117
+ // Auto-generated by typed-svg-sprite
118
+ // Do not edit this file manually
119
+
120
+ import type { IconHref } from "${normalizedImportPath}";
121
+
122
+ export interface Props {
123
+ /** The icon href (import from generated/icons.ts) */
124
+ href: IconHref;
125
+ /** Size shorthand for width and height */
126
+ size?: number | string;
127
+ /** CSS class */
128
+ class?: string;
129
+ /** viewBox attribute */
130
+ viewBox?: string;
131
+ /** fill attribute */
132
+ fill?: string;
133
+ /** Additional HTML attributes */
134
+ [key: string]: any;
135
+ }
136
+
137
+ const {
138
+ href,
139
+ size = 24,
140
+ class: className = "",
141
+ viewBox = "0 0 24 24",
142
+ fill = "currentColor",
143
+ ...props
144
+ } = Astro.props;
145
+
146
+ const width = props.width || size;
147
+ const height = props.height || size;
148
+ ---
149
+
150
+ <svg
151
+ class={className}
152
+ width={width}
153
+ height={height}
154
+ viewBox={viewBox}
155
+ fill={fill}
156
+ aria-hidden="true"
157
+ {...props}
158
+ >
159
+ <use href={href} />
160
+ </svg>
87
161
  `;
88
162
  // Write component file
89
163
  const outputDir = path.dirname(absoluteOutputFile);
90
164
  fs.mkdirSync(outputDir, { recursive: true });
91
165
  fs.writeFileSync(absoluteOutputFile, content, "utf8");
92
166
  if (verbose) {
93
- console.log(`[svg-sprite] ✅ Generated Icon component → ${outputFile}`);
167
+ console.log(`[svg-sprite] ✅ Generated Astro Icon component → ${outputFile}`);
94
168
  }
95
169
  }
96
170
  catch (error) {
97
171
  if (verbose) {
98
- console.error("[svg-sprite] Error generating Icon component:", error);
172
+ console.error("[svg-sprite] Error generating Astro Icon component:", error);
99
173
  }
100
174
  throw error;
101
175
  }
package/dist/core.js CHANGED
@@ -143,7 +143,7 @@ function generateSpriteSvg(symbols, minify = true) {
143
143
  if (symbols.length === 0) {
144
144
  return minify
145
145
  ? '<svg xmlns="http://www.w3.org/2000/svg" style="display:none"></svg>'
146
- : `<svg xmlns="http://www.w3.org/2000/svg" class="svg-sprite" style="display: none;">
146
+ : `<svg xmlns="http://www.w3.org/2000/svg" class="svg-sprite" style="display: none;">
147
147
  </svg>`;
148
148
  }
149
149
  const symbolElements = symbols
@@ -158,8 +158,8 @@ function generateSpriteSvg(symbols, minify = true) {
158
158
  if (minify) {
159
159
  return `<svg xmlns="http://www.w3.org/2000/svg" style="display:none">${symbolElements}</svg>`;
160
160
  }
161
- return `<svg xmlns="http://www.w3.org/2000/svg" class="svg-sprite" style="display: none;">
162
- ${symbolElements}
161
+ return `<svg xmlns="http://www.w3.org/2000/svg" class="svg-sprite" style="display: none;">
162
+ ${symbolElements}
163
163
  </svg>`;
164
164
  }
165
165
  /**
package/dist/next.d.ts CHANGED
@@ -36,9 +36,9 @@ interface SpriteLoaderOptions {
36
36
  */
37
37
  generateIconComponent?: boolean;
38
38
  /**
39
- * Output path for the Icon component file.
39
+ * Output path for the Icon component file (without extension).
40
40
  * Relative to project root.
41
- * @default "generated/Icon.tsx"
41
+ * @default "generated/Icon"
42
42
  */
43
43
  iconComponentOutputFile?: string;
44
44
  }
package/dist/next.js CHANGED
@@ -1,119 +1,9 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  Object.defineProperty(exports, "__esModule", { value: true });
36
3
  exports.withSpriteLoader = withSpriteLoader;
37
- const fs = __importStar(require("fs"));
38
- const path = __importStar(require("path"));
39
- const core_js_1 = require("./core.js");
40
- const types_js_1 = require("./types.js");
41
- const components_js_1 = require("./components.js");
42
- // Track if we've already started watching
43
- let watcherInitialized = false;
44
- function generateSpriteAndTypes(inputDir, outputFile, spriteUrl, spriteFilename, typesOutputFile, generateIcon, iconComponentOutputFile) {
45
- // Generate sprite and get symbols
46
- const symbols = (0, core_js_1.generateSprite)({
47
- inputDir,
48
- outputFile,
49
- verbose: true,
50
- minify: true,
51
- optimize: true,
52
- });
53
- // Generate TypeScript types file if specified
54
- if (typesOutputFile && symbols.length > 0) {
55
- (0, types_js_1.generateTypesFile)({
56
- symbols,
57
- spriteUrl,
58
- spriteFilename,
59
- outputFile: typesOutputFile,
60
- verbose: false,
61
- });
62
- // Generate Icon component if enabled
63
- if (generateIcon && iconComponentOutputFile) {
64
- // Calculate relative path from component to types file
65
- const componentDir = path.dirname(path.resolve(process.cwd(), iconComponentOutputFile));
66
- const typesFile = path.resolve(process.cwd(), typesOutputFile);
67
- const typesDir = path.dirname(typesFile);
68
- const typesFilename = path.basename(typesFile, path.extname(typesFile));
69
- // Get relative path from component dir to types dir
70
- const relativePath = path
71
- .relative(componentDir, typesDir)
72
- .replace(/\\/g, "/");
73
- // Construct the import path
74
- // If same directory, use ./filename
75
- // If parent/child relationship, ensure proper path format
76
- let importPath;
77
- if (relativePath === "") {
78
- importPath = `./${typesFilename}`;
79
- }
80
- else if (relativePath.startsWith("..")) {
81
- // Parent directory - ensure proper path
82
- importPath = `${relativePath}/${typesFilename}`.replace(/\/+/g, "/");
83
- }
84
- else {
85
- // Child directory - ensure it starts with ./
86
- const normalizedPath = relativePath.startsWith("./")
87
- ? relativePath
88
- : `./${relativePath}`;
89
- importPath = `${normalizedPath}/${typesFilename}`.replace(/\/+/g, "/");
90
- }
91
- (0, components_js_1.generateIconComponent)({
92
- outputFile: iconComponentOutputFile,
93
- typesFileRelativePath: importPath,
94
- verbose: false,
95
- });
96
- }
97
- }
98
- }
99
- function startWatcher(inputDir, outputFile, spriteUrl, spriteFilename, typesOutputFile, generateIcon, iconComponentOutputFile) {
100
- if (watcherInitialized) {
101
- return;
102
- }
103
- const projectRoot = process.cwd();
104
- const absoluteInputDir = path.resolve(projectRoot, inputDir);
105
- if (!fs.existsSync(absoluteInputDir)) {
106
- return;
107
- }
108
- watcherInitialized = true;
109
- console.log(`[svg-sprite] 👀 Watching ${inputDir} for changes...`);
110
- fs.watch(absoluteInputDir, { recursive: true }, (eventType, filename) => {
111
- if (filename?.endsWith(".svg")) {
112
- console.log(`[svg-sprite] Change detected: ${filename}`);
113
- generateSpriteAndTypes(inputDir, outputFile, spriteUrl, spriteFilename, typesOutputFile, generateIcon, iconComponentOutputFile);
114
- }
115
- });
116
- }
4
+ const shared_js_1 = require("./shared.js");
5
+ // Prevent double generation when Next.js loads config multiple times
6
+ let hasGenerated = false;
117
7
  /**
118
8
  * Generates SVG sprite and TypeScript types for Next.js projects
119
9
  *
@@ -185,16 +75,17 @@ function withSpriteLoader(nextConfig, options) {
185
75
  const spriteUrl = options?.url ?? "/";
186
76
  const spriteFilename = options?.filename ?? "sprite.svg";
187
77
  const typesOutputFile = options?.typesOutputFile ?? "generated/icons.ts";
188
- const generateIcon = options?.generateIconComponent !== false
189
- ? options?.generateIconComponent ?? true
190
- : false;
191
- const iconComponentOutputFile = options?.iconComponentOutputFile ?? "generated/Icon.tsx";
192
- // Generate sprite and types on startup
193
- generateSpriteAndTypes(inputDir, outputFile, spriteUrl, spriteFilename, typesOutputFile, generateIcon, generateIcon ? iconComponentOutputFile : undefined);
194
- // Start watcher in dev mode
195
- const isDev = process.env.NODE_ENV === "development";
196
- if (isDev) {
197
- startWatcher(inputDir, outputFile, spriteUrl, spriteFilename, typesOutputFile, generateIcon, generateIcon ? iconComponentOutputFile : undefined);
78
+ const generateIcon = options?.generateIconComponent === false ? false : { react: true };
79
+ const iconComponentOutputFile = options?.iconComponentOutputFile ?? "generated/Icon";
80
+ // Generate sprite and types on startup (only once)
81
+ if (!hasGenerated) {
82
+ hasGenerated = true;
83
+ (0, shared_js_1.generateSpriteAndTypes)(inputDir, outputFile, spriteUrl, spriteFilename, typesOutputFile, generateIcon, iconComponentOutputFile);
84
+ // Start watcher in dev mode
85
+ const isDev = process.env.NODE_ENV === "development";
86
+ if (isDev) {
87
+ (0, shared_js_1.startWatcher)(inputDir, outputFile, spriteUrl, spriteFilename, typesOutputFile, generateIcon, iconComponentOutputFile);
88
+ }
198
89
  }
199
90
  // Return config without loader modifications
200
91
  // Users should import from the generated types file instead
@@ -0,0 +1,6 @@
1
+ export type GenerateIconOption = boolean | {
2
+ astro?: boolean;
3
+ react?: boolean;
4
+ };
5
+ export declare function generateSpriteAndTypes(inputDir: string, outputFile: string, spriteUrl: string, spriteFilename: string, typesOutputFile?: string, generateIcon?: GenerateIconOption, iconComponentOutputFile?: string): void;
6
+ export declare function startWatcher(inputDir: string, outputFile: string, spriteUrl: string, spriteFilename: string, typesOutputFile?: string, generateIcon?: GenerateIconOption, iconComponentOutputFile?: string): void;
package/dist/shared.js ADDED
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.generateSpriteAndTypes = generateSpriteAndTypes;
37
+ exports.startWatcher = startWatcher;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const core_js_1 = require("./core.js");
41
+ const types_js_1 = require("./types.js");
42
+ const components_js_1 = require("./components.js");
43
+ // Track if we've already started watching
44
+ let watcherInitialized = false;
45
+ function getTypesImportPath(componentOutputFile, typesOutputFile) {
46
+ const componentDir = path.dirname(path.resolve(process.cwd(), componentOutputFile));
47
+ const typesFile = path.resolve(process.cwd(), typesOutputFile);
48
+ const typesDir = path.dirname(typesFile);
49
+ const typesFilename = path.basename(typesFile, path.extname(typesFile));
50
+ const relativePath = path
51
+ .relative(componentDir, typesDir)
52
+ .replace(/\\/g, "/");
53
+ if (relativePath === "") {
54
+ return `./${typesFilename}`;
55
+ }
56
+ else if (relativePath.startsWith("..")) {
57
+ return `${relativePath}/${typesFilename}`.replace(/\/+/g, "/");
58
+ }
59
+ else {
60
+ const normalizedPath = relativePath.startsWith("./")
61
+ ? relativePath
62
+ : `./${relativePath}`;
63
+ return `${normalizedPath}/${typesFilename}`.replace(/\/+/g, "/");
64
+ }
65
+ }
66
+ function generateSpriteAndTypes(inputDir, outputFile, spriteUrl, spriteFilename, typesOutputFile, generateIcon, iconComponentOutputFile) {
67
+ // Generate sprite and get symbols
68
+ const symbols = (0, core_js_1.generateSprite)({
69
+ inputDir,
70
+ outputFile,
71
+ verbose: true,
72
+ minify: true,
73
+ optimize: true,
74
+ });
75
+ // Generate TypeScript types file if specified
76
+ if (typesOutputFile && symbols.length > 0) {
77
+ (0, types_js_1.generateTypesFile)({
78
+ symbols,
79
+ spriteUrl,
80
+ spriteFilename,
81
+ outputFile: typesOutputFile,
82
+ verbose: false,
83
+ });
84
+ // Determine which components to generate
85
+ const shouldGenerateAstro = generateIcon === true ||
86
+ (typeof generateIcon === "object" && generateIcon.astro === true);
87
+ const shouldGenerateReact = generateIcon === true ||
88
+ (typeof generateIcon === "object" && generateIcon.react === true);
89
+ if (iconComponentOutputFile && (shouldGenerateAstro || shouldGenerateReact)) {
90
+ const baseOutputFile = iconComponentOutputFile.replace(/\.(tsx|astro)$/, "");
91
+ if (shouldGenerateAstro) {
92
+ const astroOutputFile = `${baseOutputFile}.astro`;
93
+ const importPath = getTypesImportPath(astroOutputFile, typesOutputFile);
94
+ (0, components_js_1.generateAstroIconComponent)({
95
+ outputFile: astroOutputFile,
96
+ typesFileRelativePath: importPath,
97
+ verbose: false,
98
+ });
99
+ }
100
+ if (shouldGenerateReact) {
101
+ const reactOutputFile = `${baseOutputFile}.tsx`;
102
+ const importPath = getTypesImportPath(reactOutputFile, typesOutputFile);
103
+ (0, components_js_1.generateReactIconComponent)({
104
+ outputFile: reactOutputFile,
105
+ typesFileRelativePath: importPath,
106
+ verbose: false,
107
+ });
108
+ }
109
+ }
110
+ }
111
+ }
112
+ function startWatcher(inputDir, outputFile, spriteUrl, spriteFilename, typesOutputFile, generateIcon, iconComponentOutputFile) {
113
+ if (watcherInitialized) {
114
+ return;
115
+ }
116
+ const projectRoot = process.cwd();
117
+ const absoluteInputDir = path.resolve(projectRoot, inputDir);
118
+ if (!fs.existsSync(absoluteInputDir)) {
119
+ return;
120
+ }
121
+ watcherInitialized = true;
122
+ console.log(`[svg-sprite] 👀 Watching ${inputDir} for changes...`);
123
+ fs.watch(absoluteInputDir, { recursive: true }, (eventType, filename) => {
124
+ if (filename?.endsWith(".svg")) {
125
+ console.log(`[svg-sprite] Change detected: ${filename}`);
126
+ generateSpriteAndTypes(inputDir, outputFile, spriteUrl, spriteFilename, typesOutputFile, generateIcon, iconComponentOutputFile);
127
+ }
128
+ });
129
+ }
package/dist/types.js CHANGED
@@ -62,41 +62,41 @@ function generateTypesFile(options) {
62
62
  return `export const ${constantName}: IconHref = "${spriteUrlWithFilename}#${s.id}";`;
63
63
  })
64
64
  .join("\n");
65
- const content = `// Auto-generated by typed-svg-sprite
66
- // Do not edit this file manually
67
-
68
- /**
69
- * Available icon IDs in the sprite
70
- */
71
- export enum IconId {
72
- ${enumEntries}
73
- }
74
-
75
- /**
76
- * Type-safe icon href (sprite URL + fragment identifier)
77
- */
78
- export type IconHref = \`${spriteUrlWithFilename}#\${IconId}\`;
79
-
80
- /**
81
- * Get the full sprite URL for an icon ID
82
- */
83
- export function getIconHref(iconId: IconId): IconHref {
84
- return \`${spriteUrlWithFilename}#\${iconId}\` as IconHref;
85
- }
86
-
87
- /**
88
- * Pre-built icon references
89
- */
90
- ${iconExports}
91
-
92
- /**
93
- * All available icons as an array
94
- */
95
- export const allIcons: IconId[] = [
65
+ const content = `// Auto-generated by typed-svg-sprite
66
+ // Do not edit this file manually
67
+
68
+ /**
69
+ * Available icon IDs in the sprite
70
+ */
71
+ export enum IconId {
72
+ ${enumEntries}
73
+ }
74
+
75
+ /**
76
+ * Type-safe icon href (sprite URL + fragment identifier)
77
+ */
78
+ export type IconHref = \`${spriteUrlWithFilename}#\${IconId}\`;
79
+
80
+ /**
81
+ * Get the full sprite URL for an icon ID
82
+ */
83
+ export function getIconHref(iconId: IconId): IconHref {
84
+ return \`${spriteUrlWithFilename}#\${iconId}\` as IconHref;
85
+ }
86
+
87
+ /**
88
+ * Pre-built icon references
89
+ */
90
+ ${iconExports}
91
+
92
+ /**
93
+ * All available icons as an array
94
+ */
95
+ export const allIcons: IconId[] = [
96
96
  ${symbols
97
97
  .map((s) => ` IconId.${s.originalId.replace(/-/g, "_").toUpperCase()},`)
98
- .join("\n")}
99
- ];
98
+ .join("\n")}
99
+ ];
100
100
  `;
101
101
  // Write types file
102
102
  const outputDir = path.dirname(absoluteOutputFile);