UNPKG

@snowplow/snowtype

Version:

A code generator CLI for faster and type-safe Snowplow tracking code

117 lines (93 loc) 42.9 kB
"use strict";var zn=Object.create;var ae=Object.defineProperty;var Bn=Object.getOwnPropertyDescriptor;var Jn=Object.getOwnPropertyNames;var Kn=Object.getPrototypeOf,qn=Object.prototype.hasOwnProperty;var Xn=(t,e,n,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of Jn(e))!qn.call(t,o)&&o!==n&&ae(t,o,{get:()=>e[o],enumerable:!(i=Bn(e,o))||i.enumerable});return t};var h=(t,e,n)=>(n=t!=null?zn(Kn(t)):{},Xn(e||!t||!t.__esModule?ae(n,"default",{value:t,enumerable:!0}):n,t));var Rn=h(require("process")),b=require("@commander-js/extra-typings");var O=require("@inquirer/prompts");var Yn={AuthError:"Authentication failed. Check if your API key and organization ID are correct.",ConfigAlreadyExists:"Snowtype config file already exists.",ConfigNotExists:"Snowtype config file does not exist in current directory. Start with running 'init'.",ConfigInvalid:"Snowtype config exists but it is invalid.",InternalError:"An internal error occured.",InvalidOption:"Invalid option provided.",MissingOptions:"Action called with no options.",WriteLockFile:"Failed writing lock file.",MissingLockFile:"Missing lockfile. You might need to run `snowtype generate` first.",GenerationFailed:"Something went wrong with code generation.",PatchingNotSupported:"Patching is only supported using a Snowtype config file in JSON format.",DevNotAllowed:"Code generation using schemas in DEV environment not allowed. Publish the schemas and retry.",AuthCredentialsMissing:"Required API key credentials not detected. Please refer to https://docs.snowplow.io/docs/collecting-data/code-generation/using-the-cli/#authenticating-with-the-console"},Zn="Please report a bug.",S=class extends Error{code;constructor(e,n=""){let i=Yn[e].concat(n);super(i),Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.code=e}},Q=class extends S{constructor(){super("GenerationFailed")}},B=class extends S{constructor(){super("ConfigAlreadyExists")}},tt=class extends S{constructor(){super("ConfigNotExists")}},et=class extends S{constructor(e){super("ConfigInvalid",e)}},nt=class extends S{constructor(e){super("InternalError",e.concat(Zn))}},R=class extends S{constructor(e,n){let i=`Value ${n} is an invalid ${e}.`;super("InvalidOption",i)}},it=class extends S{constructor(){super("MissingOptions")}},$=class extends S{constructor(){super("AuthError")}},ot=class extends S{constructor(){super("WriteLockFile")}},rt=class extends S{constructor(){super("MissingLockFile")}},at=class extends S{constructor(){super("PatchingNotSupported")}},st=class extends S{constructor(){super("DevNotAllowed")}},ct=class extends S{constructor(){super("AuthCredentialsMissing")}};var se=h(require("got"));async function ce({schema:t}){return(await(0,se.default)(`https://raw.githubusercontent.com/snowplow/iglu-central/master/schemas/${t.replace("iglu:","")}`)).body}var St=h(require("got"));var fe=require("js-sha256"),$t=h(require("assert"));var u=h(require("joi")),mt=require("@snowplow/snowtype-core");var Rt=h(require("assert"));var J="snowtype.config",pt=".js",ut=".ts",dt=".json",pe=Object.freeze([pt,ut,dt]),lt=".snowtype-lock.json",Ft="snowplow";var K={"google-tag-manager":[{value:"javascript-gtm",name:"JavaScript"}],"@snowplow/javascript-tracker":[{value:"javascript",name:"JavaScript"}],"@snowplow/browser-tracker":[{value:"javascript",name:"JavaScript"},{value:"typescript",name:"TypeScript"}],"@snowplow/node-tracker":[{value:"javascript",name:"JavaScript"},{value:"typescript",name:"TypeScript"}],"snowplow-android-tracker":[{value:"kotlin",name:"Kotlin"}],"snowplow-ios-tracker":[{value:"swift",name:"Swift"}],"snowplow-golang-tracker":[{value:"go",name:"Go"}],"@snowplow/react-native-tracker":[{value:"typescript",name:"TypeScript"}],"snowplow-flutter-tracker":[{value:"dart",name:"Dart"}],"snowplow-java-tracker":[{value:"java",name:"Java"}]},ue={commands:{generate:{instructions:!1,validations:!1,disallowDevSchemas:!1,deprecateOnlyOnProdAvailableUpdates:!1},update:{maximumBump:"major",regenerateOnUpdate:!1,showOnlyProdUpdates:!1},patch:{regenerateOnPatch:!1}}},de=["iglu:com.snowplowanalytics.snowplow/page_ping/jsonschema/1-0-0","iglu:com.snowplowanalytics.snowplow/link_click/jsonschema/1-0-1","iglu:com.snowplowanalytics.snowplow/page_view/jsonschema/1-0-0","iglu:com.snowplowanalytics.mobile/screen_view/jsonschema/1-0-0","iglu:com.snowplowanalytics.snowplow/button_click/jsonschema/1-0-0","iglu:com.snowplowanalytics.snowplow/application_background/jsonschema/1-0-0","iglu:com.snowplowanalytics.snowplow/application_foreground/jsonschema/1-0-0","iglu:com.snowplowanalytics.mobile/application_install/jsonschema/1-0-0","iglu:com.snowplowanalytics.mobile/screen_end/jsonschema/1-0-0","iglu:com.snowplowanalytics.snowplow/custom_event/jsonschema/1-0-0"],le="iglu:com.snowplowanalytics.snowplow.ecommerce";var gt=require("lodash");function ge(t){let e=t.split("-");(0,Rt.default)(e.length===3,"invalid SchemaVer"),(0,Rt.default)(e.filter(n=>isNaN(parseInt(n))).length===0,"invalid SchemaVer")}function j(t){t.options=(0,gt.merge)((0,gt.cloneDeep)(ue),t.options||{})}var me=new RegExp("^iglu:[a-zA-Z0-9-_.]+/[a-zA-Z0-9-_]+/[a-zA-Z0-9-_]+/[0-9]+-[0-9]+-[0-9]+$"),Qn=u.default.object().required().keys({tracker:u.default.string().required().valid(...mt.trackerTemplates),language:u.default.string().required().valid(...mt.languageIds),outpath:u.default.string().required(),organizationId:u.default.string().when("dataStructures",{is:u.default.array().min(1),then:u.default.required(),otherwise:u.default.optional()}).when("eventSpecificationIds",{is:u.default.array().min(1),then:u.default.required(),otherwise:u.default.optional()}).when("dataProductIds",{is:u.default.array().min(1),then:u.default.required(),otherwise:u.default.optional()}),igluCentralSchemas:u.default.array().optional().items(u.default.string().regex(me)),repositories:u.default.array().optional().items(u.default.string()),dataStructures:u.default.array().optional().items(u.default.string().regex(me)),eventSpecificationIds:u.default.array().optional().items(u.default.string()),dataProductIds:u.default.array().optional().items(u.default.string()),options:u.default.object().optional().keys({commands:u.default.object().optional().keys({generate:u.default.object().optional().keys({instructions:u.default.boolean().optional(),validations:u.default.boolean().optional(),disallowDevSchemas:u.default.boolean().optional(),deprecateOnlyOnProdAvailableUpdates:u.default.boolean().optional()}),patch:u.default.object().optional().keys({regenerateOnPatch:u.default.boolean().optional()}),update:u.default.object().optional().keys({maximumBump:u.default.string().valid("major","minor","patch").optional(),regenerateOnUpdate:u.default.boolean().optional(),showOnlyProdUpdates:u.default.boolean().optional()})})})}),M=t=>{let e=Qn.validate(t,{abortEarly:!1,convert:!1});if(e.error)throw new et(e.error.annotate());return t};function ti(t){let e=fe.sha256.create();return e.update(t),e.hex()}function ft(t,e){let{vendor:n,name:i,format:o}=E(t);return ti(`${e}-${n}-${i}-${o}`)}function E(t){let e=t.replace("iglu:",""),[n,i,o,r]=e.split("/");return(0,$t.default)(typeof n=="string"&&typeof i=="string"&&typeof o=="string"&&typeof r=="string",`invalid iglu uri ${t}`),ge(r),{vendor:n,name:i,format:o,version:r}}function he(t,{vendor:e,name:n,format:i,version:o}){let r=t.replace("iglu:",""),[a,s,p,c]=r.split("/");return`iglu:${e||a}/${n||s}/${i||p}/${o||c}`}function Se(t){return t.some(e=>e.eventSchema.isEcomTemplateSchema)}function q(t){let[e,n,i]=t.split("-").map(o=>parseInt(o));return{model:e,revision:n,addition:i}}function ve(t,e,n=0){if(t===e&&n!==0)return"patch";let{model:i,revision:o,addition:r}=q(t),{model:a,revision:s,addition:p}=q(e);if(i!==a)return"major";if(o!==s)return"minor";if(r!==p)return"patch";(0,$t.default)(!1,"SchemaVer checking went wrong")}var ht=class extends Error{response;constructor(e){let n=e.response?.statusCode||0,{method:i,url:o}=e.options,r=e.response?.body||e.message,a=[[n,i,o].filter(Boolean).join(" "),r].filter(Boolean).join(` `);super(a),this.response={statusCode:n,body:r}}};function ye(t){return!!Object.hasOwn(t||{},"response")}var N="0.12.3";var we=h(require("p-limit")),P=class{apiKeyId;apiKey;organizationId;accessToken;pLimit;apiUrl=process.env.SNOWPLOW_CONSOLE_API_URL||"https://console.snowplowanalytics.com/api/msc";constructor({apiKeyId:e,apiKey:n,organizationId:i,requestLimit:o=20}){this.apiKeyId=e,this.apiKey=n,this.organizationId=i,this.pLimit=(0,we.default)(o)}async fetchAccessToken(){if(this.accessToken)return this.accessToken;let e=`${this.apiUrl}/v1/organizations/${this.organizationId}/credentials/v3/token`,{accessToken:n}=await(0,St.default)(e,{headers:{"X-API-Key-Id":this.apiKeyId,"X-API-Key":this.apiKey,"X-Snowtype":N}}).json();return this.accessToken=n,n}async fetchResource(e){return this.pLimit(async()=>{try{let n=await this.fetchAccessToken();return await(0,St.default)(e,{headers:{Authorization:"Bearer "+n,"X-Snowtype":N}}).json()}catch(n){throw ye(n)?new ht(n):n}})}fetchSchemaVersion({schema:e,env:n="DEV"}){let{version:i}=E(e),o=ft(e,this.organizationId),r=`${this.apiUrl}/v1/organizations/${this.organizationId}/data-structures/v1/${o}/versions/${i}?env=${n}`;return this.fetchResource(r)}fetchSchemaHash({schema:e}){let n=ft(e,this.organizationId),i=`${this.apiUrl}/v1/organizations/${this.organizationId}/data-structures/v1/${n}`;return this.fetchResource(i)}async fetchDeployments({schema:e,deploymentEnv:n}){let i=ft(e,this.organizationId),o=25,r=[],a=!0,s=0,p=c=>`${this.apiUrl}/v1/organizations/${this.organizationId}/data-structures/v1/${i}/deployments?size=${o}&from=${c}${n?`&env=${n}`:""}`;for(;a;){let c=await this.fetchResource(p(s));s+=o,r=r.concat(c),c.length===0&&(a=!1)}return r}fetchEventSpecification({eventSpecificationId:e}){let n=`${this.apiUrl}/v1/organizations/${this.organizationId}/event-specs/v1/${e}`;return this.fetchResource(n)}async fetchImageVariant({imageId:e,imageVariant:n}){let i=`${this.apiUrl}/v1/organizations/${this.organizationId}/images/v1/${e}/${n}`,o=await this.fetchAccessToken();return(0,St.default)(i,{headers:{Authorization:"Bearer "+o,"X-Snowtype":N}})}fetchDataProduct({dataProductId:e}){let n=`${this.apiUrl}/v1/organizations/${this.organizationId}/data-products/v2/${e}`;return this.fetchResource(n)}async authenticate(){try{return await this.fetchAccessToken(),!0}catch{return!1}}};var x=require("path"),y=require("fs");var Ut=h(require("util")),_t=require("tsx/cjs/api");var D=(()=>{let t="json";return{setFormat:i=>t=i,getFormat:()=>t}})();var xt=require("@snowplow/snowtype-core");var yt=require("fs");var vt=h(require("assert"));var Ie=require("semver");function Ee(t,e,n){try{let i=(0,yt.readFileSync)(n,{encoding:"utf-8"}),o=JSON.parse(i);return o[t].some(a=>a===e)||o[t].push(e),(0,yt.writeFileSync)(n,Nt(o)),!0}catch(i){return console.error(i),!1}}var ei=(t,e)=>{let{model:n,revision:i,addition:o}=q(t.version),{model:r,revision:a,addition:s}=q(e.version);return(0,vt.default)(n!==void 0&&i!==void 0&&o!==void 0&&r!==void 0&&a!==void 0&&s!==void 0,`Invalid version number comparing (${t}, ${e})`),n>r?1:n<r?-1:i>a?1:i<a?-1:o>s?1:o<s?-1:t.patchLevel>e.patchLevel&&t.contentHash!==e.contentHash?1:e.patchLevel>t.patchLevel&&t.contentHash!==e.contentHash||t.env==="DEV"&&e.env==="PROD"?-1:t.env==="PROD"&&e.env==="DEV"?1:0};async function xe(t,e,n,i){return(await Promise.all(e.map(async r=>{let{version:a}=E(r),s=await t.fetchDeployments({schema:r,...i&&{deploymentEnv:"PROD"}}),p=ni(s,a,n);p.sort(ei);let c=p.pop();if(!c)return null;let d={previous:r,next:he(r,{version:c.version}),nextEnv:c.env};return c.version!==a?{...d,nextReason:"version"}:c.patchLevel>0&&c.env==="DEV"?{...d,nextReason:"patch"}:null}))).flatMap(r=>r===null?[]:[r])}async function jt(t,e){return Promise.all(e.map(async n=>{try{await t.fetchSchemaVersion({schema:n,env:"PROD"})}catch(i){if(i.response?.statusCode===404)try{return await t.fetchSchemaVersion({schema:n,env:"DEV"}),n}catch(o){if(o.response?.statusCode!==404)throw o}}return null})).then(n=>n.flatMap(i=>i!==null?[i]:[]))}async function Pe(t,e,n){let{eventSpecifications:i}=n,o={};return await Promise.all(e.map(async r=>{let a=i[r];if(!a)return r;let s=(await t.fetchEventSpecification({eventSpecificationId:r})).data[0];(0,vt.default)(!!s,`failed to fetch event spec ${r}`),(0,vt.default)(!!s.version,`event spec with no version ${r}`);let p=[s.event?.source,...s.entities?.tracked?.map(d=>d.source)||[]].flatMap(d=>typeof d=="string"?[d]:[]),c=await jt(t,p);return(s.version||0)>a&&(o[r]={previous:a,next:s.version,devOnlySchema:c}),r})),o}function ni(t,e,n){return t.filter(i=>Mt(e,i.version)!==1).filter(i=>i.version!==e||i.patchLevel).map(i=>({...i,updateType:ve(i.version,e,i.patchLevel)})).filter(ii(n))}function ii(t){return({updateType:e})=>{switch(t){case"major":return!0;case"minor":return e==="patch"||e==="minor";case"patch":return e==="patch"}}}function Mt(t,e){let n=t.replaceAll("-","."),i=e.replaceAll("-",".");return(0,Ie.compare)(n,i)}var Ae=require("cli-spinner"),v=h(require("chalk"));function Oe(){let t=new Ae.Spinner;return t.setSpinnerString(18),t}var oi="https://snowplow.io",ri="https://docs.snowplow.io/docs/collecting-data/code-generation/",X={SUCCESS:"\u2714",LOG:"\u2139",DEBUG:"\u27A4",ERROR:"\u2717",WARN:"\u26A0"},be={LINK:"#9911BB",OPTION:"#9911DD"};function Ce(t){return v.default.hex(be.LINK).bold(t)}function k(t){return v.default.hex(be.OPTION).italic(t)}function wt(t,e){switch(t){case"h1":return v.default.bold.underline(e);default:return v.default.bold(e)}}function Te(){return` ${wt("h1","CLI Help")} For more information visit the Snowplow website ${Ce(oi)} For details see the CLI documentation ${Ce(ri)} ${wt("h2","How to get started")} 1. Use ${v.default.cyanBright("snowtype init")} to initialize the setup. 2. Use ${v.default.cyanBright("snowtype patch")} to add a Data Structure or Event Specification. 3. Use ${v.default.cyanBright("snowtype generate")} to generate tracking code. ${wt("h2","Available commands")} To learn more about each CLI command, use the ${k("--help")} option, for example, ${k("snowtype init --help")}. ${k("snowtype init")} Initialize the setup of Snowtype code generation in a project. Creates the \`snowtype.config.json\` file. ${k("snowtype patch")} Adds new Data Structures and Event Specifications in the \`snowtype.config.json\` file. ${k("snowtype generate")} Generates tracking code based on configuration on the \`snowtype.config.json\` file. ${k("snowtype update")} Checks for latest version updates in Data Structures and Event Specifications. ${wt("h2","Debug")} Use the ${k("-v")} to output verbose logs `}function De(t){let e=`${X.SUCCESS}: `;return v.default.cyanBright(e)+t}function It(t){let e=`${X.WARN} Warning: `;return v.default.hex("#FFA500")(e)+t}function ke(t){let e=`${X.LOG} ${t}`;return v.default.yellowBright(e)}function Le(t){let e=`${X.DEBUG} Debug: `;return v.default.magenta(e)+t}function Fe(t){let e=`${X.ERROR} Error: `;return v.default.redBright(e)+t}function Re(t,e){let n=`- ${t}`,i=`+ ${e}`;return` ${v.default.magenta(n)} ${v.default.cyanBright(i)} `}var Ve=h(require("mime-types"));var $e=t=>{let e={outdatedDsWarnings:[],hiddenDsWarnings:[],metrics:[]};return t.reduce((n,i)=>ai({currentMetadata:n,eventSpecificationId:i.eventSpecification.id,newMetadata:i.metadata||e}),{})};function ai({currentMetadata:t,eventSpecificationId:e,newMetadata:n}){let i=(o,r)=>o.id>r.id?1:-1;return{...t,[e]:{hiddenDsWarnings:n.hiddenDsWarnings.sort(i).map(o=>({sources:o.sources})),outdatedDsWarnings:n.outdatedDsWarnings.sort(i).map(o=>({sources:o.sources}))}}}var je=t=>(e,n)=>{si(e,n||"").forEach(t.warn)};function si(t,e){let n=ci(t.outdatedDsWarnings,e),i=pi(t.hiddenDsWarnings,e);return n.concat(i)}function ci(t,e){return t.reduce((n,i)=>{let o=i.sources.map(r=>[`Source: ${r.source}`,`Latest Version: ${r.latestVersion}`].join(` `));return[...n,`${["Outdated Data Structures detected:",`Data Product Id: ${e}`,`Event Specification Id: ${i.id}`,...o].join(` `)}`]},[])}function pi(t,e){return t.reduce((n,i)=>{let o=i.sources.map(r=>`Source: ${r.source}`).join(` `);return[...n,`${["Hidden Data Structures detected:",`Data Product Id: ${e}`,`Event Specification Id: ${i.id}`,o].join(` `)}`]},[])}async function Me(t,e){let n=di(t),i=await Promise.all(n.map(async r=>({schema:r,deployments:await e.fetchDeployments({schema:r,deploymentEnv:"PROD"})}))),o=ui(i);return li(t,o)}var ui=t=>t.flatMap(({schema:e,deployments:n})=>{let{version:i}=E(e);return n.filter(r=>Mt(i,r.version)===-1).length===0?[]:[e]}),di=t=>V(Object.entries(t).filter(([,e])=>e.outdatedDsWarnings.length!==0).flatMap(([,e])=>e.outdatedDsWarnings.flatMap(n=>n.sources.map(i=>i.source)))),li=(t,e)=>Object.keys(t).reduce((n,i)=>{let o=t[i];if(o){let r=o.outdatedDsWarnings.flatMap(({sources:a})=>{let s=a.filter(p=>e.includes(p.source));return s.length>0?[{sources:s}]:[]});n[i]={...o,outdatedDsWarnings:r}}return n},{});async function Et(t,e){return(await Promise.all(e.map(i=>t.fetchDataProduct({dataProductId:i})))).flatMap(({data:[i]})=>i?i.eventSpecs:[]).map(i=>i.id)}function mi(t){let{original:e}=t,[n,i]=e.split("/").reverse();return{imageVariant:n,imageId:i}}async function We(t,e){let n=[];if(!(e&&e.length))return[];for(let i of e){let{description:o,appIds:r,url:a,variantUrls:s}=i,p={description:o,appIds:r,url:a};if(s){let{imageVariant:c,imageId:d}=mi(s),f=await t.fetchImageVariant({imageId:d,imageVariant:c});p.imageBuffer=f.rawBody,p.imageExtension=Ve.default.extension(f.headers["content-type"])||""}n.push(p)}return n}async function Ue(t,e,n){return{eventSpecificationsWithId:(await Promise.all(e.map(async o=>{let r=await t.fetchEventSpecification({eventSpecificationId:o}),a=r.data[0];if(typeof a>"u"||typeof a.event>"u")return[];!!r.metadata&&je(n)(r.metadata,a.dataProductId);let p=Vt(a.event.source);p&&n.warn("Currently code will not be generated for `Standard` events. Skipping...");let c=a.triggers,d=a.name,f=a.version,w=a.sourceApplications||[],m=a.event.schema,l=p?fi(a.event.source):await Ne(t,a,a.event.source),g=a.entities?.tracked||[],H=await Promise.all(g.map(async({source:I,schema:z})=>({original:await Ne(t,a,I),propertyRule:z})));return{eventSpecification:{name:d||"",id:o,dataProductId:a.dataProductId||"",dataProductName:"",dataProductDomain:""},version:f||0,eventSchema:l,entitiesSchemas:H,entities:g,triggers:c,propertyRules:m,sourceApplicationIds:w,metadata:r.metadata}}))).flat()}}async function _e(t){return await Promise.all(t.map(async n=>JSON.parse(await ce({schema:n}))))}async function Ge(t,e){return await Promise.all(e.map(i=>t.fetchSchemaVersion({schema:i})))}async function He(t,e){let n=e.flatMap(({eventSpecification:{dataProductId:r}})=>r?[r]:[]);return(await Promise.all(n.map(r=>t.fetchDataProduct({dataProductId:r})))).map(r=>r.data[0]&&{...r.data[0],sourceApplications:r.includes.sourceApplications||[]}).filter(gi)}function ze(t,e){let n=t.reduce((o,r)=>(o[r.id]={...r},o),{});return e.map(o=>{let r=n[o.eventSpecification.dataProductId],a=o.sourceApplicationIds.flatMap(s=>r?.sourceApplications.find(p=>p.id===s)||[]);return{...o,eventSpecification:{...o.eventSpecification,dataProductName:r?.name||"",dataProductDomain:r?.domain||""},sourceApplications:a}})}function gi(t){return!!t}async function Ne(t,e,n){let i=e.event?.schema?.properties?.type?.enum?.[0];return n.match(le)?{self:E(n),isEcomTemplateSchema:i}:await t.fetchSchemaVersion({schema:n})}function Be(t){return t.reduce((n,i)=>{let o=i.eventSpecification.id;return i.entities.forEach(({source:r,minCardinality:a,maxCardinality:s})=>{if(typeof a<"u"||typeof s<"u"){let p={minCardinality:a,maxCardinality:s};n[o]=n[o]||{},n[o][r]=p}}),n},{})}function fi(t){return{self:{...E(t)}}}var hi="SNOWPLOW_CONSOLE_API_KEY_ID",Si="SNOWPLOW_CONSOLE_API_KEY";function qe(t){return t.length!==0}function Nt(t){return JSON.stringify(t,null,2)}function Xe(t){let e={organizationId:t.organizationId,tracker:t.tracker,language:t.language,outpath:t.outpath};return Object.assign({igluCentralSchemas:[],dataStructures:[],repositories:[],eventSpecificationIds:[],dataProductIds:[]},e)}function vi(t){switch(t){case"typescript":return`${J}${ut}`;case"javascript":return`${J}${pt}`;case"json":return`${J}${dt}`;default:return""}}var Je=t=>(0,y.existsSync)(t)&&!(0,y.lstatSync)(t).isDirectory(),yi=t=>J+t,wi=t=>({isTS:t.endsWith(ut),isJSON:t.endsWith(dt),isJS:t.endsWith(pt)}),Wt=t=>({configDir:(0,x.dirname)(t),configPath:t,...wi(t)});function C(t){let e=(0,x.isAbsolute)(t)?t:(0,x.resolve)(process.cwd(),t);if(Je(e))return Wt(e);if(!(0,y.existsSync)(e))throw new Error(`Can't find a root directory while resolving a config file path. Provided path to resolve: ${t} cwd: ${process.cwd()}`);let[n]=pe.map(i=>(0,x.resolve)(e,yi(i))).filter(Je);return Wt(typeof n!="string"?e:n)}function Pt(t,e){let n=D.getFormat(),i=vi(n),o=(0,x.resolve)(e,i),r=`const config = ${Ut.default.inspect(t,!1,null)} `,a='import { SnowtypeConfig } from "@snowplow/snowtype/types";',s=`const config: SnowtypeConfig = ${Ut.default.inspect(t,!1,null)} `,p="module.exports = config;",c="export default config;";return n==="json"?(0,y.writeFileSync)(o,Nt(t)):(0,y.writeFileSync)(o,(n==="typescript"?[a,s,c]:[r,p]).join(` `))}function Gt(t){let e=(0,y.statSync)(t,{throwIfNoEntry:!1});return e===void 0?!1:e.isFile()}function Ht(t){return(0,y.readFileSync)(t,{encoding:"utf-8"})}var Ii=async t=>(await(0,_t.require)(t,__filename)).default;async function W(t){let{configPath:e,isJS:n,isJSON:i,isTS:o}=C(t),r;return o?(r=await Ii(e),D.setFormat("typescript")):n?(r=(await import(e)).default,D.setFormat("javascript")):i&&(r=JSON.parse(Ht(e)),D.setFormat("json")),typeof r=="function"&&(r=await r()),r}function Ye(t){return JSON.parse(Ht(t))}async function Ze(t,e){t.debug("Checking for existing configuration.."),await zt(!0,e),t.success("Valid configuration found")}async function zt(t,e){let{configPath:n,isJS:i,isJSON:o,isTS:r}=C(e),a=o===!0||r===!0||i===!0,s=r===!1&&i===!1&&o===!1,p;if(r?p=(await(0,_t.require)(n,__filename)).default:i?p=(await import(n)).default:o&&(p=JSON.parse(Ht(n))),typeof p=="function"&&(p=await p()),t){if(s)throw new tt;M(p)}else if(a)try{throw M(p),new B}catch(c){if(c instanceof B)throw c}}function Qe(t){return{javascript:".js","javascript-gtm":".js",typescript:".ts",kotlin:".kt",swift:".swift",go:".go",dart:".dart",java:".java"}[t]||""}function tn(t,e){let n={eventSpecifications:{}};t.forEach(o=>{n.eventSpecifications[o.eventSpecification.id]=o.version});let i=(0,x.resolve)(e,lt);try{(0,y.writeFileSync)(i,JSON.stringify(n,null,2))}catch{throw new ot}}function en(t,e,n){let i=Object.entries(t);i.length>0&&n.success("Available Event Specification Updates"),i.forEach(([o,r])=>{let a=`${o}: version ${r.previous}`,s=`${o}: version ${r.next}`;n.diff(a,s),r.devOnlySchema.length>0&&(n.warn("This Event Specification uses schema that are not in production."),n.warn(r.devOnlySchema.join(" ")))}),e.length>0&&n.success("Available Data Structures Updates"),e.forEach(o=>{let r=`${o.previous}`,a=`${o.next}`;if(n.diff(r,a),o.nextReason==="patch"&&n.warn("The most recent version of this schema has been patched. Possible update required."),o.nextEnv==="DEV"){let s=o.next.split("/").pop();n.warn(`This data structure version (${s}) is not in production.`)}})}function nn(t){let e=t.optsWithGlobals();return{...e,apiKeyId:e.apiKeyId||process.env[hi],apiKey:e.apiKey||process.env[Si]}}function U(t){return!!(Array.isArray(t)&&!t.length)}function V(t){return[...new Set(t)]}function on(t){let e=V(t);return e.sort(),e}function Ei(t){return t.flatMap(e=>{let n=(0,xt.joinIgluSchemaUrlParts)(e.eventSchema.self),i=e.entities.map(o=>o.source);return[n,...i]})}async function rn(t,e,n,i){let o=t.map(s=>(0,xt.joinIgluSchemaUrlParts)(s.self)),r=Ei(e),a=await jt(n,V([...o,...r]));if(a.length>0&&(console.log(` `,It(`Generating code using schemas in DEV environment, tracking against those will result in failed events. Schemas in DEV: `+a.join(` `)),` `),i))throw new st}function Vt(t){return de.includes(t)}function Ke({self:t}){let e=(0,xt.joinIgluSchemaUrlParts)(t);return Vt(e)}function an(t){return{standardEventSpecs:t.filter(e=>Ke(e.eventSchema)),customEventSpecs:t.filter(e=>!Ke(e.eventSchema))}}function sn(t,e,n){if(typeof t=="string"&&typeof e=="string"&&t&&e)return{apiKeyId:t,apiKey:e};throw n.error(new ct),new Error}var xi=["javascript","json","typescript"];function cn(t){return t in K}function pn(t,e){let n=K[t];return Array.isArray(n)?n.map(o=>o.value).includes(e):!1}function un(t){return xi.includes(t)}function dn(){return{withVerbosity:e=>({success:i=>{console.log(De(i))},warn:i=>{console.log(It(i))},log:i=>{console.log(ke(i))},diff:(i,o)=>{console.log(Re(i,o))},debug:i=>{e===!0&&console.log(Le(JSON.stringify(i)))},error:i=>{console.log(Fe(i.message)),e===!0&&console.log(i)}})}}function A(t,e){return async(n,i)=>{let o=nn(i),r=dn(),a=Oe(),s=r.withVerbosity(o.verbose),{apiKeyId:p,apiKey:c}=sn(o.apiKeyId,o.apiKey,s);if(e!=="init")try{let d=n.config||process.cwd();await Ze(s,d)}catch(d){ln(d,s,a)}return t({apiKeyId:p,apiKey:c},s,a,n).then(()=>mn(a)).catch(d=>{ln(d,s,a)})}}function ln(t,e,n){throw mn(n),e.error(t),t}function mn(t){t.isSpinning()===!0&&t.stop(!0)}var Pi={type:"password",message:"Enter your Snowplow organization ID:",mask:!0,validate:qe},Ci={type:"select",message:"Select the Snowplow Tracker to use:",choices:[{value:"google-tag-manager",name:"Google Tag Manager"},{value:"@snowplow/javascript-tracker",name:"JavaScript Tracker"},{value:"@snowplow/browser-tracker",name:"Browser Tracker"},{value:"@snowplow/node-tracker",name:"Node Tracker"},{value:"snowplow-android-tracker",name:"Android Tracker"},{value:"snowplow-ios-tracker",name:"iOS Tracker"},{value:"snowplow-golang-tracker",name:"Golang Tracker"},{value:"@snowplow/react-native-tracker",name:"React Native Tracker"},{value:"snowplow-flutter-tracker",name:"Flutter Tracker"},{value:"snowplow-java-tracker",name:"Java Tracker"}]},Ai={type:"select",message:"Select the format to use:",choices:[{value:"javascript",name:"JavaScript"},{value:"typescript",name:"TypeScript"},{value:"json",name:"JSON"}]},Oi={type:"input",message:"Enter the directory for Snowtype output:",default:"./snowtype"},bi=t=>({type:"select",message:"Select the language to use:",choices:t});async function Ti(t,e){e.debug("Checking for existing configuration file.."),await zt(!1,process.cwd());let n=t.organizationId||await(0,O.password)(Pi),i=t.tracker||await(0,O.select)(Ci);if(!cn(i))throw new R("tracker",i);let o=K[i],r;if(o.length===1){let p=o[0];if(typeof p>"u")throw new nt("Missing language entry.");r=p.value}else r=t.language||await(0,O.select)(bi(o));if(!pn(i,r))throw new R("language",r);let a=await(0,O.select)(Ai);if(!un(a))throw new R("format",a);D.setFormat(a);let s=t.outpath||await(0,O.input)(Oi);return e.debug("Assembling initialization options.."),{organizationId:n,tracker:i,language:r,format:a,outpath:s}}async function Di(t,e,n,i){let o=await Ti(i,e);n.setSpinnerTitle("Initialising..."),n.isSpinning()===!1&&n.start(),e.debug("Creating configuration with options: ".concat(JSON.stringify(o)));let r=Xe(o);if(M(r),!await new P({...t,organizationId:r.organizationId}).authenticate())throw new $;e.success("Authentication succeeded"),Pt(r,process.cwd()),e.success("Configuration created")}var Bt=A(Di,"init");var Fn=require("path");var Ln=require("@snowplow/snowtype-core");var Ct=require("path"),gn=require("mkdirp"),Kt=require("fs"),At=require("@snowplow/snowtype-core");var ki="instructions.md",fn="assets";async function hn(t,e,n,i,o){gn.mkdirp.sync((0,Ct.resolve)(i,fn));let r=[],a=$i(e,n,o),s=[];await Promise.all(e.map(async c=>{let d={triggers:await We(t,c.triggers),instructionsHeading:Jt(c.eventSpecification.name)};s.push(Jt(c.eventSpecification.name));let f=Mi(c.propertyRules),w=Ni(c.entities);Fi(c.eventSpecification.id,d,i),r.push(Li({eventStructure:c.eventSchema.self,entitiesStructures:c.entitiesSchemas?.map(m=>m.original.self)||[],name:c.eventSpecification.name,id:c.eventSpecification.id,dataProductId:c.eventSpecification.dataProductId,version:c.version,triggerInstructions:d.triggers,linkToCode:a[c.eventSpecification.id],formattedPropertyRules:f,formattedCardinalityRules:w,organizationId:t.organizationId,sourceApplications:c.sourceApplications,dataProductDomain:c.eventSpecification?.dataProductDomain||""}))}));let p=` # Implementation instructions _A guide on how to implement tracking for the generated Event Specifications._ **Table of contents:** ${s.map(c=>`- [${c.instructionsTitle}](#${c.instructionsLink})`).join(` `)} ${r.join(` `)} `;(0,Kt.writeFileSync)((0,Ct.resolve)(i,ki),p,"utf-8")}function Li({eventStructure:t,entitiesStructures:e,name:n,id:i,dataProductId:o,version:r,triggerInstructions:a,linkToCode:s,formattedPropertyRules:p,formattedCardinalityRules:c,organizationId:d,sourceApplications:f,dataProductDomain:w}){let m="_N/A_";return` ## [${Jt(n).instructionsTitle}](${Ri(d,o,i)}) | | | | ----------- | ----------- | | **Id** | ${i} | | **Version** | ${r} | | **Data Product Id** | ${o} | | **Source Application/s** | ${f.length?f.map(l=>l.name).join(", "):"None selected"} | | **Event Data Structure** | ${t.name}/${t.version} | | **Entity Data Structures** | ${e.map(l=>`${l.name}/${l.version}`).sort().join(", ")} | | **Code** | ${s} | | **Data Product Domain** | ${w.length>0?w:m} | ${p.length>0?`### Implementation Instructions for ${t.name} event properties #### Property Rules | Name | Required | Description | Exact value(s) expected | | ----------- | ----------- | ----------- | ----------- | ${p.map(l=>Object.values(l).join(" | ")).join(` `)} `:""} ${c.length>0?` #### Entity Cardinality Rules | Name | Required | Number of entities | | ----------- | ----------- | ----------- | ${c.map(l=>Object.values(l).join(" | ")).join(` `)} `:""} ${a.map((l,g,H)=>` ### Trigger ${H.length!==1?g+1:""} #### Screenshot ${l.imageBuffer?`[<img src="./assets/${i}_${g}.${l.imageExtension}" width="550"/>](./assets/${i}_${g}.${l.imageExtension})`:m} #### In which application(s) does this trigger apply? ${l.appIds&&l.appIds.length?l.appIds.map(I=>"`"+I+"` "):m} #### The URL of the page on which this event specification triggers: ${l.url||m} #### Notes ${l.description||m} `).join("")}`}function Fi(t,e,n){e.triggers.forEach((i,o)=>{i.imageBuffer&&(0,Kt.writeFileSync)((0,Ct.resolve)(n,fn,t+"_"+o+"."+i.imageExtension),i.imageBuffer,"binary")})}function Ri(t,e,n){return`https://console.snowplowanalytics.com/${t}/data-products/${e}/event-specifications/${n}`}function $i(t,e,n){let i=t.reduce((o,{eventSpecification:{id:r}})=>(o[r]="",o),{});return Object.keys(i).forEach(o=>{let r=e.findIndex(a=>a.match((0,At.createEventSpecificationInstructionsIdentifier)(o)));i[o]=r!==-1?`[Link](./${n+"#L"+r})`:"N/A"}),i}function Jt(t){let e=t;return{instructionsTitle:e,instructionsLink:ji(e)}}function ji(t){return t.toLowerCase().replace(/[^a-z\d\s-]/g," ").replace(/\s+/g," ").trim().replace(/-{2,}|\s/g,"-")}function Mi(t){return t?Object.entries(t.properties||{}).map(e=>{let[n,i]=e,o=t.required?.includes(n)?"\u2705":"\u274C",r=i.description||"-",a=i.enum?i.enum.map(s=>`\`${s}\``).join(" or "):"-";return{name:n,isRequired:o,description:r,expectedValues:a}}):[]}function Ni(t){return t?t.map(({source:e,minCardinality:n,maxCardinality:i})=>{let{name:o}=(0,At.splitIgluSchemaUrlParts)(e),r=typeof n<"u"&&n>0?"\u2705":"\u274C",a=Vi(n,i);return{name:o,isRequired:r,formattedCardinalityValues:a}}):[]}function Vi(t,e){return typeof t>"u"?"`any`":typeof e<"u"?t===e?`Exactly \`${t}\``:`Between \`${t}\` and \`${e}\``:`At least \`${t}\``}var vn=require("fs"),yn=require("path"),wn=h(require("util"));function In(t,e,n,i){let o=e==="typescript"?"ts":"js";(0,vn.writeFileSync)((0,yn.resolve)(t,`validations.${o}`),`${o==="ts"?` import { AnySchema } from "ajv"; export type CardinalityRule = { minCardinality?: number; maxCardinality?: number }; type IgluUrl = string; type EventSpecificationId = string; `:""} export const entityRules${o==="ts"?": Record<EventSpecificationId, Record<IgluUrl, CardinalityRule>>":""} = ${Sn(i)} export const schemasObject${o==="ts"?": Record<IgluUrl | EventSpecificationId, AnySchema | Record<IgluUrl, AnySchema>>":""} = ${Sn(n)}`,"utf-8")}function Sn(t){return wn.default.inspect(t,{showHidden:!1,depth:null,maxArrayLength:null})}function qt(t){return Object.values(t).some(e=>Wi(e)?Ui(e):qt(e))}function Wi(t){return typeof t=="object"&&t!==null&&Object.hasOwn(t,"$schema")}function Ui(t){return t.properties?Object.values(t.properties).some(e=>Object.hasOwn(e||{},"pattern")):!1}function En(t,e){let n=Gi(t);_i(n,e)}function _i(t,e){Object.entries(t).map(([n,i])=>e.warn(`Event Specification ${n} includes entities that are also present in it's application context: ${i.join(", ")}`))}function Gi(t){let e={};return t.forEach(n=>{let i=n.entities.map(r=>r.source),o=n.sourceApplications.flatMap(r=>[...r.entities.enriched.map(a=>a.source),...r.entities.tracked.map(a=>a.source)]);i.forEach(r=>{o.includes(r)&&(e[n.eventSpecification.id]?e[n.eventSpecification.id]?.push(r):e[n.eventSpecification.id]=[r])})}),e}var Ot=h(require("fs/promises")),bt=h(require("path")),xn=require("yaml");async function Pn(t,e=[]){let n=[];for(let i of e){let o=bt.default.resolve(t,i),r=await Cn(o),a=await Hi(r);n.push(...a)}return n}async function Hi(t){let e=[];for(let n of t){let{isJson:i}=An(n),o=await Ot.default.readFile(n,{encoding:"utf-8"}),r=i?JSON.parse(o):(0,xn.parse)(o);zi(r)&&e.push(r.data)}return e}async function Cn(t,e=[]){let n=await Ot.default.readdir(t);for(let i of n){let o=bt.default.join(t,i),r=await Ot.default.stat(o),{isJson:a,isYaml:s}=An(i);r.isDirectory()?e=await Cn(o,e):(a||s)&&e.push(o)}return e}function zi(t){return typeof t=="object"&&t!==null&&"apiVersion"in t&&typeof t.apiVersion=="string"&&"resourceType"in t&&t.resourceType==="data-structure"}function An(t){let e=bt.default.extname(t);return e.match(/\.yml|\.yaml/)?{isYaml:!0,isJson:!1}:e.match(".json")?{isYaml:!1,isJson:!0}:{isYaml:!1,isJson:!1}}var _=require("path"),Xt=require("fs"),Yt=require("mkdirp"),On=h(require("fs-extra"));function bn({codeLines:t,outFilePath:e,language:n}){if(n==="java"){let i="// SNOWTYPE START: ",o="// SNOWTYPE END: ",r=(0,_.resolve)((0,_.dirname)(e),"com","snowplowanalytics","snowplow","snowtype");Yt.mkdirp.sync(r);let a="",s=!1,p="";for(let c of t)c===o+a&&((0,Xt.writeFileSync)((0,_.resolve)(r,a),p),p="",s=!1),s&&(p+=c+` `),c.startsWith(i)&&(a=c.slice(i.length),s=!0)}else{let i=t.join(` `);(0,Xt.writeFileSync)(e,i)}}function Tn(t){On.default.removeSync((0,_.resolve)(t)),Yt.mkdirp.sync(t)}var Zt=require("path");var Dn=require("path"),Tt=require("fs-extra"),G=2e4,Bi=({code:t,codeMinified:e})=>t.length>G&&e.length<=G?`Warning: The content exceeds the GTM limit of ${G} characters. Please use the minified version.`:e.length>G&&e.length>G?`Warning: The content exceeds the GTM limit of ${G} characters.`:"";async function kn({defaultFileName:t,outDir:e,codeLines:n}){let i=(0,Dn.resolve)(e,t+".minified.js"),o=n.join(` `),{minify:r}=await import("terser"),a=await r(o,{mangle:!1,ecma:5});a.code?(console.warn(Bi({code:o,codeMinified:a.code})),await(0,Tt.remove)(i),await(0,Tt.writeFile)(i,a.code)):console.error("Minification failed: Terser did not generate any code.")}async function Ji(t){let{config:e,...n}=t,i=await W(e||process.cwd());return j(i),i.options.commands.generate={...i.options.commands.generate,...n},i}async function Y(t,e,n,i){let{dataProductIds:o,dataStructures:r,igluCentralSchemas:a,eventSpecificationIds:s,repositories:p,language:c,tracker:d,outpath:f,organizationId:w,options:{commands:{generate:m}}}=await Ji(i),{configDir:l}=C(i.config||process.cwd());n.setSpinnerTitle("Generating..."),n.isSpinning()===!1&&n.start(),U(r)&&U(a)&&U(s)&&U(o)&&U(p)&&e.warn("Data Structures, Schemas and Event Specifications are empty.");let g=new P({...t,organizationId:w});if(!await g.authenticate())throw new $;let I=await Et(g,o),z=on([...I,...s]),{eventSpecificationsWithId:L}=await Ue(g,z,e),kt=$e(L);m.deprecateOnlyOnProdAvailableUpdates&&(kt=await Me(kt,g));let jn=await He(g,L),Z=ze(jn,L);En(Z,e);let{customEventSpecs:Mn,standardEventSpecs:Nn}=an(Z),Vn=Nn.flatMap(Lt=>Lt.entities.map(Hn=>Hn.source));Se(L)&&d==="@snowplow/browser-tracker"&&e.log("You are generating Snowplow Ecommerce events. You would need to install `@snowplow/browser-plugin-snowplow-ecommerce`."),m.validations&&e.log("For validations to work properly you would need to install `ajv@8`, `ajv-formats@2` and `ajv-draft-04@1` on your project.");let Wn=await _e(a),ne=await Ge(g,[...r,...Vn]),Un=await Pn(l,p),ie=!!(d==="@snowplow/browser-tracker"&&c.match(/javascript|typescript/));await rn(ne,Z,g,m.disallowDevSchemas);let oe={language:c,tracker:d,schemas:[...Un,...Wn,...ne],eventSpecifications:Mn,validations:ie&&m.validations,eventSpecificationsInputMetadata:kt},T=await(0,Ln.generate)(oe);if(n.stop(!0),!T)throw new Q;e.success("Code generated, writing...");let F=(0,Zt.resolve)(l,f),_n=Qe(c),re=Ft+_n,Gn=(0,Zt.resolve)(F,re);if(Tn(F),bn({codeLines:T.lines,outFilePath:Gn,language:c}),oe.language==="javascript-gtm"&&await kn({defaultFileName:Ft,outDir:F,codeLines:T.lines}),tn(L,F),ie&&m.validations&&T.validationsSchemaObject){let Lt=Be(L);In(F,c,T.validationsSchemaObject,Lt),qt(T.validationsSchemaObject)&&e.warn("Some schemas appear to have attributes that can have inconsistent validations between the pipeline and client-side validation. Read more at https://docs.snowplow.io/docs/collecting-data/code-generation/client-side-validation/#divergence-with-pipeline-validation")}m.instructions&&await hn(g,Z,T.lines,F,re)}var Qt=A(Y,"generate");async function Ki(t){let e=await W(t||process.cwd());return j(e),e}async function qi(t,e,n,i){let o=await Ki(i.config),{options:{commands:{update:{maximumBump:r,regenerateOnUpdate:a,showOnlyProdUpdates:s},generate:p}}}=o;e.debug("Starting update process with options: ".concat(JSON.stringify(i)));let{configDir:c}=C(i.config||process.cwd()),d=(0,Fn.resolve)(c,o.outpath,lt),f=new P({...t,organizationId:o.organizationId});n.setSpinnerTitle("Checking for updates..."),n.isSpinning()===!1&&n.start();let w=await Et(f,o.dataProductIds),m=V([...o.eventSpecificationIds,...w]),l={};if(!Gt(d)&&m.length>0)throw new rt;if(Gt(d)&&m.length>0){let I=Ye(d);l=await Pe(f,m,I)}let g=await xe(f,o.dataStructures,i.maximumBump||r,s);if((Object.entries(l).length>0||g.length>0)===!0){if(e.success("Available updates found!"),en(l,g,e),i.yes||a)return g.length>0&&(g.forEach(I=>{let z=o.dataStructures.indexOf(I.previous);o.dataStructures[z]=I.next}),Pt(o,i.config||process.cwd())),e.debug("Applying the updates.."),Y(t,e,n,{...p,...i.config&&{config:i.config}});e.log("No updates applied"),e.log("To apply the available updates automatically run `update` with the --yes flag"),e.log("(caution: will ovewrite the configuration file)")}else e.success("No updates found. Everything is up-to-date!");return Promise.resolve(void 0)}var te=A(qi,"update");async function Xi(t){let{config:e,...n}=t;if(Object.values(n).every(o=>Array.isArray(o)&&o.length===0))throw new it;let i=await W(e||process.cwd());return j(i),{patchOptions:n,generateOptions:i.options.commands.generate,regenerateOnPatch:i.options.commands.patch.regenerateOnPatch}}async function Yi(t,e,n,i){let{isJSON:o,configPath:r}=C(i.config||process.cwd());if(o===!1)throw new at;let{patchOptions:a,generateOptions:s,regenerateOnPatch:p}=await Xi(i);return e.debug("Starting patch process with options: ".concat(JSON.stringify(a))),Object.entries(a).forEach(([d,f])=>{f.forEach(w=>{Ee(d,w,r)})}),e.success("Configuration patched"),p?Y(t,e,n,s):(e.log("Code is not generated yet for the patched configuration"),Promise.resolve(void 0))}var ee=A(Yi,"patch");var Dt=require("@snowplow/snowtype-core");async function $n(){await import("dotenv/config");let t=new b.Command;t.exitOverride(),t.version(N,void 0,"Snowtype CLI version number").name("snowtype").description("The Snowtype CLI is a tool which aims to speed up tracking implementations, provide type safety and inline documentation for developers and ultimately reduce the number of erroneous events.").showHelpAfterError().configureHelp({showGlobalOptions:!0}).option("-k, --apiKey <string>","Snowplow Console API key").option("-s, --apiKeyId <string>","Snowplow Console API key ID").option("-v, --verbose","Enable verbose logging"),t.command("init").description("Initialize the setup of Snowtype code generation in a project. Creates the `snowtype.config.json` file.").option("-i, --organizationId <string>","organization ID").addOption(new b.Option("-t, --tracker <availableTrackers>","tracker to use").choices(Dt.trackerTemplates)).addOption(new b.Option("-l, --language <availableLanguages>","language to use").choices(Dt.languageIds)).option("-o, --outpath <string>","output path").action(Bt),t.command("update").description("Checks for latest version updates in Data Structures and Event Specifications.").option("-c, --config <string>","config file path").option("-y, --yes","updates all to latest without asking (caution: will ovewrite the configuration file)").addOption(new b.Option("-m, --maximumBump <'patch' | 'minor' | 'major'>","the maximum SchemaVer update to show an available update notification. Defaults to 'major'").choices(["patch","minor","major"])).action(te),t.command("generate").option("-c, --config <string>","config file path").option("--instructions","generate event specification instructions").option("--no-instructions","generate without instructions").option("--validations","add runtime validation using Ajv").option("--no-validations","generate without runtime validations").option("--disallowDevSchemas","disallow generation of code using schemas only deployed on DEV environment").option("--deprecateOnlyOnProdAvailableUpdates","show deprecation warnings only when there are PROD available schema updates").description("Generates tracking code based on configuration on the `snowtype.config.json` file.").action(Qt),t.command("patch").option("-c, --config <string>","config file path").description("Adds new Data Structures and Event Specifications in the `snowtype.config.json` file.").option("-p, --dataProductIds <dataProductIds...>","data product ID").option("-e, --eventSpecificationIds <eventSpecificationIds...>","tracking eventSpecification ID").option("-d, --dataStructures <dataStructures...>","data structure URI").option("-i, --igluCentralSchemas <igluCentralSchemas...>","iglu central URI").option("-r, --repositories <repositories...>","repository path").action(ee),t.addHelpText("before",Te()).addHelpText("after",` `),await t.parseAsync(Rn.argv).catch(e=>{Zi(e)})}function Zi(t){if(!(t instanceof b.CommanderError&&["commander.help","commander.version","commander.helpDisplayed"].indexOf(t.code)>-1))throw t}$n().then(()=>{}).catch(()=>{process.exitCode=1});