<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Kosko Blog</title>
        <link>https://kosko.dev/blog</link>
        <description>Kosko Blog</description>
        <lastBuildDate>Thu, 28 Mar 2024 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Kosko 4.1: Beyond Type Safe]]></title>
            <link>https://kosko.dev/blog/2024/03/28/kosko-4.1</link>
            <guid>https://kosko.dev/blog/2024/03/28/kosko-4.1</guid>
            <pubDate>Thu, 28 Mar 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Today, I'm excited to announce the release of Kosko 4.1. This release is a significant milestone for Kosko.]]></description>
            <content:encoded><![CDATA[<p>Today, I'm excited to announce the release of Kosko 4.1. This release is a significant milestone for Kosko.</p>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="plugin-system">Plugin System<a href="https://kosko.dev/blog/2024/03/28/kosko-4.1#plugin-system" class="hash-link" aria-label="Direct link to Plugin System" title="Direct link to Plugin System">​</a></h2>
<p>The first major feature is the plugin system introduced in Kosko 4.0. It allows you to modify manifests, or run extra validations. Currently there are two official plugins, and we are going to introduce them in this post.</p>
<h3 class="anchor anchorWithStickyNavbar_zlB1" id="set-metadata">Set Metadata<a href="https://kosko.dev/blog/2024/03/28/kosko-4.1#set-metadata" class="hash-link" aria-label="Direct link to Set Metadata" title="Direct link to Set Metadata">​</a></h3>
<p>The first one is <code>@kosko/plugin-set-metadata</code>. This plugin can modify namespace, name, labels and annotations of manifests. For example, you can set a namespace for all manifests.</p>
<div class="language-toml codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-toml codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token punctuation" style="color:#8dc891">[</span><span class="token punctuation" style="color:#8dc891">[</span><span class="token table class-name" style="color:#FAC863">plugins</span><span class="token punctuation" style="color:#8dc891">]</span><span class="token punctuation" style="color:#8dc891">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token key property" style="color:#5a9bcf">name</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">=</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"@kosko/plugin-set-metadata"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token key property" style="color:#5a9bcf">config.namespace.value</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">=</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"dev"</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>You can check <a href="https://kosko.dev/docs/plugins/set-metadata">here</a> for more details.</p>
<h3 class="anchor anchorWithStickyNavbar_zlB1" id="lint">Lint<a href="https://kosko.dev/blog/2024/03/28/kosko-4.1#lint" class="hash-link" aria-label="Direct link to Lint" title="Direct link to Lint">​</a></h3>
<p>The other one is <code>@kosko/plugin-lint</code>. Prior to Kosko 4, Kosko only validates manifests against Kubernetes OpenAPI schema, which only contains data types, formats, required fields, etc. However, it's not enough to find all potential issues in manifests.</p>
<p><code>@kosko/plugin-lint</code> can run extra validations on manifests. For example:</p>
<ul>
<li>Check if a resource reference exists or not. (<a href="https://kosko.dev/docs/plugins/lint/rules">no-missing-* rules</a>)</li>
<li>Require security context for containers. (<a href="https://kosko.dev/docs/plugins/lint/rules/require-security-context">require-security-context</a>)</li>
<li>Check if service ports are unique. (<a href="https://kosko.dev/docs/plugins/lint/rules/unique-service-port-name">unique-service-port-name</a>)</li>
<li>Check if deployment selector matches with pod labels. (<a href="https://kosko.dev/docs/plugins/lint/rules/valid-pod-selector">valid-pod-selector</a>)</li>
</ul>
<p>You can enable the recommended rules by setting the following configuration.</p>
<div class="language-toml codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-toml codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token punctuation" style="color:#8dc891">[</span><span class="token punctuation" style="color:#8dc891">[</span><span class="token table class-name" style="color:#FAC863">plugins</span><span class="token punctuation" style="color:#8dc891">]</span><span class="token punctuation" style="color:#8dc891">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token key property" style="color:#5a9bcf">name</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">=</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"@kosko/plugin-lint"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token key property" style="color:#5a9bcf">config.extends</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">[</span><span class="token string" style="color:#8dc891">"@kosko/plugin-lint/presets/recommended"</span><span class="token punctuation" style="color:#8dc891">]</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Please check <a href="https://kosko.dev/docs/plugins/lint">here</a> for more details. More lint rules will be added in the future. Feel free to open an issue if you have any ideas.</p>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="streamlined-error-report">Streamlined Error Report<a href="https://kosko.dev/blog/2024/03/28/kosko-4.1#streamlined-error-report" class="hash-link" aria-label="Direct link to Streamlined Error Report" title="Direct link to Streamlined Error Report">​</a></h2>
<p>Error report was hugely improved in Kosko 3.0. However, it might be too verbose sometimes. In Kosko 4.1, error report system was redesigned to be more streamlined.</p>
<p>Manifest information such as API version, kind, namespace, name, and index were previously displayed in multiple lines. Now, they are displayed in a single line.</p>
<div class="codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-text codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token plain">components/nginx.ts - apps/v1/Deployment dev/nginx [0]</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">✖ /spec/replicas must be integer</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">✖ no-missing-namespace: Namespace "dev" does not exist or is not allowed.</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">components/nginx.ts - v1/Service nginx [1]</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">✖ unique-service-port-name: Service contains multiple ports with the same name "http"</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">error - Found 3 errors in total</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">error - Generate failed</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>The other improvement is the new <strong>warning</strong> severity. This severity is used for issues that are not critical, but should be fixed. When a warning is found, the error report will display a warning message, but the manifest generation will still be successful.</p>
<p>In the following example, missing readiness probe is displayed as a warning.</p>
<div class="codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-text codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token plain">components/nginx.ts - apps/v1/Deployment nginx [0]</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">⚠ require-probe: Container "nginx" must define a readiness probe.</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">warn  - Found 1 warning in total</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">info  - Components are valid</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="breaking-changes">Breaking Changes<a href="https://kosko.dev/blog/2024/03/28/kosko-4.1#breaking-changes" class="hash-link" aria-label="Direct link to Breaking Changes" title="Direct link to Breaking Changes">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_zlB1" id="minimum-nodejs-version">Minimum Node.js Version<a href="https://kosko.dev/blog/2024/03/28/kosko-4.1#minimum-nodejs-version" class="hash-link" aria-label="Direct link to Minimum Node.js Version" title="Direct link to Minimum Node.js Version">​</a></h3>
<p>Support for Node.js 14 was dropped. The minimum supported Node.js version is now 18.</p>
<h3 class="anchor anchorWithStickyNavbar_zlB1" id="kosko-cli">Kosko CLI<a href="https://kosko.dev/blog/2024/03/28/kosko-4.1#kosko-cli" class="hash-link" aria-label="Direct link to Kosko CLI" title="Direct link to Kosko CLI">​</a></h3>
<p><code>kosko init</code> command was removed from the CLI because it's only used at the first time. Now, you can use the new <a href="https://kosko.dev/docs/cli/create-kosko">create-kosko</a> package to create a new project.</p>
<div class="tabs-container tabList_hrVC"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_iNZw tabs__item--active">npm</li><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_iNZw">Yarn</li><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_iNZw">pnpm</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_EZ4y"><div class="language-shell codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-shell codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token plain">npm init kosko@latest example</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div><div role="tabpanel" class="tabItem_EZ4y" hidden=""><div class="language-shell codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-shell codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token plain">yarn create kosko@latest example</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div><div role="tabpanel" class="tabItem_EZ4y" hidden=""><div class="language-shell codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-shell codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token plain">pnpm create kosko@latest example</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_zlB1" id="koskogenerate"><code>@kosko/generate</code><a href="https://kosko.dev/blog/2024/03/28/kosko-4.1#koskogenerate" class="hash-link" aria-label="Direct link to koskogenerate" title="Direct link to koskogenerate">​</a></h3>
<div class="theme-admonition theme-admonition-info admonition_umkN alert alert--info"><div class="admonitionHeading_fwb7"><span class="admonitionIcon_WSTI"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_gis7"><p>This section only applies to users who use <code>@kosko/generate</code> programmatically. You can safely ignore this section if you only use the CLI.</p></div></div>
<p>Error handling was hugely changed in <code>@kosko/generate</code> 5.0. To support the new error report system, a new type <a href="https://kosko.dev/api/generate/interface/Issue"><code>Issue</code></a> ws introduced. This type is used in <a href="https://kosko.dev/api/generate/interface/Manifest#issues"><code>Manifest.issues</code></a>, providing more information about issues of manifests.</p>
<p>However, this means errors are no longer thrown when a validation error occurs. You can enable the previous behavior by setting <a href="https://kosko.dev/api/generate/interface/ResolveOptions#throwOnError"><code>throwOnError</code></a> to <code>true</code>.</p>
<p>Another change about the error handling is that Ajv errors are automatically transformed into issues. Now you can access Ajv errors in <a href="https://kosko.dev/api/generate/interface/Manifest#issues"><code>Manifest.issues</code></a>. You can disable this behavior by setting <a href="https://kosko.dev/api/generate/interface/ResolveOptions#keepAjvErrors"><code>keepAjvErrors</code></a> to <code>true</code>.</p>
<p>Next, the <code>component</code> property was replaced by <code>metadata</code> property in <a href="https://kosko.dev/api/generate/class/ResolveError"><code>ResolveError</code></a> class. The <code>metadata</code> property was added to <a href="https://kosko.dev/api/generate/interface/Manifest"><code>Manifest</code></a> type as well. This property contains API version, kind, namespace, and name of a manifest.</p>
<p>Lastly, <code>path</code> and <code>index</code> properties were replaced by the <code>position</code> property in <a href="https://kosko.dev/api/generate/interface/Manifest"><code>Manifest</code></a>, <a href="https://kosko.dev/api/generate/interface/ResolveErrorOptions"><code>ResolveErrorOptions</code></a>, and <a href="https://kosko.dev/api/generate/class/ResolveError"><code>ResolveError</code></a> type.</p>
<h3 class="anchor anchorWithStickyNavbar_zlB1" id="koskoaggregate-error"><code>@kosko/aggregate-error</code><a href="https://kosko.dev/blog/2024/03/28/kosko-4.1#koskoaggregate-error" class="hash-link" aria-label="Direct link to koskoaggregate-error" title="Direct link to koskoaggregate-error">​</a></h3>
<div class="theme-admonition theme-admonition-info admonition_umkN alert alert--info"><div class="admonitionHeading_fwb7"><span class="admonitionIcon_WSTI"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_gis7"><p>This section only applies to users who use the <code>@kosko/aggregate-error</code> package. You can safely ignore this section if you only use the CLI.</p></div></div>
<p>This package was removed because <code>AggregateError</code> is now built-in in Node.js 15.0.0 and later. If you are using <code>@kosko/aggregate-error</code> package, please remove it from your dependencies and just use the global <code>AggregateError</code> class.</p>
<h3 class="anchor anchorWithStickyNavbar_zlB1" id="koskorequire"><code>@kosko/require</code><a href="https://kosko.dev/blog/2024/03/28/kosko-4.1#koskorequire" class="hash-link" aria-label="Direct link to koskorequire" title="Direct link to koskorequire">​</a></h3>
<div class="theme-admonition theme-admonition-info admonition_umkN alert alert--info"><div class="admonitionHeading_fwb7"><span class="admonitionIcon_WSTI"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_gis7"><p>This section only applies to users who use the <code>@kosko/require</code> package. It's a low-level package, so you probably don't use it at all.</p></div></div>
<p>The <code>resolve</code> function is renamed to <a href="https://kosko.dev/api/require/function/resolvePath"><code>resolvePath</code></a> because the introduction of the new <a href="https://kosko.dev/api/require/function/resolveModule"><code>resolveModule</code></a> function. The <a href="https://kosko.dev/api/require/function/resolvePath"><code>resolvePath</code></a> function only supports path resolution, while the <a href="https://kosko.dev/api/require/function/resolveModule"><code>resolveModule</code></a> function supports both path and module resolution.</p>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="changelog">Changelog<a href="https://kosko.dev/blog/2024/03/28/kosko-4.1#changelog" class="hash-link" aria-label="Direct link to Changelog" title="Direct link to Changelog">​</a></h2>
<ul>
<li><a href="https://github.com/tommy351/kosko/pull/132" target="_blank" rel="noopener noreferrer">Kosko 4.0</a></li>
<li><a href="https://github.com/tommy351/kosko/pull/134" target="_blank" rel="noopener noreferrer">Kosko 4.1</a></li>
</ul>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Kosko 3.0 Released]]></title>
            <link>https://kosko.dev/blog/2022/11/06/kosko-3.0</link>
            <guid>https://kosko.dev/blog/2022/11/06/kosko-3.0</guid>
            <pubDate>Sun, 06 Nov 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[Kosko 3.0 has been released a few weeks ago. There are many improvements and some breaking changes in this version.]]></description>
            <content:encoded><![CDATA[<p>Kosko 3.0 has been released a few weeks ago. There are many improvements and some breaking changes in this version.</p>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="refined-error-report">Refined Error Report<a href="https://kosko.dev/blog/2022/11/06/kosko-3.0#refined-error-report" class="hash-link" aria-label="Direct link to Refined Error Report" title="Direct link to Refined Error Report">​</a></h2>
<p>In the previous version, when you run <code>kosko generate</code> or <code>kosko validate</code> command, only the first error is reported. Error messages are cramped and there is a lot of useless information.</p>
<div class="codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-text codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token plain">error - data/spec/replicas must be integer, data/spec must be null, data/spec must match exactly one schema in oneOf (path: "/home/tommy/Projects/kosko-old/examples/getting-started/components/nginx.js", index: [0], kind: "apps/v1/Deployment", name: "nginx")</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">ValidationError: data/spec/replicas must be integer, data/spec must be null, data/spec must match exactly one schema in oneOf</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">- path: "/home/tommy/Projects/kosko-old/examples/getting-started/components/nginx.js"</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">- index: [0]</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">- kind: "apps/v1/Deployment"</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">- name: "nginx"</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    at Object.validate (.../node_modules/.pnpm/@kubernetes-models+validate@2.0.1/node_modules/@kubernetes-models/validate/dist/validate.js:9:21)</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    at IoK8sApiAppsV1Deployment.validate (.../node_modules/.pnpm/@kubernetes-models+base@2.0.1/node_modules/@kubernetes-models/base/dist/model.js:44:20)</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    at resolve (.../packages/generate/dist/resolve.js:63:29)</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    at resolve (.../packages/generate/dist/resolve.js:50:34)</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    at generate (.../packages/generate/dist/generate.js:39:56)</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    at async generateHandler (.../packages/cli/dist/commands/generate/index.js:69:20)</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    at async Object.handler (.../packages/cli/dist/commands/generate/index.js:108:24)</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>In Kosko 3.0 and kubernetes-models 4.0, you can get all errors in a single run. This means you don't need to modify your code and rerun <code>kosko generate</code> command anymore.</p>
<p>Furthermore, error messages become cleaner and more human-readable now. They are grouped by component paths, and error stacks are only displayed for non-validation errors.</p>
<div class="codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-text codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token plain">components/mysql.js - 1 error</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  ✖ ResolveError: Validation error</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    Index: [0]</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    Kind: apps/v1/Deployment</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    Name: mysql</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">      /spec/template/spec/containers/0/env/0/value must be string</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">components/nginx.js - 1 error</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  ✖ ResolveError: Validation error</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    Index: [0]</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    Kind: apps/v1/Deployment</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    Name: nginx</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">      /spec/replicas must be integer</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">      /spec/template/spec/containers/0/ports/0/containerPort must be integer</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">error - Generate failed (Total 2 errors)</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>If you want to stop immediately whenever an error occurred, run <code>kosko generate</code> with <a href="https://kosko.dev/docs/cli/generate#--bail"><code>--bail</code></a> option.</p>
<div class="language-shell codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-shell codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token plain">kosko generate --bail</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Or enable <a href="https://kosko.dev/docs/configuration#bail"><code>bail</code></a> option in <code>kosko.toml</code>.</p>
<div class="language-toml codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockTitle_cQTU">kosko.toml</div><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-toml codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token plain">bail: </span><span class="token boolean" style="color:#ff8b50">true</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="improved-nullable-type-error">Improved Nullable Type Error<a href="https://kosko.dev/blog/2022/11/06/kosko-3.0#improved-nullable-type-error" class="hash-link" aria-label="Direct link to Improved Nullable Type Error" title="Direct link to Improved Nullable Type Error">​</a></h2>
<p>Besides Kosko, kubernetes-models was also updated to provide better error information for nullable types.</p>
<p>Let's say we have a nullable type as below.</p>
<div class="language-ts codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-ts codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token keyword" style="color:#c5a5c5">interface</span><span class="token plain"> </span><span class="token class-name" style="color:#FAC863">IPod</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  spec</span><span class="token operator" style="color:#d7deea">?</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> IPodSpec</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token punctuation" style="color:#8dc891">}</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>When a value in <code>spec</code> is invalid, it throws a validation error like this.</p>
<div class="codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-text codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token plain">data/spec must have required property 'containers',</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">data/spec must be null,</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">data/spec must match exactly one schema in oneOf</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Only the first line in this error message is helpful. Other lines are very confusing and might make developers think they should set <code>spec</code> as <code>null</code>. Such error messages are removed in this version.</p>
<div class="codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-text codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token plain">data/spec must have required property 'containers'</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="esm-loader-support">ESM Loader Support<a href="https://kosko.dev/blog/2022/11/06/kosko-3.0#esm-loader-support" class="hash-link" aria-label="Direct link to ESM Loader Support" title="Direct link to ESM Loader Support">​</a></h2>
<p>ESM loaders are finally supported in Kosko 3.0. You can use ESM loaders by adding <a href="https://kosko.dev/docs/configuration#loaders"><code>loaders</code></a> option to <code>kosko.toml</code>.</p>
<div class="language-toml codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockTitle_cQTU">kosko.toml</div><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-toml codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token key property" style="color:#5a9bcf">loaders</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">[</span><span class="token string" style="color:#8dc891">"ts-node/esm"</span><span class="token punctuation" style="color:#8dc891">]</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Or running <code>kosko generate</code> with <a href="https://kosko.dev/docs/cli/generate#--loader"><code>--loader</code></a> option.</p>
<div class="language-shell codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-shell codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token plain">kosko generate --loader ts-node/esm</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>See <a href="https://kosko.dev/docs/ecmascript-modules#typescript">ECMAScript modules</a> for more information about how to use TypeScript ESM loader.</p>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="faster-kustomize-build">Faster Kustomize Build<a href="https://kosko.dev/blog/2022/11/06/kosko-3.0#faster-kustomize-build" class="hash-link" aria-label="Direct link to Faster Kustomize Build" title="Direct link to Faster Kustomize Build">​</a></h2>
<p>In <code>@kosko/kustomize</code> 0.2, when you call <code>loadKustomize</code> function without <code>kustomize</code> CLI installed on your computer. <code>loadKustomize</code> will always try to call <code>kustomize</code> first then <code>kubectl kustomize</code>, which is slow if your components contain a lot of <code>loadKustomize</code> calls.</p>
<p>In <code>@kosko/kustomize</code> 1.0, successful <code>kustomize</code> CLI invocations are cached, so <code>loadKustomize</code> doesn't have to retry <code>kustomize</code> CLI every time.</p>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="iterable-support">Iterable Support<a href="https://kosko.dev/blog/2022/11/06/kosko-3.0#iterable-support" class="hash-link" aria-label="Direct link to Iterable Support" title="Direct link to Iterable Support">​</a></h2>
<p>Kosko 3.0 supports <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol" target="_blank" rel="noopener noreferrer">the iterable protocol</a>. You can use <code>Set</code>, <code>Map</code>, or generator functions in components now.</p>
<div class="language-ts codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-ts codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token comment" style="color:#999999">// Set</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">export</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">default</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">new</span><span class="token plain"> </span><span class="token class-name" style="color:#FAC863">Set</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">[</span><span class="token keyword" style="color:#c5a5c5">new</span><span class="token plain"> </span><span class="token class-name" style="color:#FAC863">Deployment</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">,</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">new</span><span class="token plain"> </span><span class="token class-name" style="color:#FAC863">Service</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">]</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token comment" style="color:#999999">// Generator function</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">function</span><span class="token operator" style="color:#d7deea">*</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">gen</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token keyword" style="color:#c5a5c5">yield</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">new</span><span class="token plain"> </span><span class="token class-name" style="color:#FAC863">Deployment</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token keyword" style="color:#c5a5c5">yield</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">new</span><span class="token plain"> </span><span class="token class-name" style="color:#FAC863">Service</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token punctuation" style="color:#8dc891">}</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>See <a href="https://kosko.dev/docs/components#iterable">Iterable</a> and <a href="https://kosko.dev/docs/components#async-iterable">Async Iterable</a> for more info.</p>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="breaking-changes">Breaking Changes<a href="https://kosko.dev/blog/2022/11/06/kosko-3.0#breaking-changes" class="hash-link" aria-label="Direct link to Breaking Changes" title="Direct link to Breaking Changes">​</a></h2>
<ul>
<li>
<p>Drop support for Node.js 12. The minimum supported Node.js version is 14.18.0 now.</p>
</li>
<li>
<p><code>@kosko/generate</code> - All errors thrown in <code>generate</code> and <code>resolve</code> functions are wrapped in <code>GenerateError</code> or <code>ResolveError</code> for better access to context.</p>
</li>
<li>
<p><code>@kosko/generate</code> - <code>ValidationError</code> is renamed as <code>ResolveError</code>.</p>
</li>
<li>
<p><code>@kosko/generate</code> - Multiple errors are wrapped in <code>AggregateError</code>.</p>
</li>
<li>
<p><code>@kosko/generate</code> - <code>ResolveError.message</code> no longer contains context information. You can access context from stack or direct access properties in the error value.</p>
</li>
<li>
<p><code>@kosko/generate</code> - <a href="https://github.com/mrmlnc/fast-glob" target="_blank" rel="noopener noreferrer"><code>fast-glob</code></a> is replaced with a homemade glob function based on <a href="https://github.com/micromatch/micromatch" target="_blank" rel="noopener noreferrer"><code>micromatch</code></a>. The behavior will be slightly different. Please submit an issue if you encounter any unexpected problems.</p>
</li>
<li>
<p><code>@kosko/yaml</code> - Value type in Manifest has been changed from <code>any</code> to <code>unknown</code>. You might need to modify <code>transform</code> function to fix type errors. For example:</p>
<div class="language-ts codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-ts codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token comment" style="color:#999999">// Before</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">manifest</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token plain">metadata</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token plain">namespace </span><span class="token operator" style="color:#d7deea">=</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"foo"</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token comment" style="color:#999999">// After (Preferred)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"> Pod </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"kubernetes-models/v1/Pod"</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">(</span><span class="token plain">Pod</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token keyword" style="color:#c5a5c5">is</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token plain">manifest</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  manifest</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token plain">metadata</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token plain">namespace </span><span class="token operator" style="color:#d7deea">=</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"foo"</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token comment" style="color:#999999">// After (Another way)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"> IObjectMeta </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"@kubernetes-models/apimachinery/apis/meta/v1/ObjectMeta"</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token punctuation" style="color:#8dc891">(</span><span class="token plain">manifest</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token plain">metadata </span><span class="token keyword" style="color:#c5a5c5">as</span><span class="token plain"> IObjectMeta</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token plain">namespace </span><span class="token operator" style="color:#d7deea">=</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"foo"</span><span class="token punctuation" style="color:#8dc891">;</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
</li>
<li>
<p><code>readonly</code> attribute is removed from the return types of many packages.</p>
</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="changelog">Changelog<a href="https://kosko.dev/blog/2022/11/06/kosko-3.0#changelog" class="hash-link" aria-label="Direct link to Changelog" title="Direct link to Changelog">​</a></h2>
<ul>
<li><a href="https://github.com/tommy351/kosko/releases/tag/%40kosko%2Faggregate-error%400.1.0" target="_blank" rel="noopener noreferrer"><code>@kosko/aggregate-error@0.1.0</code></a></li>
<li><a href="https://github.com/tommy351/kosko/releases/tag/%40kosko%2Fcli%403.0.0" target="_blank" rel="noopener noreferrer"><code>@kosko/cli@3.0.0</code></a></li>
<li><a href="https://github.com/tommy351/kosko/releases/tag/%40kosko%2Fcommon-utils%400.1.0" target="_blank" rel="noopener noreferrer"><code>@kosko/common-utils@0.1.0</code></a></li>
<li><a href="https://github.com/tommy351/kosko/releases/tag/%40kosko%2Fconfig%403.0.0" target="_blank" rel="noopener noreferrer"><code>@kosko/config@3.0.0</code></a></li>
<li><a href="https://github.com/tommy351/kosko/releases/tag/%40kosko%2Fenv%404.0.0" target="_blank" rel="noopener noreferrer"><code>@kosko/env@4.0.0</code></a></li>
<li><a href="https://github.com/tommy351/kosko/releases/tag/%40kosko%2Fexec-utils%401.0.0" target="_blank" rel="noopener noreferrer"><code>@kosko/exec-utils@1.0.0</code></a></li>
<li><a href="https://github.com/tommy351/kosko/releases/tag/%40kosko%2Fgenerate%403.0.0" target="_blank" rel="noopener noreferrer"><code>@kosko/generate@3.0.0</code></a></li>
<li><a href="https://github.com/tommy351/kosko/releases/tag/%40kosko%2Fhelm%403.0.0" target="_blank" rel="noopener noreferrer"><code>@kosko/helm@3.0.0</code></a></li>
<li><a href="https://github.com/tommy351/kosko/releases/tag/%40kosko%2Fkustomize%401.0.0" target="_blank" rel="noopener noreferrer"><code>@kosko/kustomize@1.0.0</code></a></li>
<li><a href="https://github.com/tommy351/kosko/releases/tag/%40kosko%2Flog%401.0.0" target="_blank" rel="noopener noreferrer"><code>@kosko/log@1.0.0</code></a></li>
<li><a href="https://github.com/tommy351/kosko/releases/tag/%40kosko%2Fmigrate%404.0.0" target="_blank" rel="noopener noreferrer"><code>@kosko/migrate@4.0.0</code></a></li>
<li><a href="https://github.com/tommy351/kosko/releases/tag/%40kosko%2Frequire%404.0.0" target="_blank" rel="noopener noreferrer"><code>@kosko/require@4.0.0</code></a></li>
<li><a href="https://github.com/tommy351/kosko/releases/tag/%40kosko%2Ftemplate-deployed-service%403.0.0" target="_blank" rel="noopener noreferrer"><code>@kosko/template-deployed-service@3.0.0</code></a></li>
<li><a href="https://github.com/tommy351/kosko/releases/tag/%40kosko%2Ftemplate-environment%403.0.0" target="_blank" rel="noopener noreferrer"><code>@kosko/template-environment@3.0.0</code></a></li>
<li><a href="https://github.com/tommy351/kosko/releases/tag/%40kosko%2Ftemplate%403.0.0" target="_blank" rel="noopener noreferrer"><code>@kosko/template@3.0.0</code></a></li>
<li><a href="https://github.com/tommy351/kosko/releases/tag/%40kosko%2Fyaml%403.0.0" target="_blank" rel="noopener noreferrer"><code>@kosko/yaml@3.0.0</code></a></li>
</ul>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[kubernetes-models 3.0 Released]]></title>
            <link>https://kosko.dev/blog/2022/02/23/kubernetes-models-3.0-released</link>
            <guid>https://kosko.dev/blog/2022/02/23/kubernetes-models-3.0-released</guid>
            <pubDate>Wed, 23 Feb 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[[kubernetes-models] 3.0 has been released last month. To upgrade to the latest kubernetes-models, run:]]></description>
            <content:encoded><![CDATA[<p><a href="https://github.com/tommy351/kubernetes-models-ts" target="_blank" rel="noopener noreferrer">kubernetes-models</a> 3.0 has been released last month. To upgrade to the latest <code>kubernetes-models</code>, run:</p>
<div class="language-shell codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-shell codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token plain">npm install kubernetes-models@latest</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>If you have installed any CRD packages, don't forget to upgrade them as well.</p>
<!-- -->
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="smaller-package-size">Smaller Package Size<a href="https://kosko.dev/blog/2022/02/23/kubernetes-models-3.0-released#smaller-package-size" class="hash-link" aria-label="Direct link to Smaller Package Size" title="Direct link to Smaller Package Size">​</a></h2>
<p>The package size of <code>kubernetes-models</code> 3.0 is reduced by 34% compressed, or 20% unpacked (compared to 2.0.2).</p>
<table><thead><tr><th>Version</th><th style="text-align:right">Unpacked</th><th style="text-align:right">Compressed</th></tr></thead><tbody><tr><td>2.0.2</td><td style="text-align:right">5.9MB</td><td style="text-align:right">749KB</td></tr><tr><td>3.0.1</td><td style="text-align:right">4.7MB</td><td style="text-align:right">494KB</td></tr><tr><td>Diff</td><td style="text-align:right">-20.33%</td><td style="text-align:right">-34.04%</td></tr></tbody></table>
<p>Several changes made the package size smaller in 3.0.</p>
<p>First, the following alias files are removed in 3.0. These alias files were introduced a few years ago. Removing these files can reduce the number of files and the size of the export map.</p>
<div class="theme-admonition theme-admonition-caution admonition_umkN alert alert--warning"><div class="admonitionHeading_fwb7"><span class="admonitionIcon_WSTI"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>Breaking Change</div><div class="admonitionContent_gis7"><p>If you are using any of these import patterns, please rewrite import paths after upgrading to 3.0.</p><ul>
<li><code>kubernetes-models/api/core/v1/Pod</code></li>
<li><code>kubernetes-models/api/apps/v1/Deployment</code></li>
<li><code>kubernetes-models/apiextensions-apiserver/pkg/apis/apiextensions/v1/CustomResourceDefinition</code></li>
</ul></div></div>
<p>Next, type definition files are used to be stored in <code>_definitions/&lt;id&gt;.js</code>. In 3.0, they are moved to <code>&lt;apiVersion&gt;/&lt;kind&gt;.js</code>. This can also reduce the number of alias files, and import paths can be shorter, too.</p>
<p>Last, a new type <code>TypeMeta</code> has been added to <code>@kubernetes-models/base</code> package. Interfaces with <code>apiVersion</code> and <code>kind</code> will extend <code>TypeMeta</code> type now. This can remove doc comments in each type.</p>
<div class="language-ts codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-ts codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token comment" style="color:#999999">// Before</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">export</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">interface</span><span class="token plain"> </span><span class="token class-name" style="color:#FAC863">IIoK8sApiCoreV1Pod</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token doc-comment comment" style="color:#999999">/**</span><br></span><span class="token-line" style="color:#ffffff"><span class="token doc-comment comment" style="color:#999999">   * APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources</span><br></span><span class="token-line" style="color:#ffffff"><span class="token doc-comment comment" style="color:#999999">   */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  apiVersion</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"v1"</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token doc-comment comment" style="color:#999999">/**</span><br></span><span class="token-line" style="color:#ffffff"><span class="token doc-comment comment" style="color:#999999">   * Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds</span><br></span><span class="token-line" style="color:#ffffff"><span class="token doc-comment comment" style="color:#999999">   */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  kind</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"Pod"</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token comment" style="color:#999999">// After</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">export</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">interface</span><span class="token plain"> </span><span class="token class-name" style="color:#FAC863">IPod</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">extends</span><span class="token plain"> </span><span class="token class-name" style="color:#FAC863">TypeMeta</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  apiVersion</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"v1"</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  kind</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"Pod"</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token punctuation" style="color:#8dc891">}</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="better-import-suggestions">Better Import Suggestions<a href="https://kosko.dev/blog/2022/02/23/kubernetes-models-3.0-released#better-import-suggestions" class="hash-link" aria-label="Direct link to Better Import Suggestions" title="Direct link to Better Import Suggestions">​</a></h2>
<p>Type definition files are used to be stored in <code>_definitions/&lt;id&gt;.js</code>, which are supposed to be hidden files. But sometimes IDEs get confused and show them in import suggestions. In 3.0, they are moved to more proper locations, which should provide a better IDE experience.</p>
<p>Before:</p>
<div style="background-size:cover;background-repeat:no-repeat;position:relative;background-image:url(&quot;data:image/jpeg;base64,/9j/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAADAAoDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAMH/8QAHhAAAgEDBQAAAAAAAAAAAAAAAAECAxEhIjJRkbH/xAAVAQEBAAAAAAAAAAAAAAAAAAACA//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhEDEQA/AMUryenL2x8I3fL7AKg//9k=&quot;)"><svg style="width:100%;height:auto;max-width:100%;margin-bottom:-4px" width="1200" height="399"></svg><noscript><img style=width:100%;height:auto;max-width:100%;margin-bottom:-4px;position:absolute;top:0;left:0 src=/assets/ideal-img/import-path-before.55a2e0b.1200.jpg srcset="/assets/ideal-img/import-path-before.55a2e0b.1200.jpg 1200w" width=1200 height=399></noscript></div>
<p>After:</p>
<div style="background-size:cover;background-repeat:no-repeat;position:relative;background-image:url(&quot;data:image/jpeg;base64,/9j/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAADAAoDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAMH/8QAHBAAAQMFAAAAAAAAAAAAAAAAAAECEQMhQnGR/8QAFQEBAQAAAAAAAAAAAAAAAAAAAgP/xAAVEQEBAAAAAAAAAAAAAAAAAAAAAf/aAAwDAQACEQMRAD8AxSo5YZfBCMb6AUCv/9k=&quot;)"><svg style="width:100%;height:auto;max-width:100%;margin-bottom:-4px" width="1200" height="397"></svg><noscript><img style=width:100%;height:auto;max-width:100%;margin-bottom:-4px;position:absolute;top:0;left:0 src=/assets/ideal-img/import-path-after.e7790c9.1200.jpg srcset="/assets/ideal-img/import-path-after.e7790c9.1200.jpg 1200w" width=1200 height=397></noscript></div>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="api-machinery-package">API Machinery Package<a href="https://kosko.dev/blog/2022/02/23/kubernetes-models-3.0-released#api-machinery-package" class="hash-link" aria-label="Direct link to API Machinery Package" title="Direct link to API Machinery Package">​</a></h2>
<p>A new package <code>@kubernetes-models/apimachinery</code> has been released with <code>kubernetes-models</code> 3.0. This package includes types defined in <a href="https://github.com/kubernetes/apimachinery" target="_blank" rel="noopener noreferrer">kubernetes/apimachinery</a> only. All CRD packages have been migrated to import this package instead of the whole <code>kubernetes-models</code>. This can reduce the size of dependencies of CRD packages.</p>
<div class="theme-admonition theme-admonition-caution admonition_umkN alert alert--warning"><div class="admonitionHeading_fwb7"><span class="admonitionIcon_WSTI"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>Breaking Change</div><div class="admonitionContent_gis7"><p>If you are using API machinery files, please rewrite import paths as below.</p><div class="language-ts codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-ts codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token comment" style="color:#999999">// Before</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"> IObjectMeta </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"kubernetes-models/apimachinery/pkg/apis/meta/v1/ObjectMeta"</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token comment" style="color:#999999">// After</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"> IObjectMeta </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"@kubernetes-models/apimachinery/pkg/apis/meta/v1/ObjectMeta"</span><span class="token punctuation" style="color:#8dc891">;</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="type-guard">Type Guard<a href="https://kosko.dev/blog/2022/02/23/kubernetes-models-3.0-released#type-guard" class="hash-link" aria-label="Direct link to Type Guard" title="Direct link to Type Guard">​</a></h2>
<p>All classes with <code>apiVersion</code> and <code>kind</code> now come with a new static method <code>is</code>, which can be used to narrow down object types. Please note that this function does <strong>NOT</strong> validate the object itself. It just checks whether <code>apiVersion</code> and <code>kind</code> match or not.</p>
<div class="language-ts codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-ts codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token keyword" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"> Pod </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"kubernetes-models/v1/Pod"</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> thing </span><span class="token operator" style="color:#d7deea">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"> apiVersion</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"v1"</span><span class="token punctuation" style="color:#8dc891">,</span><span class="token plain"> kind</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"Pod"</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">(</span><span class="token plain">Pod</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token keyword" style="color:#c5a5c5">is</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token plain">thing</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token comment" style="color:#999999">// thing is an `IPod`.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token comment" style="color:#999999">// thing is something else</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token punctuation" style="color:#8dc891">}</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Type guards can also be used in the <code>transform</code> function of <code>@kosko/yaml</code>.</p>
<div class="language-ts codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-ts codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token keyword" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"> loadFile </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"@kosko/yaml"</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"> Service </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"kubernetes-models/v1/Service"</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token function" style="color:#79b6f2">loadFile</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token string" style="color:#8dc891">"manifest.yaml"</span><span class="token punctuation" style="color:#8dc891">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token function" style="color:#79b6f2">transform</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token plain">manifest</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    </span><span class="token comment" style="color:#999999">// Set all service type as "ClusterIP"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    </span><span class="token keyword" style="color:#c5a5c5">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">(</span><span class="token plain">Service</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token keyword" style="color:#c5a5c5">is</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token plain">manifest</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">      manifest</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token plain">spec</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token plain">type </span><span class="token operator" style="color:#d7deea">=</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"ClusterIP"</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    </span><span class="token keyword" style="color:#c5a5c5">return</span><span class="token plain"> manifest</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token punctuation" style="color:#8dc891">}</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">;</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>You can see <a href="https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates" target="_blank" rel="noopener noreferrer">TypeScript documentation</a> for more information about narrowing and type predicates.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introducing Kustomize Support]]></title>
            <link>https://kosko.dev/blog/2021/12/19/kustomize</link>
            <guid>https://kosko.dev/blog/2021/12/19/kustomize</guid>
            <pubDate>Sun, 19 Dec 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Kosko now supports Kustomize files. With the new @kosko/kustomize package, you can load your existing Kustomize files into Kosko, and it also supports Kubernetes OpenAPI schema validation.]]></description>
            <content:encoded><![CDATA[<p>Kosko now supports Kustomize files. With the new <code>@kosko/kustomize</code> package, you can load your existing Kustomize files into Kosko, and it also supports Kubernetes OpenAPI schema validation.</p>
<p><code>@kosko/kustomize</code> uses the <code>kustomize build</code> or <code>kubectl kustomize</code> command to generate Kubernetes manifests and the <code>@kosko/yaml</code> package to load Kubernetes YAML.</p>
<p>First, you have to install either <a href="https://kubectl.docs.kubernetes.io/installation/kustomize/" target="_blank" rel="noopener noreferrer"><code>kustomize</code></a> or <a href="https://kubectl.docs.kubernetes.io/installation/kubectl/" target="_blank" rel="noopener noreferrer"><code>kubectl</code></a> CLI, then install the <code>@kosko/kustomize</code> package.</p>
<div class="language-shell codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-shell codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token plain">npm install @kosko/kustomize</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Next, use the <code>loadKustomize</code> function to load Kustomize files.</p>
<div class="language-js codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-js codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"> loadKustomize </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"> </span><span class="token operator" style="color:#d7deea">=</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">require</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token string" style="color:#8dc891">"@kosko/kustomize"</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token function" style="color:#79b6f2">loadKustomize</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token literal-property property" style="color:#5a9bcf">path</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"./dir"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token punctuation" style="color:#8dc891">}</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">;</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>See <a href="https://kosko.dev/docs/components/loading-kustomize">loading Kustomize</a> for more details.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Running Kosko in Browser]]></title>
            <link>https://kosko.dev/blog/2021/04/29/browser</link>
            <guid>https://kosko.dev/blog/2021/04/29/browser</guid>
            <pubDate>Thu, 29 Apr 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Last month, ECMAScript modules (ESM) support was shipped in Kosko 1.1. Today, you can use ESM not only in Node.js, but also in browsers. Currently only the following packages are browser-ready. Please make sure to update these packages before using Kosko in a browser.]]></description>
            <content:encoded><![CDATA[<p>Last month, ECMAScript modules (ESM) support was shipped in Kosko 1.1. Today, you can use ESM not only in Node.js, but also in browsers. Currently only the following packages are browser-ready. Please make sure to update these packages before using Kosko in a browser.</p>
<ul>
<li><code>@kosko/env</code> - 2.0.0</li>
<li><code>@kosko/generate</code> - 1.2.0</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="programmatic-api">Programmatic API<a href="https://kosko.dev/blog/2021/04/29/browser#programmatic-api" class="hash-link" aria-label="Direct link to Programmatic API" title="Direct link to Programmatic API">​</a></h2>
<p>Kosko can be used in browsers via the programmatic API. In the following example, first we use dynamic import to load environment variables. Then, use the <code>resolve</code> function to resolve and validate components. And finally, print the resolved manifests with the <code>print</code> function.</p>
<div class="language-js codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-js codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports">env</span><span class="token imports punctuation" style="color:#8dc891">,</span><span class="token imports"> </span><span class="token imports punctuation" style="color:#8dc891">{</span><span class="token imports"> createAsyncLoaderReducers </span><span class="token imports punctuation" style="color:#8dc891">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"@kosko/env"</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#8dc891">{</span><span class="token imports"> resolve</span><span class="token imports punctuation" style="color:#8dc891">,</span><span class="token imports"> print</span><span class="token imports punctuation" style="color:#8dc891">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">PrintFormat</span><span class="token imports"> </span><span class="token imports punctuation" style="color:#8dc891">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"@kosko/generate"</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token comment" style="color:#999999">// Load environment variables with dynamic import</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">env</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token method function property-access" style="color:#79b6f2">setReducers</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token parameter">reducers</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#d7deea">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token spread operator" style="color:#d7deea">...</span><span class="token plain">reducers</span><span class="token punctuation" style="color:#8dc891">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token spread operator" style="color:#d7deea">...</span><span class="token method function property-access" style="color:#79b6f2">createAsyncLoaderReducers</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    </span><span class="token function-variable function" style="color:#79b6f2">global</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#d7deea">=&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">      </span><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token string" style="color:#8dc891">"./environments/dev/index.js"</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token method function property-access" style="color:#79b6f2">then</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token parameter">mod</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#d7deea">=&gt;</span><span class="token plain"> mod</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token keyword module" style="color:#c5a5c5">default</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    </span><span class="token function-variable function" style="color:#79b6f2">component</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">(</span><span class="token parameter">name</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#d7deea">=&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">      </span><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token template-string template-punctuation string" style="color:#8dc891">`</span><span class="token template-string string" style="color:#8dc891">./environments/dev/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#8dc891">${</span><span class="token template-string interpolation">name</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#8dc891">}</span><span class="token template-string string" style="color:#8dc891">.js</span><span class="token template-string template-punctuation string" style="color:#8dc891">`</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token method function property-access" style="color:#79b6f2">then</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token parameter">mod</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#d7deea">=&gt;</span><span class="token plain"> mod</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token keyword module" style="color:#c5a5c5">default</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token punctuation" style="color:#8dc891">]</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token punctuation" style="color:#8dc891">(</span><span class="token keyword" style="color:#c5a5c5">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#d7deea">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token comment" style="color:#999999">// Resolve and validate components</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> manifests </span><span class="token operator" style="color:#d7deea">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#c5a5c5">await</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">resolve</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    </span><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token string" style="color:#8dc891">"./components/nginx.js"</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token method function property-access" style="color:#79b6f2">then</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token parameter">mod</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#d7deea">=&gt;</span><span class="token plain"> mod</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token keyword module" style="color:#c5a5c5">default</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token comment" style="color:#999999">// Print resolved manifests</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token function" style="color:#79b6f2">print</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"> manifests </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token punctuation" style="color:#8dc891">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">      </span><span class="token literal-property property" style="color:#5a9bcf">format</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> </span><span class="token maybe-class-name">PrintFormat</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token constant" style="color:#5a9bcf">YAML</span><span class="token punctuation" style="color:#8dc891">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">      </span><span class="token literal-property property" style="color:#5a9bcf">writer</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"> </span><span class="token function-variable function" style="color:#79b6f2">write</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">(</span><span class="token parameter">data</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#d7deea">=&gt;</span><span class="token plain"> </span><span class="token console class-name" style="color:#FAC863">console</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token method function property-access" style="color:#79b6f2">log</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token plain">data</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token punctuation" style="color:#8dc891">}</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">;</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>See <a href="https://kosko.dev/docs/using-in-browser">using in browser</a> for more details.</p>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="more-examples">More Examples<a href="https://kosko.dev/blog/2021/04/29/browser#more-examples" class="hash-link" aria-label="Direct link to More Examples" title="Direct link to More Examples">​</a></h2>
<p>You can try Kosko in the <a href="https://kosko.dev/play">playground</a>, or check the following examples.</p>
<ul>
<li>Webpack 5 - <a href="https://github.com/tommy351/kosko/tree/master/examples/web-webpack-5" target="_blank" rel="noopener noreferrer">GitHub</a> / <a href="https://codesandbox.io/s/github/tommy351/kosko/tree/master/examples/web-webpack-5" target="_blank" rel="noopener noreferrer">CodeSandbox</a></li>
<li>Static - <a href="https://github.com/tommy351/kosko/tree/master/examples/web-static" target="_blank" rel="noopener noreferrer">GitHub</a> / <a href="https://codesandbox.io/s/github/tommy351/kosko/tree/master/examples/web-static" target="_blank" rel="noopener noreferrer">CodeSandbox</a></li>
<li>Sync Environment - <a href="https://github.com/tommy351/kosko/tree/master/examples/web-sync-environment" target="_blank" rel="noopener noreferrer">GitHub</a> / <a href="https://codesandbox.io/s/github/tommy351/kosko/tree/master/examples/web-sync-environment" target="_blank" rel="noopener noreferrer">CodeSandbox</a></li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="breaking-changes">Breaking Changes<a href="https://kosko.dev/blog/2021/04/29/browser#breaking-changes" class="hash-link" aria-label="Direct link to Breaking Changes" title="Direct link to Breaking Changes">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_zlB1" id="koskoenv"><code>@kosko/env</code><a href="https://kosko.dev/blog/2021/04/29/browser#koskoenv" class="hash-link" aria-label="Direct link to koskoenv" title="Direct link to koskoenv">​</a></h3>
<p>The following APIs were changed in this release.</p>
<ul>
<li><code>Environment</code> class → <code>Environment</code> interface</li>
<li><code>SyncEnvironment</code> class → <code>createNodeCJSEnvironment</code> function</li>
<li><code>AsyncEnvironment</code> class → <code>createNodeESMEnvironment</code> function</li>
</ul>
<p>You don't have to change anything, unless you initialize these classes manually.</p>
<div class="language-js codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-js codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token comment" style="color:#999999">// Before</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"> </span><span class="token maybe-class-name">Environment</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"> </span><span class="token operator" style="color:#d7deea">=</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">require</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token string" style="color:#8dc891">"@kosko/env"</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> env </span><span class="token operator" style="color:#d7deea">=</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">new</span><span class="token plain"> </span><span class="token class-name" style="color:#FAC863">Environment</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token plain">process</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token method function property-access" style="color:#79b6f2">cwd</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token comment" style="color:#999999">// After</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"> createNodeCJSEnvironment </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"> </span><span class="token operator" style="color:#d7deea">=</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">require</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token string" style="color:#8dc891">"@kosko/env"</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> env </span><span class="token operator" style="color:#d7deea">=</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">createNodeCJSEnvironment</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#5a9bcf">cwd</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token method function property-access" style="color:#79b6f2">cwd</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">;</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introducing Helm Support]]></title>
            <link>https://kosko.dev/blog/2021/04/05/helm</link>
            <guid>https://kosko.dev/blog/2021/04/05/helm</guid>
            <pubDate>Mon, 05 Apr 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Most popular apps are available as Helm charts. It was not easy to use them in Kosko directly. The all new @kosko/helm package can help you load Helm charts, and of course, it also supports Kubernetes OpenAPI schema validation.]]></description>
            <content:encoded><![CDATA[<p>Most popular apps are available as Helm charts. It was not easy to use them in Kosko directly. The all new <code>@kosko/helm</code> package can help you load Helm charts, and of course, it also supports Kubernetes OpenAPI schema validation.</p>
<p><code>@kosko/helm</code> uses the <a href="https://helm.sh/docs/helm/helm_template/" target="_blank" rel="noopener noreferrer"><code>helm template</code></a> command to render chart templates and the <code>@kosko/yaml</code> package to load Kubernetes YAML.</p>
<p>First, you have to <a href="https://helm.sh/docs/intro/install/" target="_blank" rel="noopener noreferrer">install the Helm CLI</a>, then install the <code>@kosko/helm</code> package.</p>
<div class="language-shell codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-shell codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token plain">npm install @kosko/helm</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Next, use the <code>loadChart</code> function to load Helm charts.</p>
<div class="language-js codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-js codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"> loadChart </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"> </span><span class="token operator" style="color:#d7deea">=</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">require</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token string" style="color:#8dc891">"@kosko/helm"</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token function" style="color:#79b6f2">loadChart</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token literal-property property" style="color:#5a9bcf">name</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"prom"</span><span class="token punctuation" style="color:#8dc891">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token literal-property property" style="color:#5a9bcf">chart</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"prometheus"</span><span class="token punctuation" style="color:#8dc891">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token literal-property property" style="color:#5a9bcf">repo</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"https://prometheus-community.github.io/helm-charts"</span><span class="token punctuation" style="color:#8dc891">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token literal-property property" style="color:#5a9bcf">version</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"13.6.0"</span><span class="token punctuation" style="color:#8dc891">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token literal-property property" style="color:#5a9bcf">values</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    </span><span class="token literal-property property" style="color:#5a9bcf">server</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">      </span><span class="token literal-property property" style="color:#5a9bcf">persistentVolume</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">        </span><span class="token literal-property property" style="color:#5a9bcf">enabled</span><span class="token operator" style="color:#d7deea">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ff8b50">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">      </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token punctuation" style="color:#8dc891">}</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">;</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>See <a href="https://kosko.dev/docs/components/loading-helm-chart">loading Helm chart</a> for more details.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Kosko 1.1: ESM Support]]></title>
            <link>https://kosko.dev/blog/2021/03/09/kosko-1.1</link>
            <guid>https://kosko.dev/blog/2021/03/09/kosko-1.1</guid>
            <pubDate>Tue, 09 Mar 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Kosko comes with ECMAScript modules (ESM) support since v1.1. You can write components and environments in native ESM files. The following packages are updated for ESM support. Please make sure to update these packages before using ESM.]]></description>
            <content:encoded><![CDATA[<p>Kosko comes with ECMAScript modules (ESM) support since v1.1. You can write components and environments in native ESM files. The following packages are updated for ESM support. Please make sure to update these packages before using ESM.</p>
<ul>
<li><code>@kosko/cli</code> - 1.2.0</li>
<li><code>@kosko/env</code> - 1.1.0</li>
<li><code>@kosko/generate</code> - 1.1.0</li>
<li><code>kosko</code> - 1.1.0</li>
<li><code>@kosko/migrate</code> - 2.0.0</li>
<li><code>@kosko/require</code> - 2.0.0</li>
<li><code>@kosko/yaml</code> - 1.0.0</li>
</ul>
<p>The biggest difference between CommonJS and ESM is that <code>@kosko/env</code> is asynchronous in ESM. This is because <code>import()</code> is asynchronous. But don't freak out, it won't break your current code at all. <code>@kosko/env</code> is still synchronous in CommonJS.</p>
<p>When retrieving environments in ESM, you <strong>MUST</strong> add <code>await</code> as the example below.</p>
<div class="language-js codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-js codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports">env</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"@kosko/env"</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> globalParams </span><span class="token operator" style="color:#d7deea">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#c5a5c5">await</span><span class="token plain"> env</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token method function property-access" style="color:#79b6f2">global</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> componentParams </span><span class="token operator" style="color:#d7deea">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#c5a5c5">await</span><span class="token plain"> env</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token method function property-access" style="color:#79b6f2">component</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token string" style="color:#8dc891">"demo"</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">;</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Instead of <code>module.exports</code>, export components or environments with <code>export default</code>.</p>
<div class="language-js codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-js codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#8dc891">{</span><span class="token imports"> </span><span class="token imports maybe-class-name">Deployment</span><span class="token imports"> </span><span class="token imports punctuation" style="color:#8dc891">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"kubernetes-models/apps/v1/Deployment"</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#8dc891">{</span><span class="token imports"> </span><span class="token imports maybe-class-name">Service</span><span class="token imports"> </span><span class="token imports punctuation" style="color:#8dc891">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"kubernetes-models/v1/Service"</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token keyword module" style="color:#c5a5c5">export</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">default</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">[</span><span class="token keyword" style="color:#c5a5c5">new</span><span class="token plain"> </span><span class="token class-name" style="color:#FAC863">Deployment</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">{</span><span class="token punctuation" style="color:#8dc891">}</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">,</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">new</span><span class="token plain"> </span><span class="token class-name" style="color:#FAC863">Service</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">{</span><span class="token punctuation" style="color:#8dc891">}</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">]</span><span class="token punctuation" style="color:#8dc891">;</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>For more details about how to enable ESM or programmatical usage, please check <a href="https://kosko.dev/docs/ecmascript-modules">here</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="breaking-changes">Breaking Changes<a href="https://kosko.dev/blog/2021/03/09/kosko-1.1#breaking-changes" class="hash-link" aria-label="Direct link to Breaking Changes" title="Direct link to Breaking Changes">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_zlB1" id="koskoyaml"><code>@kosko/yaml</code><a href="https://kosko.dev/blog/2021/03/09/kosko-1.1#koskoyaml" class="hash-link" aria-label="Direct link to koskoyaml" title="Direct link to koskoyaml">​</a></h3>
<p><code>loadString</code> and <code>getResourceModule</code> functions become asynchronous because of ESM support.</p>
<h3 class="anchor anchorWithStickyNavbar_zlB1" id="koskomigrate"><code>@kosko/migrate</code><a href="https://kosko.dev/blog/2021/03/09/kosko-1.1#koskomigrate" class="hash-link" aria-label="Direct link to koskomigrate" title="Direct link to koskomigrate">​</a></h3>
<p><code>migrate</code> and <code>migrateString</code> functions become asynchronous because of the breaking changes of <code>@kosko/yaml</code> package.</p>
<h3 class="anchor anchorWithStickyNavbar_zlB1" id="koskorequire"><code>@kosko/require</code><a href="https://kosko.dev/blog/2021/03/09/kosko-1.1#koskorequire" class="hash-link" aria-label="Direct link to koskorequire" title="Direct link to koskorequire">​</a></h3>
<p><code>resolve</code> function no longer allows <code>resolve.AsyncOpts</code> as options, please use <code>ResolveOptions</code> instead.</p>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="kubernetes-models">kubernetes-models<a href="https://kosko.dev/blog/2021/03/09/kosko-1.1#kubernetes-models" class="hash-link" aria-label="Direct link to kubernetes-models" title="Direct link to kubernetes-models">​</a></h2>
<p><a href="https://github.com/tommy351/kubernetes-models-ts" target="_blank" rel="noopener noreferrer">kubernetes-models</a> is also updated for ESM support.</p>
<ul>
<li><code>@kubernetes-models/base</code> - 1.2.0</li>
<li><code>@kubernetes-models/cert-manager</code> - 1.1.0</li>
<li><code>@kubernetes-models/contour</code> - 1.1.0</li>
<li><code>@kubernetes-models/crd-generate</code> - 1.2.0</li>
<li><code>@kubernetes-models/gke</code> - 1.1.0</li>
<li><code>kubernetes-models</code> - 1.1.0</li>
<li><code>@kubernetes-models/openapi-generate</code> - 1.2.0</li>
<li><code>@kubernetes-models/prometheus-operator</code> - 1.1.0</li>
<li><code>@kubernetes-models/read-input</code> - 1.1.0</li>
<li><code>@kubernetes-models/sealed-secrets</code> - 1.1.0</li>
<li><code>@kubernetes-models/string-util</code> - 1.1.0</li>
<li><code>@kubernetes-models/validate</code> - 1.1.0</li>
</ul>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Kosko 1.0 Released]]></title>
            <link>https://kosko.dev/blog/2020/11/22/kosko-1.0-released</link>
            <guid>https://kosko.dev/blog/2020/11/22/kosko-1.0-released</guid>
            <pubDate>Sun, 22 Nov 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[It has been a long time since the last stable release v0.9. Recently, I decide to implement some features that I always want to have at work. Hope these new features can also help you.]]></description>
            <content:encoded><![CDATA[<p>It has been a long time since the last stable release v0.9. Recently, I decide to implement some features that I always want to have at work. Hope these new features can also help you.</p>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="nested-manifests">Nested Manifests<a href="https://kosko.dev/blog/2020/11/22/kosko-1.0-released#nested-manifests" class="hash-link" aria-label="Direct link to Nested Manifests" title="Direct link to Nested Manifests">​</a></h2>
<p>In v1.0, arrays and functions in components are flattened. This is useful for sharing manifests across components.</p>
<p>For instance, a database in Kubernetes is typically composed by a <code>Deployment</code> and a <code>Service</code>. To include a database in a component, before v1.0, you have to flatten these two manifests in the component by yourself. After v1.0, they are flattened automatically.</p>
<p>In this way, a database can be used as a single resource, which can be used everywhere in your components.</p>
<div class="language-js codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-js codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token keyword" style="color:#c5a5c5">function</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">createDatabase</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#c5a5c5">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">[</span><span class="token keyword" style="color:#c5a5c5">new</span><span class="token plain"> </span><span class="token class-name" style="color:#FAC863">Deployment</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">,</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">new</span><span class="token plain"> </span><span class="token class-name" style="color:#FAC863">Service</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">]</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token comment" style="color:#999999">// Before v1.0</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">module</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token property-access">exports</span><span class="token plain"> </span><span class="token operator" style="color:#d7deea">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">[</span><span class="token keyword" style="color:#c5a5c5">new</span><span class="token plain"> </span><span class="token class-name" style="color:#FAC863">Deployment</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">,</span><span class="token plain"> </span><span class="token spread operator" style="color:#d7deea">...</span><span class="token method function property-access" style="color:#79b6f2">createDatabase</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">]</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain"></span><span class="token comment" style="color:#999999">// After v1.0</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">module</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token property-access">exports</span><span class="token plain"> </span><span class="token operator" style="color:#d7deea">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">[</span><span class="token keyword" style="color:#c5a5c5">new</span><span class="token plain"> </span><span class="token class-name" style="color:#FAC863">Deployment</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">,</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">createDatabase</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">]</span><span class="token punctuation" style="color:#8dc891">;</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="more-information-in-validationerror">More Information in <code>ValidationError</code><a href="https://kosko.dev/blog/2020/11/22/kosko-1.0-released#more-information-in-validationerror" class="hash-link" aria-label="Direct link to more-information-in-validationerror" title="Direct link to more-information-in-validationerror">​</a></h2>
<p>There was only <code>path</code> and <code>index</code> in <code>ValidationError</code> before v1.0. Sometimes it might be difficult to find where the error is. In v1.0, <code>apiVersion</code>, <code>kind</code>, <code>namespace</code> and <code>name</code> are added to <code>ValidationError</code>. The following is an example of the new error message.</p>
<div class="language-shell codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-shell codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token plain">ValidationError: data.metadata.annotations['dependencies'] should be string</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">- path: ".../components/config-api"</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">- index: [0]</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">- kind: "apps/v1/Deployment"</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">- name: "config-api"</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    at resolveComponent (.../node_modules/@kosko/generate/src/generate.ts:81:15)</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    at resolveComponent (.../node_modules/@kosko/generate/src/generate.ts:59:28)</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    at Object.generate (.../node_modules/@kosko/generate/src/generate.ts:134:30)</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    at generateHandler (.../node_modules/@kosko/cli/src/commands/generate/index.ts:156:18)</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    at handler (.../node_modules/@kosko/cli/src/commands/generate/index.ts:200:20)</span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">    at Object.run (.../node_modules/@kosko/cli/src/index.ts:12:3)</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="loading-kubernetes-yaml">Loading Kubernetes YAML<a href="https://kosko.dev/blog/2020/11/22/kosko-1.0-released#loading-kubernetes-yaml" class="hash-link" aria-label="Direct link to Loading Kubernetes YAML" title="Direct link to Loading Kubernetes YAML">​</a></h2>
<p>If you have been using Kubernetes for a while, you may have a lot of existing Kubernetes YAML files just like me. Instead of migrating YAML into JavaScript, try use the new package <code>@kosko/yaml</code>.</p>
<p><code>@kosko/yaml</code> reads YAML files and transforms data into <a href="https://github.com/tommy351/kubernetes-models-ts" target="_blank" rel="noopener noreferrer">kubernetes-models</a> classes, so your manifests are validated against Kubernetes OpenAPI schema.</p>
<div class="language-js codeBlockContainer_ydF7 theme-code-block" style="--prism-background-color:#282c34;--prism-color:#ffffff"><div class="codeBlockContent_gSYR"><pre tabindex="0" class="prism-code language-js codeBlock_tSFE thin-scrollbar" style="background-color:#282c34;color:#ffffff"><code class="codeBlockLines_eXUB"><span class="token-line" style="color:#ffffff"><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#8dc891">{</span><span class="token plain"> loadFile </span><span class="token punctuation" style="color:#8dc891">}</span><span class="token plain"> </span><span class="token operator" style="color:#d7deea">=</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">require</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token string" style="color:#8dc891">"@kosko/yaml"</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#ffffff"><span class="token plain">module</span><span class="token punctuation" style="color:#8dc891">.</span><span class="token property-access">exports</span><span class="token plain"> </span><span class="token operator" style="color:#d7deea">=</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">loadFile</span><span class="token punctuation" style="color:#8dc891">(</span><span class="token string" style="color:#8dc891">"manifest.yaml"</span><span class="token punctuation" style="color:#8dc891">)</span><span class="token punctuation" style="color:#8dc891">;</span><br></span></code></pre><div class="buttonGroup_HMky"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_ljcn" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_Zyt5"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_NB8J"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>This package works better with "nested manifests", so please don't forget to upgrade to Kosko v1.0 first.</p>
<p>For more details, please check <a href="https://kosko.dev/docs/components/loading-kubernetes-yaml">here</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_zlB1" id="breaking-changes">Breaking Changes<a href="https://kosko.dev/blog/2020/11/22/kosko-1.0-released#breaking-changes" class="hash-link" aria-label="Direct link to Breaking Changes" title="Direct link to Breaking Changes">​</a></h2>
<ul>
<li>Drop support for Node.js 8.</li>
<li><code>@kosko/generate</code>
<ul>
<li>The type of <code>Manifest.index</code> and <code>ValidationError.index</code> is changed from <code>number</code> to <code>number[]</code>.</li>
<li>The type of <code>Manifest.data</code> is changed from <code>any</code> to <code>unknown</code>.</li>
</ul>
</li>
</ul>]]></content:encoded>
        </item>
    </channel>
</rss>