UNPKG

@shopify/cli

Version:

A CLI tool to build for the Shopify platform

23 lines (16 loc) • 14.8 kB
import{c as te,e as oe,f as O,g as ie}from"../../../chunk-3D4JXJPS.js";import{a as Q,c as X,d as ee,e as ne}from"../../../chunk-OTY24J2W.js";import{a as Z}from"../../../chunk-JCL2RRU6.js";import{a as W}from"../../../chunk-AGNMOFJS.js";import{$ as q,Ba as J,F as M,I as H,X as P,f as G,l as K}from"../../../chunk-54CAKCYR.js";import"../../../chunk-7ESSIN27.js";import"../../../chunk-ULFWK45W.js";import"../../../chunk-KHTV6PBV.js";import"../../../chunk-NKQBEFPS.js";import{k as I}from"../../../chunk-GZS44BUW.js";import"../../../chunk-K2WUCOQJ.js";import"../../../chunk-7QIOUDCX.js";import"../../../chunk-7MUKLZOL.js";import"../../../chunk-VBUZWRUL.js";import"../../../chunk-DCPBRWVC.js";import"../../../chunk-KR6QDE7D.js";import"../../../chunk-UXVZ2P63.js";import"../../../chunk-QSTEVZFQ.js";import"../../../chunk-5Y7GIF2W.js";import"../../../chunk-EKXY5COY.js";import"../../../chunk-4DCQNGUV.js";import"../../../chunk-QBSKKQBN.js";import"../../../chunk-FQWB2F75.js";import"../../../chunk-XONFGLJQ.js";import"../../../chunk-4LNCYIS3.js";import"../../../chunk-L2MGAEV3.js";import"../../../chunk-PRKBO42R.js";import"../../../chunk-ZSBA6VIC.js";import"../../../chunk-F2QU6WWX.js";import"../../../chunk-XULPJ6UG.js";import{b as Y}from"../../../chunk-XR6GMMEU.js";import"../../../chunk-3TNEIDOD.js";import"../../../chunk-MHWV5RQV.js";import"../../../chunk-XOTA6JTZ.js";import"../../../chunk-MOA33ZFO.js";import"../../../chunk-JUVAGMIH.js";import{A as S,D as V,I as C,t as $,u as j,v as A}from"../../../chunk-6G6TMKXF.js";import"../../../chunk-P6XE4MH5.js";import"../../../chunk-KLMDWDT2.js";import"../../../chunk-5CH3B62S.js";import"../../../chunk-QUTQDXSL.js";import{d as N}from"../../../chunk-WSDN25F5.js";import{d as y,f as z}from"../../../chunk-M56NDIMD.js";import"../../../chunk-PD5ZHJWI.js";import{r as me}from"../../../chunk-LDGAHMS7.js";import"../../../chunk-ZR76GGZ6.js";import"../../../chunk-EENHXSWU.js";import"../../../chunk-FUOIGXI4.js";import"../../../chunk-6M3ZYNGO.js";import"../../../chunk-QYR5VPQA.js";import"../../../chunk-OBEWZXOQ.js";import{Ca as U,Hb as D,L as F,Nb as k,Sb as _,wa as w}from"../../../chunk-N5PQPIBF.js";import"../../../chunk-CERXUPGC.js";import"../../../chunk-T4M5CWAO.js";import"../../../chunk-PRVQAHWI.js";import"../../../chunk-YTNDFQJT.js";import"../../../chunk-ULQG3XQS.js";import{d as E,i as B}from"../../../chunk-IU2ZQ6TE.js";import"../../../chunk-PIBY5DDZ.js";import{e as ue,g}from"../../../chunk-VPRTJUIN.js";g();g();g();async function se(e){let n,t;e.bundlePath&&(n=await ne(e.developerPlatformClient,{id:e.apiKey,apiKey:e.apiKey,organizationId:e.organizationId}),await ee(n,e.bundlePath));let o={appManifest:e.appManifest,appId:e.appId,apiKey:e.apiKey,name:e.name,organizationId:e.organizationId,skipPublish:!e.release,message:e.message,versionTag:e.version,commitReference:e.commitReference};n&&(o.bundleUrl=n),e.appModules.length>0&&(o.appModules=e.appModules);let i=await e.developerPlatformClient.deploy(o);if(!i.appDeploy.appVersion){let r=fe(i.appDeploy.userErrors??[],e.extensionIds,e.appModules,{version:e.version});throw new y({bold:"Version couldn't be created."},null,[],r)}return i.appDeploy.userErrors?.length>0&&(t=i.appDeploy.userErrors.map(r=>r.message).join(", ")),{validationErrors:i.appDeploy.appVersion.appModuleVersions.filter(r=>r.validationErrors.length>0).map(r=>({uuid:r.registrationUuid,errors:r.validationErrors})),versionTag:i.appDeploy.appVersion.versionTag,location:i.appDeploy.appVersion.location,message:i.appDeploy.appVersion.message,deployError:t}}var v=` Validation errors`,T=` `;function fe(e,n,t,o={}){let i=d=>d.details?.some(x=>x.extension_id)??!1,s=(d,x)=>{let b=d.details?.find(R=>typeof R.extension_id<"u")?.extension_id??"";return Object.values(x).includes(b.toString())},r=d=>{let x=d.on?d.on[0]:void 0;return t.some(b=>b.uid===x?.user_identifier)},[a,l]=I(e,d=>r(d)),[m,c]=I(l,d=>i(d)),[f,p]=I(m,d=>s(d,n));return[...ge(c,{version:o.version}),...ye(f,n),...xe(p),...he(a,t)]}function ge(e,n={}){return e.length>0?e.filter(t=>t.field&&t.field.includes("version_tag")&&t.message==="has already been taken").length>0&&n.version?[{body:["An app version with the name",{userInput:n.version},"already exists. Deploy again with a different version name."]}]:e.length===1?[{body:e[0]?.message??""}]:[{body:{list:{items:e.map(t=>t.message)}}}]:[]}function ye(e,n){return e.reduce((t,o)=>{let i=(o.field??["unknown"]).join(".").replace("extension_points","extensions.targeting"),s=i==="base"?o.message:`${i}: ${o.message}`,r=o.details.find(p=>typeof p.extension_title<"u")?.extension_title,a=o.details.find(p=>typeof p.specification_identifier<"u")?.specification_identifier,l=o.details.find(p=>typeof p.extension_id<"u")?.extension_id?.toString(),c=Object.keys(n).find(p=>n[p]===l)??r;a==="webhook_subscription"&&(c="Webhook Subscription");let f=t.find(p=>p.title===c);if(f){let p=f.body,u=o.category==="invalid"?p.find(d=>d.list.title===v):p.find(d=>d.list.title===T);u?u.list.items.includes(s)||u.list.items.push(s):p.push({list:{title:o.category==="invalid"?v:T,items:[s]}})}else t.push({title:c,body:[{list:{title:o.category==="invalid"?v:T,items:[s]}}]});return t.forEach(p=>{p.body.sort((u,d)=>u.list.title===v?1:d.list.title===v?-1:0)}),t},[])}function he(e,n){return e.reduce((t,o)=>{let s=(o.on?o.on[0]:void 0)?.user_identifier,r=n.find(p=>p.uid===s),a=s?`Extension with uid: ${s}`:"Unknown Extension",l=r?.handle??a,c=`${(o.field??["unknown"]).join(".")}: ${o.message}`,f=t.find(p=>p.title===l);if(f){let u=f.body.find(d=>d.list.title===v);u&&(u.list.items.includes(c)||u.list.items.push(c))}else t.push({title:l,body:[{list:{title:v,items:[c]}}]});return t},[])}function xe(e){return e.reduce((n,t)=>{let o=t.details.find(s=>typeof s.extension_title<"u")?.extension_title,i=n.find(s=>s.title===o);return i?i.errorCount+=1:n.push({title:o,errorCount:1}),n},[]).map(n=>({title:n.title,body:` ${n.errorCount} error${n.errorCount>1?"s":""} found in your extensions. Fix these issues and try deploying again.`}))}g();async function re(e){let n=E(e.app.directory,".shopify","deploy-bundle");await U(n,{force:!0}),await w(n),await Q(e.appManifest,n),e.skipBuild||await G(e.app);let t=e.app.allExtensions.map(i=>({prefix:i.localIdentifier,action:async(s,r,a)=>{let l=e.isDevDashboardApp?void 0:e.identifiers?.extensions[i.localIdentifier];e.skipBuild?await i.copyIntoBundle({stderr:r,stdout:s,signal:a,app:e.app,environment:"production"},n,l):await i.buildForBundle({stderr:r,stdout:s,signal:a,app:e.app,environment:"production"},n,l)}}));if(await $({processes:t,showTimestamps:!1}),e.app.allExtensions.some(i=>i.hasDeploySteps))return await X(n,e.bundlePath),e.bundlePath}async function be(e){let{app:n,remoteApp:t,developerPlatformClient:o,force:i,extensions:s}=e;if(i||!C())return n;let r=[`App includes legacy extensions that will be deprecated soon: `,s.map(l=>` - ${l.title}`).join(` `),` Run `,{command:"shopify app import-extensions"},"to add legacy extensions now?"];return await S({message:r,confirmationMessage:"Yes, add legacy extensions and deploy",cancellationMessage:"No, skip for now"})?(await O({app:n,remoteApp:t,developerPlatformClient:o,extensions:s}),M(n)):n}async function ve(e){let{app:n,remoteApp:t,developerPlatformClient:o,force:i,extensions:s}=e,r=[`App can't be deployed until Partner Dashboard managed extensions are added to your version or removed from your app: `,s.map(c=>` - ${c.title}`).join(` `)],a=[` Run `,{command:"shopify app import-extensions"},"to add legacy extensions."];if(i||!C())throw new y(r,a);let l=[` Run `,{command:"shopify app import-extensions"}," to add legacy extensions now?"];if(await S({message:[...r,...l],confirmationMessage:"Yes, add legacy extensions and deploy",cancellationMessage:"No, don't add legacy extensions"}))return await O({app:n,remoteApp:t,developerPlatformClient:o,extensions:s}),M(n);throw new z}async function Ee(e){let{app:n,remoteApp:t,developerPlatformClient:o}=e,i=await ie({developerPlatformClient:o,apiKey:t.apiKey,organizationId:t.organizationId,extensionTypes:te,onlyDashboardManaged:!0}),s=oe(e.app,i);return s.length===0?n:o.supportsDashboardManagedExtensions?be({...e,extensions:s}):ve({...e,extensions:s})}async function ae(e){let{remoteApp:n,developerPlatformClient:t,noRelease:o,force:i,allowUpdates:s,allowDeletes:r}=e,a=await Ee({app:e.app,remoteApp:n,developerPlatformClient:t,force:i}),{identifiers:l,didMigrateExtensionsToDevDash:m}=await q({...e,app:a,developerPlatformClient:t,allowUpdates:s,allowDeletes:r}),c=!o,f=n.apiKey;_(),c?k(`Releasing a new app version as part of ${n.title}`):k(`Creating a new app version as part of ${n.title}`),_();let p;try{let u=E(e.app.directory,".shopify",`deploy-bundle.${t.bundleFormat}`);await w(B(u));let d=await a.manifest(l),x=await re({app:a,appManifest:d,bundlePath:u,identifiers:l,skipBuild:e.skipBuild,isDevDashboardApp:t.supportsAtomicDeployments}),b;c?b="Releasing an app version":b="Creating an app version",await V([{title:"Running validation",task:async()=>{await a.preDeployValidation()}},{title:b,task:async()=>{let de=await Promise.all(a.allExtensions.flatMap(ce=>ce.bundleConfig({identifiers:l,developerPlatformClient:t,apiKey:f,appConfiguration:a.configuration})));p=await se({appManifest:d,appId:n.id,apiKey:f,name:a.name,organizationId:n.organizationId,bundlePath:x,appModules:F(de),release:c,developerPlatformClient:t,extensionIds:l.extensionIds,message:e.message,version:e.version,commitReference:e.commitReference}),await P({app:a,identifiers:l,command:"deploy",developerPlatformClient:t})}}]),await we({app:a,project:e.project,release:c,uploadExtensionsBundleResult:p,didMigrateExtensionsToDevDash:m})}catch(u){throw await P({app:a,identifiers:l,command:"deploy",developerPlatformClient:t}),u}return{app:a}}async function we({app:e,project:n,release:t,uploadExtensionsBundleResult:o,didMigrateExtensionsToDevDash:i}){let s=[{link:{label:o.versionTag??"version",url:o.location}},o.message?` ${o.message}`:""],r=[];if(i){let a=await H(e.directory),l=Object.values(a).filter(c=>c!==a[e.configuration.client_id]),m=[];l.length>0&&m.push("\u2022 Map extension IDs to other copies of your app by running",{command:D(n.packageManager,"shopify app deploy")},"for: ",{list:{items:l}}),m.push("\u2022 Commit to source control to ensure your extension IDs aren't regenerated on the next deploy."),r=[{title:"Next steps",body:m},{title:"Reference",body:["\u2022 ",{link:{label:"Migrating from the Partner Dashboard",url:"https://shopify.dev/docs/apps/build/dev-dashboard/migrate-from-partners"}}]}]}return t?o.deployError?j({headline:"New version created, but not released.",body:[...s,` ${o.deployError}`],customSections:r}):A({headline:"New version released to users.",body:s,customSections:r}):A({headline:"New version created.",body:s,customSections:r,nextSteps:[["Run",{command:D(n.packageManager,"shopify app release",`--version=${o.versionTag}`)},"to release this version to users."]]})}g();function pe(e){if(typeof e>"u")return;let n=["Invalid version name:",{userInput:e}],t=100;if(e.length>t)throw new y(n,`Version name must be ${t} characters or less.`);let o=[".",".."];if(o.find(s=>e===s))throw new y(n,`Version name may not be any of: ${o.map(s=>`'${s}'`).join(" , ")}`);let i=/^[a-zA-Z0-9.\-_]+$/;if(!e.match(i))throw new y(n,["Version name can only contain alphanumeric characters, periods, hyphens, and underscores"])}g();function le(e){if(typeof e>"u")return;let n=["Invalid message:",{userInput:e}],t=200;if(e.length>t)throw new y(n,`Message name must be ${t} characters or less.`)}var h=ue(me(),1);var L=class e extends Z{static{this.summary="Deploy your Shopify app."}static{this.descriptionWithMarkdown=`[Builds the app](https://shopify.dev/docs/api/shopify-cli/app/app-build), then deploys your app configuration and extensions. This command creates an app version, which is a snapshot of your app configuration and all extensions. This version is then released to users. This command doesn't deploy your [web app](https://shopify.dev/docs/apps/tools/cli/structure#web-components). You need to [deploy your web app](https://shopify.dev/docs/apps/deployment/web) to your own hosting solution. `}static{this.description=this.descriptionWithoutMarkdown()}static{this.flags={...Y,...W,"allow-updates":h.Flags.boolean({hidden:!1,description:"Allows adding and updating extensions and configuration without requiring user confirmation. Recommended option for CI/CD environments.",env:"SHOPIFY_FLAG_ALLOW_UPDATES"}),"allow-deletes":h.Flags.boolean({hidden:!1,description:"Allows removing extensions and configuration without requiring user confirmation. For CI/CD environments, the recommended flag is --allow-updates.",env:"SHOPIFY_FLAG_ALLOW_DELETES"}),"no-release":h.Flags.boolean({hidden:!1,description:"Creates a version but doesn't release it - it's not made available to merchants. With this flag, a user confirmation is not required.",env:"SHOPIFY_FLAG_NO_RELEASE",default:!1,exclusive:["allow-updates","allow-deletes"]}),"no-build":h.Flags.boolean({description:"Use with caution: Skips building any elements of the app that require building. You should ensure your app has been prepared in advance, such as by running `shopify app build` or by caching build artifacts.",env:"SHOPIFY_FLAG_NO_BUILD",default:!1}),message:h.Flags.string({hidden:!1,description:"Optional message that will be associated with this version. This is for internal use only and won't be available externally.",env:"SHOPIFY_FLAG_MESSAGE"}),version:h.Flags.string({hidden:!1,description:"Optional version tag that will be associated with this app version. If not provided, an auto-generated identifier will be generated for this app version.",env:"SHOPIFY_FLAG_VERSION"}),"source-control-url":h.Flags.string({hidden:!1,description:"URL associated with the new app version.",env:"SHOPIFY_FLAG_SOURCE_CONTROL_URL"})}}async run(){let{flags:n}=await this.parse(e);await K.addPublicMetadata(()=>({cmd_deploy_flag_message_used:!!n.message,cmd_deploy_flag_version_used:!!n.version,cmd_deploy_flag_source_url_used:!!n["source-control-url"]})),pe(n.version),le(n.message);let t=n["client-id"];await N(()=>({cmd_app_reset_used:n.reset}));let o=n["no-release"],i=[];o||n["allow-updates"]||n["allow-deletes"]||i.push("allow-updates"),this.failMissingNonTTYFlags(n,i);let{app:r,project:a,remoteApp:l,developerPlatformClient:m,organization:c}=await J({directory:n.path,clientId:t,forceRelink:n.reset,userProvidedConfigName:n.config}),f=o||n["allow-updates"],p=o||n["allow-deletes"];return{app:(await ae({app:r,project:a,remoteApp:l,organization:c,developerPlatformClient:m,reset:n.reset,force:o,allowUpdates:f,allowDeletes:p,noRelease:n["no-release"],message:n.message,version:n.version,commitReference:n["source-control-url"],skipBuild:n["no-build"]})).app}}};export{L as default};