sharetribe-cli 1.16.6 → 1.16.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import{Command as ir}from"commander";import{readFileSync as ar}from"node:fs";import{fileURLToPath as cr}from"node:url";import{dirname as lr,join as pr}from"node:path";import{readFileSync as Pe}from"node:fs";import{fileURLToPath as Ie}from"node:url";import{dirname as V,join as be}from"node:path";function Oe(){let s=Ie(import.meta.url),t=V(s);for(;t!=="/";)try{let e=be(t,"package.json");return Pe(e,"utf-8")}catch{t=V(t)}throw new Error("Could not find package.json")}function H(){let s=JSON.parse(Oe());console.log(s.version)}import Re from"inquirer";import{writeAuth as xe}from"sharetribe-flex-build-sdk";async function J(){let s=await Re.prompt([{type:"password",name:"apiKey",message:"Enter API key:",mask:"*",validate:t=>!t||t.trim().length===0?"API key cannot be empty":!0}]);xe({apiKey:s.apiKey}),console.log("Successfully logged in.")}import{clearAuth as Te}from"sharetribe-flex-build-sdk";async function B(){await Te(),console.log("Successfully logged out.")}import{listProcesses as qe,listProcessVersions as Me}from"sharetribe-flex-build-sdk";import R from"chalk";function C(s,t){if(t.length===0)return;let e={};for(let n of s)e[n]=n.length+1;for(let n of t)for(let i of s){let a=n[i]||"";e[i]=Math.max(e[i]||0,a.length)}console.log("");let o=s.map((n,i)=>{let a=e[n]||0,p=n.padEnd(a+1);return i===s.length-1?p:p+" "}).join("");console.log(R.bold.black(o));for(let n of t){let a=s.map((p,l)=>{let m=n[p]||"",u=e[p]||0,f=m.padEnd(u+1);return l===s.length-1?f:f+" "}).join("");console.log(a)}console.log("")}function c(s){console.error(R.red(`Error: ${s}`))}function E(s){console.log(R.green(s))}function De(s){try{let t=new Date(s),e=t.getFullYear(),r=String(t.getMonth()+1).padStart(2,"0"),o=String(t.getDate()).padStart(2,"0"),n=t.toLocaleTimeString("en-US");return`${e}-${r}-${o} ${n}`}catch{return s}}async function x(s,t){try{if(t){let e=await Me(void 0,s,t);if(e.length===0){console.log(`No versions found for process: ${t}`);return}let r=e.map(o=>({Created:De(o.createdAt),Version:o.version.toString(),Aliases:o.aliases?.join(", ")||"",Transactions:o.transactionCount?.toString()||"0"}));C(["Created","Version","Aliases","Transactions"],r)}else{let e=await qe(void 0,s);if(e.length===0){console.log("No processes found.");return}let r=e.map(o=>({Name:o.name,"Latest version":o.version?.toString()||""}));C(["Name","Latest version"],r)}}catch(e){e&&typeof e=="object"&&"message"in e?c(e.message):c("Failed to list processes"),process.exit(1)}}import{createProcess as _e}from"sharetribe-flex-build-sdk";import{readFileSync as Le}from"node:fs";import{join as Ne}from"node:path";async function T(s,t,e){try{let r=Ne(e,"process.edn"),o=Le(r,"utf-8"),n=await _e(void 0,s,t,o);E(`Process ${n.name} successfully created with version ${n.version}.`)}catch(r){r&&typeof r=="object"&&"message"in r?c(r.message):c("Failed to create process"),process.exit(1)}}import{pushProcess as $e}from"sharetribe-flex-build-sdk";import{readFileSync as q,readdirSync as Fe}from"node:fs";import{join as P}from"node:path";function je(s){let t=P(s,"templates"),e=[];try{let r=Fe(t);for(let o of r){let n=P(t,o),i=P(n,`${o}-html.html`),a=P(n,`${o}-subject.txt`);try{let p=q(i,"utf-8"),l=q(a,"utf-8");e.push({name:o,html:p,subject:l})}catch{}}}catch{}return e}async function M(s,t,e){try{let r=P(e,"process.edn"),o=q(r,"utf-8"),n=je(e),i=await $e(void 0,s,t,o,n);i.noChanges?console.log("No changes"):E(`Version ${i.version} successfully saved for process ${t}.`)}catch(r){r&&typeof r=="object"&&"message"in r?c(r.message):c("Failed to push process"),process.exit(1)}}import{getProcess as Ke}from"sharetribe-flex-build-sdk";import{writeFileSync as D,mkdirSync as _}from"node:fs";import{join as I}from"node:path";async function L(s,t,e,r,o){try{let n=await Ke(void 0,s,t,{version:r,alias:o});if(!n.definition)throw new Error("No process definition in response");let{existsSync:i}=await import("node:fs"),a=i(e);_(e,{recursive:!0}),a||console.error(`Creating a new directory: ${e}`);let p=I(e,"process.edn");D(p,n.definition,"utf-8");let l=n.emailTemplates||[];if(l&&Array.isArray(l)&&l.length>0){let m=I(e,"templates");_(m,{recursive:!0});for(let u of l){let f=u.name,w=u.html,S=u.subject;if(f){let d=I(m,f);if(_(d,{recursive:!0}),w){let g=I(d,`${f}-html.html`);D(g,w,"utf-8")}if(S){let g=I(d,`${f}-subject.txt`);D(g,S,"utf-8")}}}}console.error(`Saved process to ${e}`)}catch(n){n&&typeof n=="object"&&"message"in n?c(n.message):c("Failed to pull process"),process.exit(1)}}import{createAlias as Ue,updateAlias as Ve,deleteAlias as He}from"sharetribe-flex-build-sdk";async function N(s,t,e,r){try{let o=await Ue(void 0,s,t,e,r);E(`Alias ${o.alias} successfully created to point to version ${o.version}.`)}catch(o){o&&typeof o=="object"&&"message"in o?c(o.message):c("Failed to create alias"),process.exit(1)}}async function $(s,t,e,r){try{let o=await Ve(void 0,s,t,e,r);E(`Alias ${o.alias} successfully updated to point to version ${o.version}.`)}catch(o){o&&typeof o=="object"&&"message"in o?c(o.message):c("Failed to update alias"),process.exit(1)}}async function F(s,t,e){try{let r=await He(void 0,s,t,e);E(`Alias ${r.alias} successfully deleted.`)}catch(r){r&&typeof r=="object"&&"message"in r?c(r.message):c("Failed to delete alias"),process.exit(1)}}import{deployProcess as Je,parseProcessFile as Be}from"sharetribe-flex-build-sdk";import{readFileSync as We}from"node:fs";import{join as Ge}from"node:path";async function j(s,t,e,r){try{let o=Ge(e,"process.edn"),n=We(o,"utf-8"),i=Be(n),a=await Je(void 0,s,{process:t,alias:r,path:o,processDefinition:i});a.processCreated&&E(`Process ${t} successfully created.`),E(`Version ${a.version} successfully saved for process ${t}.`),a.aliasCreated?E(`Alias ${a.alias} successfully created to point to version ${a.version}.`):E(`Alias ${a.alias} successfully updated to point to version ${a.version}.`)}catch(o){o&&typeof o=="object"&&"message"in o?c(o.message):c("Failed to create/push process and alias"),process.exit(1)}}function W(s){let t=s.command("process").description("describe a process file").option("--path <PROCESS_DIR>","path to the directory where the process.edn file is").option("--transition <TRANSITION_NAME>","transition name, e.g. transition/request to get more details of it").action(async e=>{e.path?(console.log(`Describing process at: ${e.path}`),e.transition&&console.log(`Transition: ${e.transition}`),console.log("Process description not yet implemented")):t.outputHelp()});t.command("list").description("list all transaction processes").option("--process <PROCESS_NAME>","print version and alias info of a specific process").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await x(r,e.process)}),t.command("create").description("create a new transaction process").requiredOption("--process <PROCESS_NAME>","name for the new process").requiredOption("--path <LOCAL_PROCESS_DIR>","path to the directory where the process.edn file is").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await T(r,e.process,e.path)}),t.command("push").description("push a process file to the remote").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--path <LOCAL_PROCESS_DIR>","path to the directory where the process.edn file is").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await M(r,e.process,e.path)}),t.command("pull").description("fetch a process file").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--path <LOCAL_PROCESS_DIR>","path where to save the process").option("--version <VERSION_NUM>","version number").option("--alias <PROCESS_ALIAS>","alias name").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await L(r,e.process,e.path,e.version,e.alias)}),t.command("create-alias").description("create a new alias").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--version <VERSION_NUM>","version number").requiredOption("--alias <ALIAS>","alias name").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").allowUnknownOption(!1).action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await N(r,e.process,parseInt(e.version),e.alias)}),t.command("update-alias").description("update an existing alias").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--version <VERSION_NUM>","version number").requiredOption("--alias <ALIAS>","alias name").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await $(r,e.process,parseInt(e.version),e.alias)}),t.command("delete-alias").description("delete an existing alias").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--alias <ALIAS>","alias name").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await F(r,e.process,e.alias)}),t.command("deploy").description("deploy a process file with alias (create/push + alias create/update)").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--path <LOCAL_PROCESS_DIR>","path to the directory with the process files").requiredOption("--alias <ALIAS>","alias name").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await j(r,e.process,e.path,e.alias)}),s.command("process-list",{hidden:!0}).description("list all transaction processes").option("--process <PROCESS_NAME>","print version and alias info of a specific process").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await x(r,e.process)}),s.command("process-create",{hidden:!0}).description("create a new transaction process").requiredOption("--process <PROCESS_NAME>","name for the new process").requiredOption("--path <LOCAL_PROCESS_DIR>","path to the directory where the process.edn file is").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await T(r,e.process,e.path)}),s.command("process-push",{hidden:!0}).description("push a process file to the remote").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--path <LOCAL_PROCESS_DIR>","path to the directory where the process.edn file is").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await M(r,e.process,e.path)}),s.command("process-pull",{hidden:!0}).description("fetch a process file").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--path <LOCAL_PROCESS_DIR>","path where to save the process").option("--version <VERSION_NUM>","version number").option("--alias <PROCESS_ALIAS>","alias name").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await L(r,e.process,e.path,e.version,e.alias)}),s.command("process-create-alias",{hidden:!0}).description("create a new alias").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--version <VERSION_NUM>","version number").requiredOption("--alias <ALIAS>","alias name").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await N(r,e.process,parseInt(e.version),e.alias)}),s.command("process-update-alias",{hidden:!0}).description("update an existing alias").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--version <VERSION_NUM>","version number").requiredOption("--alias <ALIAS>","alias name").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await $(r,e.process,parseInt(e.version),e.alias)}),s.command("process-delete-alias",{hidden:!0}).description("delete an existing alias").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--alias <ALIAS>","alias name").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await F(r,e.process,e.alias)}),s.command("process-deploy",{hidden:!0}).description("deploy a process file with alias (create/push + alias create/update)").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--path <LOCAL_PROCESS_DIR>","path to the directory with the process files").requiredOption("--alias <ALIAS>","alias name").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await j(r,e.process,e.path,e.alias)})}import{listSearchSchemas as Qe,setSearchSchema as Ye,unsetSearchSchema as ze}from"sharetribe-flex-build-sdk";var G={metadata:"Metadata",private:"Private data",protected:"Protected data",public:"Public data"};async function Ze(s,t){try{await Ye(void 0,s,{key:t.key,scope:t.scope,type:t.type,doc:t.doc,defaultValue:t.default,schemaFor:t.schemaFor});let e=t.schemaFor||"listing",r=G[t.scope]||t.scope;console.log(`${r} schema, ${t.key} is successfully set for ${e}.`)}catch(e){e&&typeof e=="object"&&"message"in e?c(e.message):c("Failed to set search schema"),process.exit(1)}}async function Xe(s,t){try{await ze(void 0,s,{key:t.key,scope:t.scope,schemaFor:t.schemaFor});let e=t.schemaFor||"listing",r=G[t.scope]||t.scope;console.log(`${r} schema, ${t.key} is successfully unset for ${e}.`)}catch(e){e&&typeof e=="object"&&"message"in e?c(e.message):c("Failed to unset search schema"),process.exit(1)}}function et(s){return s==null?"":Array.isArray(s)?s.join(", "):String(s)}async function tt(s){try{let t=await Qe(void 0,s);if(t.length===0){console.log("No search schemas found.");return}let e=t.map(i=>({"Schema for":i.schemaFor,Scope:i.scope,Key:i.key,Type:i.type,"Default value":et(i.defaultValue),Doc:i.doc||""})).sort((i,a)=>i["Schema for"]!==a["Schema for"]?i["Schema for"].localeCompare(a["Schema for"]):i.Scope!==a.Scope?i.Scope.localeCompare(a.Scope):i.Key.localeCompare(a.Key)),r=["Schema for","Scope","Key","Type","Default value","Doc"],o={};for(let i of r)o[i]=i.length+1;for(let i of e)for(let a of r){let p=i[a]||"";o[a]=Math.max(o[a],p.length)}console.log("");let n=r.map((i,a)=>{let p=o[i]||0,l=i.padEnd(p);return a===r.length-1?l+" ":l+" "});console.log(n.join(""));for(let i of e){let a=r.map((p,l)=>{let m=i[p]||"",u=o[p]||0,f=m.padEnd(u);return l===r.length-1?f+" ":f+" "});console.log(a.join(""))}console.log("")}catch(t){t&&typeof t=="object"&&"message"in t?c(t.message):c("Failed to list search schemas"),process.exit(1)}}function Q(s){let t=s.command("search").description("list all search schemas").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await tt(r)});t.command("set").description("set search schema").requiredOption("--key <KEY>","key name").requiredOption("--scope <SCOPE>","extended data scope (either metadata or public for listing schema, metadata, private, protected or public for userProfile schema, metadata or protected for transaction schema)").requiredOption("--type <TYPE>","value type (either enum, multi-enum, boolean, long or text)").option("--doc <DOC>","description of the schema").option("--default <DEFAULT>","default value for search if value is not set").option("--schema-for <SCHEMA_FOR>","Subject of the schema (either listing, userProfile or transaction, defaults to listing)").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await Ze(r,{key:e.key,scope:e.scope,type:e.type,doc:e.doc,default:e.default,schemaFor:e.schemaFor})}),t.command("unset").description("unset search schema").requiredOption("--key <KEY>","key name").requiredOption("--scope <SCOPE>","extended data scope (either metadata or public for listing schema, metadata, private, protected or public for userProfile schema, metadata or protected for transaction schema)").option("--schema-for <SCHEMA_FOR>","Subject of the schema (either listing, userProfile or transaction, defaults to listing)").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await Xe(r,{key:e.key,scope:e.scope,schemaFor:e.schemaFor})})}import{pushAssets as rt,stageAsset as st,getApiBaseUrl as ot,readAuth as nt}from"sharetribe-flex-build-sdk";import{readFileSync as X,writeFileSync as it,existsSync as v,mkdirSync as K,readdirSync as ee,statSync as b,unlinkSync as Y,createWriteStream as te}from"node:fs";import{join as A,dirname as at}from"node:path";import{createHash as ct}from"node:crypto";import*as lt from"node:http";import*as pt from"node:https";import{tmpdir as mt}from"node:os";import{pipeline as re}from"node:stream/promises";import z from"chalk";import y from"jsedn";import dt from"yauzl";var ut="meta/asset-meta.edn",Z="assets/",ft="\x1B[K",ht="\r";function se(s){try{let t=y.parse(s),e=t.at(y.kw(":version"))||t.at(y.kw(":aliased-version")),r=t.at(y.kw(":assets")),o=[];if(r&&r.val)for(let n of r.val)o.push({path:n.at(y.kw(":path")),"content-hash":n.at(y.kw(":content-hash"))});return e?{version:e,assets:o}:null}catch{return null}}function oe(s){let t=A(s,".flex-cli","asset-meta.edn");if(!v(t))return null;try{let e=X(t,"utf-8");return se(e)}catch{return null}}function ne(s,t){let e=A(s,".flex-cli");v(e)||K(e,{recursive:!0});let r=t.assets.map(i=>new y.Map([y.kw(":path"),i.path,y.kw(":content-hash"),i["content-hash"]])),o=new y.Map([y.kw(":version"),t.version,y.kw(":assets"),new y.Vector(r)]),n=A(s,".flex-cli","asset-meta.edn");it(n,y.encode(o),"utf-8")}function gt(s){let t=Buffer.from(`${s.length}|`,"utf-8");return ct("sha1").update(t).update(s).digest("hex")}function yt(s){let t=[];function e(r,o=""){let n=ee(r);for(let i of n){if(i===".flex-cli"||i===".DS_Store")continue;let a=A(r,i),p=o?A(o,i):i,l=b(a);if(l.isDirectory())e(a,p);else if(l.isFile()){let m=X(a),u=gt(m);t.push({path:p,data:m,hash:u})}}}return e(s),t}function Et(s){let t=[];function e(r,o=""){let n=ee(r);for(let i of n){if(i===".flex-cli"||i===".DS_Store")continue;let a=A(r,i),p=o?A(o,i):i,l=b(a);l.isDirectory()?e(a,p):l.isFile()&&t.push(p)}}return e(s),t}function St(s){for(let t of s)if(t.path.endsWith(".json"))try{JSON.parse(t.data.toString("utf-8"))}catch(e){throw new Error(`Invalid JSON in ${t.path}: ${e}`)}}function At(s){let t=s/1024/1024;return`${ht}${ft}Downloaded ${t.toFixed(2)}MB`}function kt(s){let t=0,e=()=>{process.stderr.write(At(t))},r=setInterval(e,100);s.on("data",o=>{t+=o.length}),s.on("end",()=>{clearInterval(r),e(),process.stderr.write(`
3
+ import{Command as pr}from"commander";import{readFileSync as mr,existsSync as dr,writeFileSync as ur,mkdirSync as fr}from"node:fs";import{fileURLToPath as hr}from"node:url";import{dirname as gr,join as H}from"node:path";import{homedir as yr}from"node:os";import V from"chalk";import{readFileSync as Re}from"node:fs";import{fileURLToPath as xe}from"node:url";import{dirname as J,join as Te}from"node:path";function De(){let s=xe(import.meta.url),t=J(s);for(;t!=="/";)try{let e=Te(t,"package.json");return Re(e,"utf-8")}catch{t=J(t)}throw new Error("Could not find package.json")}function B(){let s=JSON.parse(De());console.log(s.version)}import Me from"inquirer";import{writeAuth as qe}from"sharetribe-flex-build-sdk";async function W(){let s=await Me.prompt([{type:"password",name:"apiKey",message:"Enter API key:",mask:"*",validate:t=>!t||t.trim().length===0?"API key cannot be empty":!0}]);qe({apiKey:s.apiKey}),console.log("Successfully logged in.")}import{clearAuth as _e}from"sharetribe-flex-build-sdk";async function G(){await _e(),console.log("Successfully logged out.")}import{listProcesses as Le,listProcessVersions as Ne}from"sharetribe-flex-build-sdk";import R from"chalk";function C(s,t){if(t.length===0)return;let e={};for(let n of s)e[n]=n.length+1;for(let n of t)for(let i of s){let a=n[i]||"";e[i]=Math.max(e[i]||0,a.length)}console.log("");let o=s.map((n,i)=>{let a=e[n]||0,p=n.padEnd(a+1);return i===s.length-1?p:p+" "}).join("");console.log(R.bold.black(o));for(let n of t){let a=s.map((p,l)=>{let m=n[p]||"",u=e[p]||0,f=m.padEnd(u+1);return l===s.length-1?f:f+" "}).join("");console.log(a)}console.log("")}function c(s){console.error(R.red(`Error: ${s}`))}function E(s){console.log(R.green(s))}function $e(s){try{let t=new Date(s),e=t.getFullYear(),r=String(t.getMonth()+1).padStart(2,"0"),o=String(t.getDate()).padStart(2,"0"),n=t.toLocaleTimeString("en-US");return`${e}-${r}-${o} ${n}`}catch{return s}}async function x(s,t){try{if(t){let e=await Ne(void 0,s,t);if(e.length===0){console.log(`No versions found for process: ${t}`);return}let r=e.map(o=>({Created:$e(o.createdAt),Version:o.version.toString(),Aliases:o.aliases?.join(", ")||"",Transactions:o.transactionCount?.toString()||"0"}));C(["Created","Version","Aliases","Transactions"],r)}else{let e=await Le(void 0,s);if(e.length===0){console.log("No processes found.");return}let r=e.map(o=>({Name:o.name,"Latest version":o.version?.toString()||""}));C(["Name","Latest version"],r)}}catch(e){e&&typeof e=="object"&&"message"in e?c(e.message):c("Failed to list processes"),process.exit(1)}}import{createProcess as Fe}from"sharetribe-flex-build-sdk";import{readFileSync as je}from"node:fs";import{join as Ke}from"node:path";async function T(s,t,e){try{let r=Ke(e,"process.edn"),o=je(r,"utf-8"),n=await Fe(void 0,s,t,o);E(`Process ${n.name} successfully created with version ${n.version}.`)}catch(r){r&&typeof r=="object"&&"message"in r?c(r.message):c("Failed to create process"),process.exit(1)}}import{pushProcess as Ue}from"sharetribe-flex-build-sdk";import{readFileSync as D,readdirSync as Ve}from"node:fs";import{join as P}from"node:path";function He(s){let t=P(s,"templates"),e=[];try{let r=Ve(t);for(let o of r){let n=P(t,o),i=P(n,`${o}-html.html`),a=P(n,`${o}-subject.txt`);try{let p=D(i,"utf-8"),l=D(a,"utf-8");e.push({name:o,html:p,subject:l})}catch{}}}catch{}return e}async function M(s,t,e){try{let r=P(e,"process.edn"),o=D(r,"utf-8"),n=He(e),i=await Ue(void 0,s,t,o,n);i.noChanges?console.log("No changes"):E(`Version ${i.version} successfully saved for process ${t}.`)}catch(r){r&&typeof r=="object"&&"message"in r?c(r.message):c("Failed to push process"),process.exit(1)}}import{getProcess as Je}from"sharetribe-flex-build-sdk";import{writeFileSync as q,mkdirSync as _}from"node:fs";import{join as I}from"node:path";async function L(s,t,e,r,o){try{let n=await Je(void 0,s,t,{version:r,alias:o});if(!n.definition)throw new Error("No process definition in response");let{existsSync:i}=await import("node:fs"),a=i(e);_(e,{recursive:!0}),a||console.error(`Creating a new directory: ${e}`);let p=I(e,"process.edn");q(p,n.definition,"utf-8");let l=n.emailTemplates||[];if(l&&Array.isArray(l)&&l.length>0){let m=I(e,"templates");_(m,{recursive:!0});for(let u of l){let f=u.name,w=u.html,S=u.subject;if(f){let d=I(m,f);if(_(d,{recursive:!0}),w){let g=I(d,`${f}-html.html`);q(g,w,"utf-8")}if(S){let g=I(d,`${f}-subject.txt`);q(g,S,"utf-8")}}}}console.error(`Saved process to ${e}`)}catch(n){n&&typeof n=="object"&&"message"in n?c(n.message):c("Failed to pull process"),process.exit(1)}}import{createAlias as Be,updateAlias as We,deleteAlias as Ge}from"sharetribe-flex-build-sdk";async function N(s,t,e,r){try{let o=await Be(void 0,s,t,e,r);E(`Alias ${o.alias} successfully created to point to version ${o.version}.`)}catch(o){o&&typeof o=="object"&&"message"in o?c(o.message):c("Failed to create alias"),process.exit(1)}}async function $(s,t,e,r){try{let o=await We(void 0,s,t,e,r);E(`Alias ${o.alias} successfully updated to point to version ${o.version}.`)}catch(o){o&&typeof o=="object"&&"message"in o?c(o.message):c("Failed to update alias"),process.exit(1)}}async function F(s,t,e){try{let r=await Ge(void 0,s,t,e);E(`Alias ${r.alias} successfully deleted.`)}catch(r){r&&typeof r=="object"&&"message"in r?c(r.message):c("Failed to delete alias"),process.exit(1)}}import{deployProcess as Qe,parseProcessFile as Ye}from"sharetribe-flex-build-sdk";import{readFileSync as ze}from"node:fs";import{join as Ze}from"node:path";async function j(s,t,e,r){try{let o=Ze(e,"process.edn"),n=ze(o,"utf-8"),i=Ye(n),a=await Qe(void 0,s,{process:t,alias:r,path:o,processDefinition:i});a.processCreated&&E(`Process ${t} successfully created.`),E(`Version ${a.version} successfully saved for process ${t}.`),a.aliasCreated?E(`Alias ${a.alias} successfully created to point to version ${a.version}.`):E(`Alias ${a.alias} successfully updated to point to version ${a.version}.`)}catch(o){o&&typeof o=="object"&&"message"in o?c(o.message):c("Failed to create/push process and alias"),process.exit(1)}}function Q(s){let t=s.command("process").description("describe a process file").option("--path <PROCESS_DIR>","path to the directory where the process.edn file is").option("--transition <TRANSITION_NAME>","transition name, e.g. transition/request to get more details of it").action(async e=>{e.path?(console.log(`Describing process at: ${e.path}`),e.transition&&console.log(`Transition: ${e.transition}`),console.log("Process description not yet implemented")):t.outputHelp()});t.command("list").description("list all transaction processes").option("--process <PROCESS_NAME>","print version and alias info of a specific process").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await x(r,e.process)}),t.command("create").description("create a new transaction process").requiredOption("--process <PROCESS_NAME>","name for the new process").requiredOption("--path <LOCAL_PROCESS_DIR>","path to the directory where the process.edn file is").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await T(r,e.process,e.path)}),t.command("push").description("push a process file to the remote").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--path <LOCAL_PROCESS_DIR>","path to the directory where the process.edn file is").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await M(r,e.process,e.path)}),t.command("pull").description("fetch a process file").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--path <LOCAL_PROCESS_DIR>","path where to save the process").option("--version <VERSION_NUM>","version number").option("--alias <PROCESS_ALIAS>","alias name").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await L(r,e.process,e.path,e.version,e.alias)}),t.command("create-alias").description("create a new alias").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--version <VERSION_NUM>","version number").requiredOption("--alias <ALIAS>","alias name").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").allowUnknownOption(!1).action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await N(r,e.process,parseInt(e.version),e.alias)}),t.command("update-alias").description("update an existing alias").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--version <VERSION_NUM>","version number").requiredOption("--alias <ALIAS>","alias name").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await $(r,e.process,parseInt(e.version),e.alias)}),t.command("delete-alias").description("delete an existing alias").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--alias <ALIAS>","alias name").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await F(r,e.process,e.alias)}),t.command("deploy").description("deploy a process file with alias (create/push + alias create/update)").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--path <LOCAL_PROCESS_DIR>","path to the directory with the process files").requiredOption("--alias <ALIAS>","alias name").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await j(r,e.process,e.path,e.alias)}),s.command("process-list",{hidden:!0}).description("list all transaction processes").option("--process <PROCESS_NAME>","print version and alias info of a specific process").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await x(r,e.process)}),s.command("process-create",{hidden:!0}).description("create a new transaction process").requiredOption("--process <PROCESS_NAME>","name for the new process").requiredOption("--path <LOCAL_PROCESS_DIR>","path to the directory where the process.edn file is").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await T(r,e.process,e.path)}),s.command("process-push",{hidden:!0}).description("push a process file to the remote").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--path <LOCAL_PROCESS_DIR>","path to the directory where the process.edn file is").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await M(r,e.process,e.path)}),s.command("process-pull",{hidden:!0}).description("fetch a process file").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--path <LOCAL_PROCESS_DIR>","path where to save the process").option("--version <VERSION_NUM>","version number").option("--alias <PROCESS_ALIAS>","alias name").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await L(r,e.process,e.path,e.version,e.alias)}),s.command("process-create-alias",{hidden:!0}).description("create a new alias").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--version <VERSION_NUM>","version number").requiredOption("--alias <ALIAS>","alias name").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await N(r,e.process,parseInt(e.version),e.alias)}),s.command("process-update-alias",{hidden:!0}).description("update an existing alias").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--version <VERSION_NUM>","version number").requiredOption("--alias <ALIAS>","alias name").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await $(r,e.process,parseInt(e.version),e.alias)}),s.command("process-delete-alias",{hidden:!0}).description("delete an existing alias").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--alias <ALIAS>","alias name").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await F(r,e.process,e.alias)}),s.command("process-deploy",{hidden:!0}).description("deploy a process file with alias (create/push + alias create/update)").requiredOption("--process <PROCESS_NAME>","name of the process").requiredOption("--path <LOCAL_PROCESS_DIR>","path to the directory with the process files").requiredOption("--alias <ALIAS>","alias name").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await j(r,e.process,e.path,e.alias)})}import{listSearchSchemas as Xe,setSearchSchema as et,unsetSearchSchema as tt}from"sharetribe-flex-build-sdk";var Y={metadata:"Metadata",private:"Private data",protected:"Protected data",public:"Public data"};async function rt(s,t){try{await et(void 0,s,{key:t.key,scope:t.scope,type:t.type,doc:t.doc,defaultValue:t.default,schemaFor:t.schemaFor});let e=t.schemaFor||"listing",r=Y[t.scope]||t.scope;console.log(`${r} schema, ${t.key} is successfully set for ${e}.`)}catch(e){e&&typeof e=="object"&&"message"in e?c(e.message):c("Failed to set search schema"),process.exit(1)}}async function st(s,t){try{await tt(void 0,s,{key:t.key,scope:t.scope,schemaFor:t.schemaFor});let e=t.schemaFor||"listing",r=Y[t.scope]||t.scope;console.log(`${r} schema, ${t.key} is successfully unset for ${e}.`)}catch(e){e&&typeof e=="object"&&"message"in e?c(e.message):c("Failed to unset search schema"),process.exit(1)}}function ot(s){return s==null?"":Array.isArray(s)?s.join(", "):String(s)}async function nt(s){try{let t=await Xe(void 0,s);if(t.length===0){console.log("No search schemas found.");return}let e=t.map(i=>({"Schema for":i.schemaFor,Scope:i.scope,Key:i.key,Type:i.type,"Default value":ot(i.defaultValue),Doc:i.doc||""})).sort((i,a)=>i["Schema for"]!==a["Schema for"]?i["Schema for"].localeCompare(a["Schema for"]):i.Scope!==a.Scope?i.Scope.localeCompare(a.Scope):i.Key.localeCompare(a.Key)),r=["Schema for","Scope","Key","Type","Default value","Doc"],o={};for(let i of r)o[i]=i.length+1;for(let i of e)for(let a of r){let p=i[a]||"";o[a]=Math.max(o[a],p.length)}console.log("");let n=r.map((i,a)=>{let p=o[i]||0,l=i.padEnd(p);return a===r.length-1?l+" ":l+" "});console.log(n.join(""));for(let i of e){let a=r.map((p,l)=>{let m=i[p]||"",u=o[p]||0,f=m.padEnd(u);return l===r.length-1?f+" ":f+" "});console.log(a.join(""))}console.log("")}catch(t){t&&typeof t=="object"&&"message"in t?c(t.message):c("Failed to list search schemas"),process.exit(1)}}function z(s){let t=s.command("search").description("list all search schemas").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await nt(r)});t.command("set").description("set search schema").requiredOption("--key <KEY>","key name").requiredOption("--scope <SCOPE>","extended data scope (either metadata or public for listing schema, metadata, private, protected or public for userProfile schema, metadata or protected for transaction schema)").requiredOption("--type <TYPE>","value type (either enum, multi-enum, boolean, long or text)").option("--doc <DOC>","description of the schema").option("--default <DEFAULT>","default value for search if value is not set").option("--schema-for <SCHEMA_FOR>","Subject of the schema (either listing, userProfile or transaction, defaults to listing)").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await rt(r,{key:e.key,scope:e.scope,type:e.type,doc:e.doc,default:e.default,schemaFor:e.schemaFor})}),t.command("unset").description("unset search schema").requiredOption("--key <KEY>","key name").requiredOption("--scope <SCOPE>","extended data scope (either metadata or public for listing schema, metadata, private, protected or public for userProfile schema, metadata or protected for transaction schema)").option("--schema-for <SCHEMA_FOR>","Subject of the schema (either listing, userProfile or transaction, defaults to listing)").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await st(r,{key:e.key,scope:e.scope,schemaFor:e.schemaFor})})}import{pushAssets as it,stageAsset as at,getApiBaseUrl as ct,readAuth as lt}from"sharetribe-flex-build-sdk";import{readFileSync as te,writeFileSync as pt,existsSync as v,mkdirSync as K,readdirSync as re,statSync as b,unlinkSync as Z,createWriteStream as se}from"node:fs";import{join as k,dirname as mt}from"node:path";import{createHash as dt}from"node:crypto";import*as ut from"node:http";import*as ft from"node:https";import{tmpdir as ht}from"node:os";import{pipeline as oe}from"node:stream/promises";import X from"chalk";import y from"jsedn";import gt from"yauzl";var yt="meta/asset-meta.edn",ee="assets/",Et="\x1B[K",St="\r";function ne(s){try{let t=y.parse(s),e=t.at(y.kw(":version"))||t.at(y.kw(":aliased-version")),r=t.at(y.kw(":assets")),o=[];if(r&&r.val)for(let n of r.val)o.push({path:n.at(y.kw(":path")),"content-hash":n.at(y.kw(":content-hash"))});return e?{version:e,assets:o}:null}catch{return null}}function ie(s){let t=k(s,".flex-cli","asset-meta.edn");if(!v(t))return null;try{let e=te(t,"utf-8");return ne(e)}catch{return null}}function ae(s,t){let e=k(s,".flex-cli");v(e)||K(e,{recursive:!0});let r=t.assets.map(i=>new y.Map([y.kw(":path"),i.path,y.kw(":content-hash"),i["content-hash"]])),o=new y.Map([y.kw(":version"),t.version,y.kw(":assets"),new y.Vector(r)]),n=k(s,".flex-cli","asset-meta.edn");pt(n,y.encode(o),"utf-8")}function kt(s){let t=Buffer.from(`${s.length}|`,"utf-8");return dt("sha1").update(t).update(s).digest("hex")}function At(s){let t=[];function e(r,o=""){let n=re(r);for(let i of n){if(i===".flex-cli"||i===".DS_Store")continue;let a=k(r,i),p=o?k(o,i):i,l=b(a);if(l.isDirectory())e(a,p);else if(l.isFile()){let m=te(a),u=kt(m);t.push({path:p,data:m,hash:u})}}}return e(s),t}function vt(s){let t=[];function e(r,o=""){let n=re(r);for(let i of n){if(i===".flex-cli"||i===".DS_Store")continue;let a=k(r,i),p=o?k(o,i):i,l=b(a);l.isDirectory()?e(a,p):l.isFile()&&t.push(p)}}return e(s),t}function wt(s){for(let t of s)if(t.path.endsWith(".json"))try{JSON.parse(t.data.toString("utf-8"))}catch(e){throw new Error(`Invalid JSON in ${t.path}: ${e}`)}}function Ct(s){let t=s/1024/1024;return`${St}${Et}Downloaded ${t.toFixed(2)}MB`}function Pt(s){let t=0,e=()=>{process.stderr.write(Ct(t))},r=setInterval(e,100);s.on("data",o=>{t+=o.length}),s.on("end",()=>{clearInterval(r),e(),process.stderr.write(`
4
4
  Finished downloading assets
5
- `)})}function vt(){let s=nt();if(!s?.apiKey)throw new Error("Not logged in. Please provide apiKey or run: sharetribe-cli login");return s.apiKey}function wt(s,t){let e=new URL(ot()+"/assets/pull");return e.searchParams.set("marketplace",s),t?e.searchParams.set("version",t):e.searchParams.set("version-alias","latest"),e}function Ct(s,t){try{let r=JSON.parse(s).errors?.[0]?.message;if(r)return r}catch{}return s||`HTTP ${t}`}async function Pt(s,t){let e=wt(s,t),r=vt(),o=e.protocol==="https:",n=o?pt:lt;return new Promise((i,a)=>{let p=n.request({method:"GET",hostname:e.hostname,port:e.port||(o?443:80),path:e.pathname+e.search,headers:{Authorization:`Apikey ${r}`,Accept:"application/zip"}},l=>{let m=l.statusCode||0;if(m<200||m>=300){let u=[];l.on("data",f=>u.push(f)),l.on("end",()=>{let f=Buffer.concat(u).toString("utf-8");a(new Error(Ct(f,m)))});return}i(l)});p.setTimeout(12e4,()=>{p.destroy(new Error("Request timeout"))}),p.on("error",a),p.end()})}function It(){return A(mt(),`assets-${Date.now()}.zip`)}function bt(s){return s.startsWith(Z)?s.slice(Z.length):s}function Ot(s){return new Promise((t,e)=>{let r=[];s.on("data",o=>r.push(o)),s.on("end",()=>t(Buffer.concat(r).toString("utf-8"))),s.on("error",e)})}async function Rt(s,t){return new Promise((e,r)=>{dt.open(s,{lazyEntries:!0},(o,n)=>{if(o||!n){r(o||new Error("Failed to open zip file"));return}let i=null;n.on("error",r),n.on("end",()=>{if(!i){r(new Error("Asset metadata not found in zip"));return}e(i)}),n.readEntry(),n.on("entry",a=>{if(a.fileName.endsWith("/")){n.readEntry();return}n.openReadStream(a,(p,l)=>{if(p||!l){r(p||new Error("Failed to read zip entry"));return}if(a.fileName===ut){Ot(l).then(f=>{if(i=se(f),!i){r(new Error("Invalid asset metadata"));return}n.readEntry()}).catch(r);return}let m=A(t,bt(a.fileName)),u=at(m);v(u)||K(u,{recursive:!0}),re(l,te(m)).then(()=>n.readEntry()).catch(r)})})})})}async function xt(s,t,e,r){try{if(v(t)||K(t,{recursive:!0}),!b(t).isDirectory())throw new Error(`${t} is not a directory`);let n=r?Et(t):[],i=oe(t),a=It();try{let p=await Pt(s,e);kt(p),await re(p,te(a));let l=await Rt(a,t),m=l.version,u=r?new Set(n.filter(S=>!l.assets.some(d=>d.path===S))):new Set,w=i?.version!==m||u.size>0;if(u.size>0)for(let S of u){let d=A(t,S);v(d)&&Y(d)}w?(ne(t,{version:m,assets:l.assets}),console.log(`Version ${m} successfully pulled.`)):console.log("Assets are up to date.")}finally{v(a)&&Y(a)}}catch(o){o&&typeof o=="object"&&"message"in o?c(o.message):c("Failed to pull assets"),process.exit(1)}}function Tt(s,t){let e=new Map(s.map(r=>[r.path,r["content-hash"]]));return t.filter(r=>{let o=e.get(r.path);return!o||o!==r.hash})}async function qt(s,t,e){try{if(!v(t)||!b(t).isDirectory())throw new Error(`${t} is not a valid directory`);let r=oe(t),o=r?.version||"nil",n=yt(t);St(n);let i=Tt(r?.assets||[],n),a=d=>d.toLowerCase().endsWith(".json"),p=i.filter(d=>!a(d.path)),l=new Map(n.map(d=>[d.path,d])),m=[];if(e&&r)for(let d of r.assets)l.has(d.path)||m.push({path:d.path,op:"delete"});if(i.length===0&&m.length===0){console.log("Assets are up to date.");return}if(i.length>0){let d=i.map(g=>g.path).join(", ");console.log(z.green(`Uploading changed assets: ${d}`))}let f=new Map;if(p.length>0){let d=p.map(g=>g.path).join(", ");console.log(z.green(`Staging assets: ${d}`));for(let g of p)try{let k=await st(void 0,s,g.data,g.path);f.set(g.path,k.stagingId)}catch(k){if(k&&typeof k=="object"&&"code"in k&&k.code==="asset-invalid-content"){let Ce="message"in k?k.message:"The file is missing or uses an unsupported format.";throw new Error(`Failed to stage image ${g.path}: ${Ce}
6
- Fix the file and rerun assets push to retry staging.`)}throw k}}let w=i.map(d=>{let g=f.get(d.path);return{path:d.path,op:"upsert",...g?{stagingId:g}:{data:d.data,filename:d.path}}}),S=await rt(void 0,s,o,[...w,...m]);ne(t,{version:S.version,assets:S.assets.map(d=>({path:d.path,"content-hash":d.contentHash}))}),console.log(`New version ${S.version} successfully created.`)}catch(r){r&&typeof r=="object"&&"message"in r?c(r.message):c("Failed to push assets"),process.exit(1)}}function ie(s){let t=s.command("assets").description("manage marketplace assets");t.command("pull").description("pull assets from remote").requiredOption("--path <PATH>","path to directory where assets will be stored").option("--version <VERSION>","version of assets to pull").option("--prune","delete local files no longer present as remote assets").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await xt(r,e.path,e.version,e.prune)}),t.command("push").description("push assets to remote").requiredOption("--path <PATH>","path to directory with assets").option("--prune","delete remote assets no longer present locally").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await qt(r,e.path,e.prune)})}import{sendNotification as Mt,previewNotification as Dt}from"sharetribe-flex-build-sdk";import{readFileSync as U,existsSync as O,statSync as _t}from"node:fs";import{join as ae}from"node:path";import{createServer as Lt}from"node:http";function ce(s){if(!O(s)||!_t(s).isDirectory())throw new Error(`Template directory not found: ${s}`);let t=ae(s,"template.html"),e=ae(s,"template-subject.txt");if(!O(t))throw new Error(`template.html not found in ${s}`);if(!O(e))throw new Error(`template-subject.txt not found in ${s}`);let r=U(t,"utf-8"),o=U(e,"utf-8").trim();return{html:r,subject:o}}function le(s){if(!s)return;if(!O(s))throw new Error(`Context file not found: ${s}`);let t=U(s,"utf-8");try{return JSON.parse(t)}catch(e){throw new Error(`Invalid JSON in context file: ${e}`)}}async function Nt(s,t,e){try{let r=ce(t),o=le(e),n=await Mt(void 0,s,{template:r,context:o});console.log(`Preview successfully sent to ${n.adminEmail}`)}catch(r){r&&typeof r=="object"&&"message"in r?c(r.message):c("Failed to send notification"),process.exit(1)}}async function $t(s,t,e){try{let r=ce(t),o=le(e);console.log(`Template: ${t}`),console.log(`Subject: ${r.subject}`),console.log(""),console.log("Starting preview server at http://localhost:3535"),console.log("Press Ctrl+C to stop"),console.log("");let n=null,i=async()=>{try{let m=(await Dt(void 0,s,{template:r,context:o})).html,u=`<title>${r.subject}</title>`;m.includes("<head>")?n=m.replace("<head>",`<head>
5
+ `)})}function It(){let s=lt();if(!s?.apiKey)throw new Error("Not logged in. Please provide apiKey or run: sharetribe-cli login");return s.apiKey}function bt(s,t){let e=new URL(ct()+"/assets/pull");return e.searchParams.set("marketplace",s),t?e.searchParams.set("version",t):e.searchParams.set("version-alias","latest"),e}function Ot(s,t){try{let r=JSON.parse(s).errors?.[0]?.message;if(r)return r}catch{}return s||`HTTP ${t}`}async function Rt(s,t){let e=bt(s,t),r=It(),o=e.protocol==="https:",n=o?ft:ut;return new Promise((i,a)=>{let p=n.request({method:"GET",hostname:e.hostname,port:e.port||(o?443:80),path:e.pathname+e.search,headers:{Authorization:`Apikey ${r}`,Accept:"application/zip"}},l=>{let m=l.statusCode||0;if(m<200||m>=300){let u=[];l.on("data",f=>u.push(f)),l.on("end",()=>{let f=Buffer.concat(u).toString("utf-8");a(new Error(Ot(f,m)))});return}i(l)});p.setTimeout(12e4,()=>{p.destroy(new Error("Request timeout"))}),p.on("error",a),p.end()})}function xt(){return k(ht(),`assets-${Date.now()}.zip`)}function Tt(s){return s.startsWith(ee)?s.slice(ee.length):s}function Dt(s){return new Promise((t,e)=>{let r=[];s.on("data",o=>r.push(o)),s.on("end",()=>t(Buffer.concat(r).toString("utf-8"))),s.on("error",e)})}async function Mt(s,t){return new Promise((e,r)=>{gt.open(s,{lazyEntries:!0},(o,n)=>{if(o||!n){r(o||new Error("Failed to open zip file"));return}let i=null;n.on("error",r),n.on("end",()=>{if(!i){r(new Error("Asset metadata not found in zip"));return}e(i)}),n.readEntry(),n.on("entry",a=>{if(a.fileName.endsWith("/")){n.readEntry();return}n.openReadStream(a,(p,l)=>{if(p||!l){r(p||new Error("Failed to read zip entry"));return}if(a.fileName===yt){Dt(l).then(f=>{if(i=ne(f),!i){r(new Error("Invalid asset metadata"));return}n.readEntry()}).catch(r);return}let m=k(t,Tt(a.fileName)),u=mt(m);v(u)||K(u,{recursive:!0}),oe(l,se(m)).then(()=>n.readEntry()).catch(r)})})})})}async function qt(s,t,e,r){try{if(v(t)||K(t,{recursive:!0}),!b(t).isDirectory())throw new Error(`${t} is not a directory`);let n=r?vt(t):[],i=ie(t),a=xt();try{let p=await Rt(s,e);Pt(p),await oe(p,se(a));let l=await Mt(a,t),m=l.version,u=r?new Set(n.filter(S=>!l.assets.some(d=>d.path===S))):new Set,w=i?.version!==m||u.size>0;if(u.size>0)for(let S of u){let d=k(t,S);v(d)&&Z(d)}w?(ae(t,{version:m,assets:l.assets}),console.log(`Version ${m} successfully pulled.`)):console.log("Assets are up to date.")}finally{v(a)&&Z(a)}}catch(o){o&&typeof o=="object"&&"message"in o?c(o.message):c("Failed to pull assets"),process.exit(1)}}function _t(s,t){let e=new Map(s.map(r=>[r.path,r["content-hash"]]));return t.filter(r=>{let o=e.get(r.path);return!o||o!==r.hash})}async function Lt(s,t,e){try{if(!v(t)||!b(t).isDirectory())throw new Error(`${t} is not a valid directory`);let r=ie(t),o=r?.version||"nil",n=At(t);wt(n);let i=_t(r?.assets||[],n),a=d=>d.toLowerCase().endsWith(".json"),p=i.filter(d=>!a(d.path)),l=new Map(n.map(d=>[d.path,d])),m=[];if(e&&r)for(let d of r.assets)l.has(d.path)||m.push({path:d.path,op:"delete"});if(i.length===0&&m.length===0){console.log("Assets are up to date.");return}if(i.length>0){let d=i.map(g=>g.path).join(", ");console.log(X.green(`Uploading changed assets: ${d}`))}let f=new Map;if(p.length>0){let d=p.map(g=>g.path).join(", ");console.log(X.green(`Staging assets: ${d}`));for(let g of p)try{let A=await at(void 0,s,g.data,g.path);f.set(g.path,A.stagingId)}catch(A){if(A&&typeof A=="object"&&"code"in A&&A.code==="asset-invalid-content"){let Oe="message"in A?A.message:"The file is missing or uses an unsupported format.";throw new Error(`Failed to stage image ${g.path}: ${Oe}
6
+ Fix the file and rerun assets push to retry staging.`)}throw A}}let w=i.map(d=>{let g=f.get(d.path);return{path:d.path,op:"upsert",...g?{stagingId:g}:{data:d.data,filename:d.path}}}),S=await it(void 0,s,o,[...w,...m]);ae(t,{version:S.version,assets:S.assets.map(d=>({path:d.path,"content-hash":d.contentHash}))}),console.log(`New version ${S.version} successfully created.`)}catch(r){r&&typeof r=="object"&&"message"in r?c(r.message):c("Failed to push assets"),process.exit(1)}}function ce(s){let t=s.command("assets").description("manage marketplace assets");t.command("pull").description("pull assets from remote").requiredOption("--path <PATH>","path to directory where assets will be stored").option("--version <VERSION>","version of assets to pull").option("--prune","delete local files no longer present as remote assets").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await qt(r,e.path,e.version,e.prune)}),t.command("push").description("push assets to remote").requiredOption("--path <PATH>","path to directory with assets").option("--prune","delete remote assets no longer present locally").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await Lt(r,e.path,e.prune)})}import{sendNotification as Nt,previewNotification as $t}from"sharetribe-flex-build-sdk";import{readFileSync as U,existsSync as O,statSync as Ft}from"node:fs";import{join as le}from"node:path";import{createServer as jt}from"node:http";function pe(s){if(!O(s)||!Ft(s).isDirectory())throw new Error(`Template directory not found: ${s}`);let t=le(s,"template.html"),e=le(s,"template-subject.txt");if(!O(t))throw new Error(`template.html not found in ${s}`);if(!O(e))throw new Error(`template-subject.txt not found in ${s}`);let r=U(t,"utf-8"),o=U(e,"utf-8").trim();return{html:r,subject:o}}function me(s){if(!s)return;if(!O(s))throw new Error(`Context file not found: ${s}`);let t=U(s,"utf-8");try{return JSON.parse(t)}catch(e){throw new Error(`Invalid JSON in context file: ${e}`)}}async function Kt(s,t,e){try{let r=pe(t),o=me(e),n=await Nt(void 0,s,{template:r,context:o});console.log(`Preview successfully sent to ${n.adminEmail}`)}catch(r){r&&typeof r=="object"&&"message"in r?c(r.message):c("Failed to send notification"),process.exit(1)}}async function Ut(s,t,e){try{let r=pe(t),o=me(e);console.log(`Template: ${t}`),console.log(`Subject: ${r.subject}`),console.log(""),console.log("Starting preview server at http://localhost:3535"),console.log("Press Ctrl+C to stop"),console.log("");let n=null,i=async()=>{try{let m=(await $t(void 0,s,{template:r,context:o})).html,u=`<title>${r.subject}</title>`;m.includes("<head>")?n=m.replace("<head>",`<head>
7
7
  ${u}`):m.includes("<html>")?n=m.replace("<html>",`<html>
8
8
  <head>${u}</head>`):n=`<html><head>${u}</head><body>${m}</body></html>`}catch(l){n=`
9
9
  <html>
@@ -13,11 +13,11 @@ ${u}`):m.includes("<html>")?n=m.replace("<html>",`<html>
13
13
  <pre style="background: #f5f5f5; padding: 15px; border-radius: 4px;">${l&&typeof l=="object"&&"message"in l?l.message:"Failed to preview notification"}</pre>
14
14
  </body>
15
15
  </html>
16
- `}};await i();let a=Lt(async(l,m)=>{l.url==="/"||l.url===""?(await i(),m.writeHead(200,{"Content-Type":"text/html"}),m.end(n)):(m.writeHead(404,{"Content-Type":"text/plain"}),m.end("Not Found"))});a.listen(3535,()=>{console.log("Preview server started. Open http://localhost:3535 in your browser.")});let p=()=>{console.log(`
17
- Shutting down preview server...`),a.close(()=>{process.exit(0)})};process.on("SIGINT",p),process.on("SIGTERM",p)}catch(r){r&&typeof r=="object"&&"message"in r?c(r.message):c("Failed to preview notification"),process.exit(1)}}function pe(s){let t=s.command("notifications").description("manage email notifications");t.command("preview").description("render a preview of an email template").requiredOption("--template <TEMPLATE_DIR>","path to template directory").option("--context <CONTEXT_FILE>","path to email rendering context JSON file").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await $t(r,e.template,e.context)}),t.command("send").description("send a preview of an email template to the logged in admin").requiredOption("--template <TEMPLATE_DIR>","path to template directory").option("--context <CONTEXT_FILE>","path to email rendering context JSON file").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await Nt(r,e.template,e.context)})}import{getListingApprovalStatus as Ft,enableListingApproval as jt,disableListingApproval as Kt}from"sharetribe-flex-build-sdk";async function Ut(s){try{(await Ft(void 0,s)).enabled?console.log(`Listing approvals are enabled in ${s}`):console.log(`Listing approvals are disabled in ${s}`)}catch(t){t&&typeof t=="object"&&"message"in t?c(t.message):c("Failed to get listing approval status"),process.exit(1)}}async function Vt(s){try{await jt(void 0,s),console.log(`Successfully enabled listing approvals in ${s}`)}catch(t){t&&typeof t=="object"&&"message"in t?c(t.message):c("Failed to enable listing approvals"),process.exit(1)}}async function Ht(s){try{await Kt(void 0,s),console.log(`Successfully disabled listing approvals in ${s}`)}catch(t){t&&typeof t=="object"&&"message"in t?c(t.message):c("Failed to disable listing approvals"),process.exit(1)}}function me(s){let t=s.command("listing-approval").description("manage listing approvals (DEPRECATED - use Console instead)").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier");t.action(async e=>{console.warn("Warning: CLI command `listing-approval` is deprecated. Use Console instead.");let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await Ut(r)}),t.command("enable").description("enable listing approvals").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{console.warn("Warning: CLI command `listing-approval` is deprecated. Use Console instead.");let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await Vt(r)}),t.command("disable").description("disable listing approvals").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{console.warn("Warning: CLI command `listing-approval` is deprecated. Use Console instead.");let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await Ht(r)})}import{queryEvents as Jt,pollEvents as Bt}from"sharetribe-flex-build-sdk";function de(s){if([s.sequenceId!==void 0,s.afterSeqId!==void 0,s.beforeSeqId!==void 0,s.afterTs!==void 0,s.beforeTs!==void 0].filter(Boolean).length>1)throw new Error("Only one of --seqid, --after-seqid, --before-seqid, --after-ts, or --before-ts can be specified");if(s.resourceId&&s.relatedResourceId)throw new Error("Only one of --resource or --related-resource can be specified")}function ue(s){try{let t=new Date(s),e=t.getFullYear(),r=String(t.getMonth()+1).padStart(2,"0"),o=String(t.getDate()).padStart(2,"0"),n=t.toLocaleTimeString("en-US");return`${e}-${r}-${o} ${n}`}catch{return s}}async function Wt(s,t){try{de(t);let e=await Jt(void 0,s,{resourceId:t.resourceId,relatedResourceId:t.relatedResourceId,eventTypes:t.eventTypes,sequenceId:t.sequenceId,afterSeqId:t.afterSeqId,beforeSeqId:t.beforeSeqId,afterTs:t.afterTs,beforeTs:t.beforeTs,limit:t.limit});if(e.length===0){console.log("No events found.");return}if(t.json)for(let r of e){let{auditEmails:o,...n}=r;console.log(JSON.stringify(n))}else if(t.jsonPretty)for(let r of e){let{auditEmails:o,...n}=r;console.log(JSON.stringify(n,null,2))}else C(["Seq ID","Resource ID","Event type","Created at local time","Source","Actor"],e.map(r=>{let o=r.auditEmails?.userEmail||r.auditEmails?.adminEmail||"",n=r.source?.replace("source/","")||"";return{"Seq ID":r.sequenceId.toString(),"Resource ID":r.resourceId,"Event type":r.eventType,"Created at local time":ue(r.createdAt),Source:n,Actor:o}}))}catch(e){e&&typeof e=="object"&&"message"in e?c(e.message):c("Failed to query events"),process.exit(1)}}async function Gt(s,t){try{de(t),console.log("Tailing events... Press Ctrl+C to stop"),console.log("");let e=Bt(void 0,s,{resourceId:t.resourceId,relatedResourceId:t.relatedResourceId,eventTypes:t.eventTypes,limit:t.limit||10},o=>{if(t.json)for(let n of o){let{auditEmails:i,...a}=n;console.log(JSON.stringify(a))}else if(t.jsonPretty)for(let n of o){let{auditEmails:i,...a}=n;console.log(JSON.stringify(a,null,2))}else C(["Seq ID","Resource ID","Event type","Created at local time","Source","Actor"],o.map(n=>{let i=n.auditEmails?.userEmail||n.auditEmails?.adminEmail||"",a=n.source?.replace("source/","")||"";return{"Seq ID":n.sequenceId.toString(),"Resource ID":n.resourceId,"Event type":n.eventType,"Created at local time":ue(n.createdAt),Source:a,Actor:i}}))},5e3),r=()=>{console.log(`
18
- Stopping tail...`),e(),process.exit(0)};process.on("SIGINT",r),process.on("SIGTERM",r)}catch(e){e&&typeof e=="object"&&"message"in e?c(e.message):c("Failed to tail events"),process.exit(1)}}function fe(s){let t=s.command("events").description("Get a list of events.").option("--resource <RESOURCE_ID>","show events for specific resource ID").option("--related-resource <RELATED_RESOURCE_ID>","show events related to specific resource ID").option("--filter <EVENT_TYPES>","filter by event types (comma-separated)").option("--seqid <SEQUENCE_ID>","get event with specific sequence ID",parseInt).option("--after-seqid <SEQUENCE_ID>","show events after sequence ID (exclusive)",parseInt).option("--before-seqid <SEQUENCE_ID>","show events before sequence ID (exclusive)",parseInt).option("--after-ts <TIMESTAMP>","show events after timestamp").option("--before-ts <TIMESTAMP>","show events before timestamp").option("-l, --limit <NUMBER>","limit results (default: 100, max: 100)",parseInt).option("--json","output as single-line JSON strings").option("--json-pretty","output as indented multi-line JSON").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier");t.action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Could not parse arguments:"),console.error("--marketplace is required"),process.exit(1)),await Wt(r,{resourceId:e.resource,relatedResourceId:e.relatedResource,eventTypes:e.filter,sequenceId:e.seqid,afterSeqId:e.afterSeqid,beforeSeqId:e.beforeSeqid,afterTs:e.afterTs,beforeTs:e.beforeTs,limit:e.limit||100,json:e.json,jsonPretty:e.jsonPretty})}),t.command("tail").description("Tail events live as they happen").option("--resource <RESOURCE_ID>","show events for specific resource ID").option("--related-resource <RELATED_RESOURCE_ID>","show events related to specific resource ID").option("--filter <EVENT_TYPES>","filter by event types (comma-separated)").option("-l, --limit <NUMBER>","limit results per poll (default: 10, max: 100)",parseInt).option("--json","output as single-line JSON strings").option("--json-pretty","output as indented multi-line JSON").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Could not parse arguments:"),console.error("--marketplace is required"),process.exit(1)),await Gt(r,{resourceId:e.resource,relatedResourceId:e.relatedResource,eventTypes:e.filter,limit:e.limit||10,json:e.json,jsonPretty:e.jsonPretty})})}import{updateStripeVersion as Qt,SUPPORTED_STRIPE_VERSIONS as Yt}from"sharetribe-flex-build-sdk";import he from"inquirer";async function zt(){return(await he.prompt([{type:"list",name:"version",message:"Select Stripe API version:",choices:[...Yt]}])).version}async function Zt(){return console.log(""),console.log("WARNING: Changing Stripe API version may affect your integration."),console.log(""),console.log("After updating the Stripe API version, you may need to:"),console.log("- Handle new Capabilities requirements"),console.log("- Update identity verification settings"),console.log(""),console.log("See Stripe documentation for details:"),console.log("https://stripe.com/docs/connect/capabilities-overview"),console.log("https://stripe.com/docs/connect/identity-verification"),console.log(""),(await he.prompt([{type:"confirm",name:"confirmed",message:"Do you want to continue?",default:!1}])).confirmed}async function Xt(s,t,e){try{let r=t;r||(r=await zt()),e||await Zt()||(console.log("Cancelled."),process.exit(0)),await Qt(void 0,s,r),console.log(`Stripe API version successfully changed to ${r}`)}catch(r){r&&typeof r=="object"&&"message"in r?c(r.message):c("Failed to update Stripe API version"),process.exit(1)}}function ge(s){s.command("stripe").description("manage Stripe integration").command("update-version").description("update Stripe API version in use").option("--version <VERSION>","Stripe API version to update to").option("-f, --force","skip confirmation prompt and force update").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await Xt(r,e.version,e.force)})}import{getConfigMap as er,readAuth as tr}from"sharetribe-flex-build-sdk";function rr(s){return s.length<=4?`...${s}`:`...${s.slice(-4)}`}function ye(){let s=tr(),t=s?.apiKey?rr(s.apiKey):"No API key set",e=er(),r=Object.keys(e).sort().map(n=>`:${n} ${e[n]}`).join(" "),o=r?`{${r}}`:"{}";console.log(`{:api-key ${t}, :conf-map ${o}}`)}function sr(s){let t=[],e=!s.parent,r=s.description();if(r&&(t.push(r),t.push("")),e){let a=s.version();a&&(t.push("VERSION"),t.push(` ${a}`),t.push(""))}t.push("USAGE");let o=or(s);t.push(` $ ${o}`),t.push("");let n=Se(s),i=s.options.length>0&&!e;if(n.length>0&&!i){t.push("COMMANDS");let a=Math.max(...n.map(p=>p.name.length));for(let p of n){let l=p.name.padEnd(a+2);t.push(` ${l}${p.description}`)}t.push("")}if(!e){let a=s.options;if(a.length>0){t.push("OPTIONS");let p=Math.max(...a.map(l=>Ee(l).length));for(let l of a){let u=Ee(l).padEnd(p+2),f=l.description||"";t.push(` ${u}${f}`)}t.push("")}}if(n.length>0&&!i){t.push("Subcommand help:");let a=Ae(s);t.push(` $ ${a} help [COMMAND]`)}return t.push(""),t.join(`
19
- `)}function Se(s){let t=[],e=s.commands.filter(r=>!r._hidden&&r.name()!=="help");for(let r of e){let o=nr(r),n=r.commands.filter(i=>!i._hidden);if(r.description()&&t.push({name:o,description:r.description()||""}),n.length>0){let i=Se(r);for(let a of i)t.push(a)}}return s.parent||t.unshift({name:"help",description:"display help for Flex CLI"}),t.sort((r,o)=>r.name.localeCompare(o.name)),t}function Ae(s){let t=[],e=s;for(;e;)e.name()&&t.unshift(e.name()),e=e.parent;return t.length>0&&(t[0]="sharetribe-cli"),t.join(" ")}function or(s){let t=Ae(s),e=s.commands.filter(n=>!n._hidden),r=s.options.length>0;return!s.parent&&e.length>0?`${t} [COMMAND]`:e.length>0&&!r?`${t} [COMMAND]`:t}function nr(s){let t=[],e=s;for(;e&&e.parent;)e.name()&&t.unshift(e.name()),e=e.parent;return t.join(" ")}function Ee(s){let e=(s.flags||"").split(/,\s*/),r=[];for(let o of e){let n=o.trim(),i=n.match(/^((?:-{1,2}[\w-]+))\s*[<\[]([^\]>]+)[\]>]/);if(i){let a=i[1],p=i[2];r.push(`${a}=${p}`)}else r.push(n)}return r.join(", ")}function ke(s){s.configureHelp({formatHelp:(t,e)=>sr(t)})}function ve(s){let t=s.findIndex(o=>o==="process");if(t===-1)return s;let e=s[t+1];return e&&["list","create","push","pull","create-alias","update-alias","delete-alias","deploy"].includes(e)?[...s.slice(0,t),`process-${e}`,...s.slice(t+2)]:s}var mr=cr(import.meta.url),dr=lr(mr),ur=JSON.parse(ar(pr(dr,"../package.json"),"utf-8"));console.error("\u26A0\uFE0F NOTICE: This is an UNOFFICIAL Sharetribe CLI (community reimplementation).");console.error(` For the official CLI, install: npm install -g flex-cli
20
- `);var we=ve(process.argv),h=new ir;ke(h);h.configureOutput({writeOut:s=>process.stdout.write(s+`
16
+ `}};await i();let a=jt(async(l,m)=>{l.url==="/"||l.url===""?(await i(),m.writeHead(200,{"Content-Type":"text/html"}),m.end(n)):(m.writeHead(404,{"Content-Type":"text/plain"}),m.end("Not Found"))});a.listen(3535,()=>{console.log("Preview server started. Open http://localhost:3535 in your browser.")});let p=()=>{console.log(`
17
+ Shutting down preview server...`),a.close(()=>{process.exit(0)})};process.on("SIGINT",p),process.on("SIGTERM",p)}catch(r){r&&typeof r=="object"&&"message"in r?c(r.message):c("Failed to preview notification"),process.exit(1)}}function de(s){let t=s.command("notifications").description("manage email notifications");t.command("preview").description("render a preview of an email template").requiredOption("--template <TEMPLATE_DIR>","path to template directory").option("--context <CONTEXT_FILE>","path to email rendering context JSON file").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await Ut(r,e.template,e.context)}),t.command("send").description("send a preview of an email template to the logged in admin").requiredOption("--template <TEMPLATE_DIR>","path to template directory").option("--context <CONTEXT_FILE>","path to email rendering context JSON file").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await Kt(r,e.template,e.context)})}import{getListingApprovalStatus as Vt,enableListingApproval as Ht,disableListingApproval as Jt}from"sharetribe-flex-build-sdk";async function Bt(s){try{(await Vt(void 0,s)).enabled?console.log(`Listing approvals are enabled in ${s}`):console.log(`Listing approvals are disabled in ${s}`)}catch(t){t&&typeof t=="object"&&"message"in t?c(t.message):c("Failed to get listing approval status"),process.exit(1)}}async function Wt(s){try{await Ht(void 0,s),console.log(`Successfully enabled listing approvals in ${s}`)}catch(t){t&&typeof t=="object"&&"message"in t?c(t.message):c("Failed to enable listing approvals"),process.exit(1)}}async function Gt(s){try{await Jt(void 0,s),console.log(`Successfully disabled listing approvals in ${s}`)}catch(t){t&&typeof t=="object"&&"message"in t?c(t.message):c("Failed to disable listing approvals"),process.exit(1)}}function ue(s){let t=s.command("listing-approval").description("manage listing approvals (DEPRECATED - use Console instead)").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier");t.action(async e=>{console.warn("Warning: CLI command `listing-approval` is deprecated. Use Console instead.");let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await Bt(r)}),t.command("enable").description("enable listing approvals").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{console.warn("Warning: CLI command `listing-approval` is deprecated. Use Console instead.");let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await Wt(r)}),t.command("disable").description("disable listing approvals").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{console.warn("Warning: CLI command `listing-approval` is deprecated. Use Console instead.");let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await Gt(r)})}import{queryEvents as Qt,pollEvents as Yt}from"sharetribe-flex-build-sdk";function fe(s){if([s.sequenceId!==void 0,s.afterSeqId!==void 0,s.beforeSeqId!==void 0,s.afterTs!==void 0,s.beforeTs!==void 0].filter(Boolean).length>1)throw new Error("Only one of --seqid, --after-seqid, --before-seqid, --after-ts, or --before-ts can be specified");if(s.resourceId&&s.relatedResourceId)throw new Error("Only one of --resource or --related-resource can be specified")}function he(s){try{let t=new Date(s),e=t.getFullYear(),r=String(t.getMonth()+1).padStart(2,"0"),o=String(t.getDate()).padStart(2,"0"),n=t.toLocaleTimeString("en-US");return`${e}-${r}-${o} ${n}`}catch{return s}}async function zt(s,t){try{fe(t);let e=await Qt(void 0,s,{resourceId:t.resourceId,relatedResourceId:t.relatedResourceId,eventTypes:t.eventTypes,sequenceId:t.sequenceId,afterSeqId:t.afterSeqId,beforeSeqId:t.beforeSeqId,afterTs:t.afterTs,beforeTs:t.beforeTs,limit:t.limit});if(e.length===0){console.log("No events found.");return}if(t.json)for(let r of e){let{auditEmails:o,...n}=r;console.log(JSON.stringify(n))}else if(t.jsonPretty)for(let r of e){let{auditEmails:o,...n}=r;console.log(JSON.stringify(n,null,2))}else C(["Seq ID","Resource ID","Event type","Created at local time","Source","Actor"],e.map(r=>{let o=r.auditEmails?.userEmail||r.auditEmails?.adminEmail||"",n=r.source?.replace("source/","")||"";return{"Seq ID":r.sequenceId.toString(),"Resource ID":r.resourceId,"Event type":r.eventType,"Created at local time":he(r.createdAt),Source:n,Actor:o}}))}catch(e){e&&typeof e=="object"&&"message"in e?c(e.message):c("Failed to query events"),process.exit(1)}}async function Zt(s,t){try{fe(t),console.log("Tailing events... Press Ctrl+C to stop"),console.log("");let e=Yt(void 0,s,{resourceId:t.resourceId,relatedResourceId:t.relatedResourceId,eventTypes:t.eventTypes,limit:t.limit||10},o=>{if(t.json)for(let n of o){let{auditEmails:i,...a}=n;console.log(JSON.stringify(a))}else if(t.jsonPretty)for(let n of o){let{auditEmails:i,...a}=n;console.log(JSON.stringify(a,null,2))}else C(["Seq ID","Resource ID","Event type","Created at local time","Source","Actor"],o.map(n=>{let i=n.auditEmails?.userEmail||n.auditEmails?.adminEmail||"",a=n.source?.replace("source/","")||"";return{"Seq ID":n.sequenceId.toString(),"Resource ID":n.resourceId,"Event type":n.eventType,"Created at local time":he(n.createdAt),Source:a,Actor:i}}))},5e3),r=()=>{console.log(`
18
+ Stopping tail...`),e(),process.exit(0)};process.on("SIGINT",r),process.on("SIGTERM",r)}catch(e){e&&typeof e=="object"&&"message"in e?c(e.message):c("Failed to tail events"),process.exit(1)}}function ge(s){let t=s.command("events").description("Get a list of events.").option("--resource <RESOURCE_ID>","show events for specific resource ID").option("--related-resource <RELATED_RESOURCE_ID>","show events related to specific resource ID").option("--filter <EVENT_TYPES>","filter by event types (comma-separated)").option("--seqid <SEQUENCE_ID>","get event with specific sequence ID",parseInt).option("--after-seqid <SEQUENCE_ID>","show events after sequence ID (exclusive)",parseInt).option("--before-seqid <SEQUENCE_ID>","show events before sequence ID (exclusive)",parseInt).option("--after-ts <TIMESTAMP>","show events after timestamp").option("--before-ts <TIMESTAMP>","show events before timestamp").option("-l, --limit <NUMBER>","limit results (default: 100, max: 100)",parseInt).option("--json","output as single-line JSON strings").option("--json-pretty","output as indented multi-line JSON").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier");t.action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Could not parse arguments:"),console.error("--marketplace is required"),process.exit(1)),await zt(r,{resourceId:e.resource,relatedResourceId:e.relatedResource,eventTypes:e.filter,sequenceId:e.seqid,afterSeqId:e.afterSeqid,beforeSeqId:e.beforeSeqid,afterTs:e.afterTs,beforeTs:e.beforeTs,limit:e.limit||100,json:e.json,jsonPretty:e.jsonPretty})}),t.command("tail").description("Tail events live as they happen").option("--resource <RESOURCE_ID>","show events for specific resource ID").option("--related-resource <RELATED_RESOURCE_ID>","show events related to specific resource ID").option("--filter <EVENT_TYPES>","filter by event types (comma-separated)").option("-l, --limit <NUMBER>","limit results per poll (default: 10, max: 100)",parseInt).option("--json","output as single-line JSON strings").option("--json-pretty","output as indented multi-line JSON").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Could not parse arguments:"),console.error("--marketplace is required"),process.exit(1)),await Zt(r,{resourceId:e.resource,relatedResourceId:e.relatedResource,eventTypes:e.filter,limit:e.limit||10,json:e.json,jsonPretty:e.jsonPretty})})}import{updateStripeVersion as Xt,SUPPORTED_STRIPE_VERSIONS as er}from"sharetribe-flex-build-sdk";import ye from"inquirer";async function tr(){return(await ye.prompt([{type:"list",name:"version",message:"Select Stripe API version:",choices:[...er]}])).version}async function rr(){return console.log(""),console.log("WARNING: Changing Stripe API version may affect your integration."),console.log(""),console.log("After updating the Stripe API version, you may need to:"),console.log("- Handle new Capabilities requirements"),console.log("- Update identity verification settings"),console.log(""),console.log("See Stripe documentation for details:"),console.log("https://stripe.com/docs/connect/capabilities-overview"),console.log("https://stripe.com/docs/connect/identity-verification"),console.log(""),(await ye.prompt([{type:"confirm",name:"confirmed",message:"Do you want to continue?",default:!1}])).confirmed}async function sr(s,t,e){try{let r=t;r||(r=await tr()),e||await rr()||(console.log("Cancelled."),process.exit(0)),await Xt(void 0,s,r),console.log(`Stripe API version successfully changed to ${r}`)}catch(r){r&&typeof r=="object"&&"message"in r?c(r.message):c("Failed to update Stripe API version"),process.exit(1)}}function Ee(s){s.command("stripe").description("manage Stripe integration").command("update-version").description("update Stripe API version in use").option("--version <VERSION>","Stripe API version to update to").option("-f, --force","skip confirmation prompt and force update").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier").action(async e=>{let r=e.marketplace||s.opts().marketplace;r||(console.error("Error: --marketplace is required"),process.exit(1)),await sr(r,e.version,e.force)})}import{getConfigMap as or,readAuth as nr}from"sharetribe-flex-build-sdk";function ir(s){return s.length<=4?`...${s}`:`...${s.slice(-4)}`}function Se(){let s=nr(),t=s?.apiKey?ir(s.apiKey):"No API key set",e=or(),r=Object.keys(e).sort().map(n=>`:${n} ${e[n]}`).join(" "),o=r?`{${r}}`:"{}";console.log(`{:api-key ${t}, :conf-map ${o}}`)}function ar(s){let t=[],e=!s.parent,r=s.description();if(r&&(t.push(r),t.push("")),e){let a=s.version();a&&(t.push("VERSION"),t.push(` ${a}`),t.push(""))}t.push("USAGE");let o=cr(s);t.push(` $ ${o}`),t.push("");let n=Ae(s),i=s.options.length>0&&!e;if(n.length>0&&!i){t.push("COMMANDS");let a=Math.max(...n.map(p=>p.name.length));for(let p of n){let l=p.name.padEnd(a+2);t.push(` ${l}${p.description}`)}t.push("")}if(!e){let a=s.options;if(a.length>0){t.push("OPTIONS");let p=Math.max(...a.map(l=>ke(l).length));for(let l of a){let u=ke(l).padEnd(p+2),f=l.description||"";t.push(` ${u}${f}`)}t.push("")}}if(n.length>0&&!i){t.push("Subcommand help:");let a=ve(s);t.push(` $ ${a} help [COMMAND]`)}return t.push(""),t.join(`
19
+ `)}function Ae(s){let t=[],e=s.commands.filter(r=>!r._hidden&&r.name()!=="help");for(let r of e){let o=lr(r),n=r.commands.filter(i=>!i._hidden);if(r.description()&&t.push({name:o,description:r.description()||""}),n.length>0){let i=Ae(r);for(let a of i)t.push(a)}}return s.parent||t.unshift({name:"help",description:"display help for Flex CLI"}),t.sort((r,o)=>r.name.localeCompare(o.name)),t}function ve(s){let t=[],e=s;for(;e;)e.name()&&t.unshift(e.name()),e=e.parent;return t.length>0&&(t[0]="sharetribe-cli"),t.join(" ")}function cr(s){let t=ve(s),e=s.commands.filter(n=>!n._hidden),r=s.options.length>0;return!s.parent&&e.length>0?`${t} [COMMAND]`:e.length>0&&!r?`${t} [COMMAND]`:t}function lr(s){let t=[],e=s;for(;e&&e.parent;)e.name()&&t.unshift(e.name()),e=e.parent;return t.join(" ")}function ke(s){let e=(s.flags||"").split(/,\s*/),r=[];for(let o of e){let n=o.trim(),i=n.match(/^((?:-{1,2}[\w-]+))\s*[<\[]([^\]>]+)[\]>]/);if(i){let a=i[1],p=i[2];r.push(`${a}=${p}`)}else r.push(n)}return r.join(", ")}function we(s){s.configureHelp({formatHelp:(t,e)=>ar(t)})}function Ce(s){let t=s.findIndex(o=>o==="process");if(t===-1)return s;let e=s[t+1];return e&&["list","create","push","pull","create-alias","update-alias","delete-alias","deploy"].includes(e)?[...s.slice(0,t),`process-${e}`,...s.slice(t+2)]:s}var Er=hr(import.meta.url),Sr=gr(Er),kr=JSON.parse(mr(H(Sr,"../package.json"),"utf-8")),be=H(yr(),".config","flex-cli"),Pe=H(be,".sharetribe-cli-notice-shown");if(!dr(Pe)){console.error(V.yellow("\u26A0\uFE0F NOTICE: This is an UNOFFICIAL Sharetribe CLI (community reimplementation).")),console.error(V.yellow(" For the official CLI, install: ")+V.cyan("npm install -g flex-cli")+`
20
+ `);try{fr(be,{recursive:!0}),ur(Pe,new Date().toISOString())}catch{}}var Ie=Ce(process.argv),h=new pr;we(h);h.configureOutput({writeOut:s=>process.stdout.write(s+`
21
21
  `),writeErr:s=>process.stderr.write(s+`
22
- `)});h.name("sharetribe-cli").description("CLI to interact with Sharetribe Flex").version(ur.version,"-V","output the version number").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier");h.command("version").description("show version").action(()=>{H()});h.command("login").description("log in with API key").action(async()=>{await J()});h.command("logout").description("logout").action(async()=>{await B()});h.command("debug").description("display debug info").action(()=>{ye()});W(h);Q(h);ie(h);pe(h);me(h);fe(h);ge(h);h.command("help [command...]").description("display help for Flex CLI").action(s=>{if(!s||s.length===0){h.outputHelp();return}let t=h;for(let e of s){let r=t.commands.find(o=>o.name()===e);r||(console.error(`Unknown command: ${s.join(" ")}`),process.exit(1)),t=r}t.outputHelp()});we.slice(2).length?h.parse(we):h.outputHelp();
22
+ `)});h.name("sharetribe-cli").description("CLI to interact with Sharetribe Flex").version(kr.version,"-V","output the version number").option("-m, --marketplace <MARKETPLACE_ID>","marketplace identifier");h.command("version").description("show version").action(()=>{B()});h.command("login").description("log in with API key").action(async()=>{await W()});h.command("logout").description("logout").action(async()=>{await G()});h.command("debug").description("display debug info").action(()=>{Se()});Q(h);z(h);ce(h);de(h);ue(h);ge(h);Ee(h);h.command("help [command...]").description("display help for Flex CLI").action(s=>{if(!s||s.length===0){h.outputHelp();return}let t=h;for(let e of s){let r=t.commands.find(o=>o.name()===e);r||(console.error(`Unknown command: ${s.join(" ")}`),process.exit(1)),t=r}t.outputHelp()});Ie.slice(2).length?h.parse(Ie):h.outputHelp();
23
23
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts", "../src/commands/version.ts", "../src/commands/login.ts", "../src/commands/logout.ts", "../src/commands/process/list.ts", "../src/util/output.ts", "../src/commands/process/create.ts", "../src/commands/process/push.ts", "../src/commands/process/pull.ts", "../src/commands/process/aliases.ts", "../src/commands/process/combined.ts", "../src/commands/process/index.ts", "../src/commands/search/index.ts", "../src/commands/assets/index.ts", "../src/commands/notifications/index.ts", "../src/commands/listing-approval.ts", "../src/commands/events/index.ts", "../src/commands/stripe/index.ts", "../src/commands/debug.ts", "../src/util/help-formatter.ts", "../src/util/command-router.ts"],
4
- "sourcesContent": ["/**\n * Sharetribe CLI - Unofficial 100% compatible implementation\n *\n * Main entry point for the CLI application\n */\n\nimport { Command } from 'commander';\nimport { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport { version } from './commands/version.js';\nimport { login } from './commands/login.js';\nimport { logout } from './commands/logout.js';\nimport { registerProcessCommands } from './commands/process/index.js';\nimport { registerSearchCommands } from './commands/search/index.js';\nimport { registerAssetsCommands } from './commands/assets/index.js';\nimport { registerNotificationsCommands } from './commands/notifications/index.js';\nimport { registerListingApprovalCommand } from './commands/listing-approval.js';\nimport { registerEventsCommand } from './commands/events/index.js';\nimport { registerStripeCommands } from './commands/stripe/index.js';\nimport { debug } from './commands/debug.js';\nimport { configureHelp } from './util/help-formatter.js';\nimport { routeProcessCommand } from './util/command-router.js';\n\n// Get package.json for version info\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst packageJson = JSON.parse(\n readFileSync(join(__dirname, '../package.json'), 'utf-8')\n);\n\n// Print unofficial notice to stderr on every run\nconsole.error('\u26A0\uFE0F NOTICE: This is an UNOFFICIAL Sharetribe CLI (community reimplementation).');\nconsole.error(' For the official CLI, install: npm install -g flex-cli\\n');\n\n// Route argv to handle process subcommands\nconst routedArgv = routeProcessCommand(process.argv);\n\nconst program = new Command();\n\n// Configure custom help formatter to match flex-cli\nconfigureHelp(program);\n\n// Configure output to add trailing newline (flex-cli behavior)\nprogram.configureOutput({\n writeOut: (str) => process.stdout.write(str + '\\n'),\n writeErr: (str) => process.stderr.write(str + '\\n'),\n});\n\n// Configure the main program\nprogram\n .name('sharetribe-cli')\n .description('CLI to interact with Sharetribe Flex')\n .version(packageJson.version, '-V', 'output the version number')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier');\n\n// Register commands\n\n// version command\nprogram\n .command('version')\n .description('show version')\n .action(() => {\n version();\n });\n\n// login command\nprogram\n .command('login')\n .description('log in with API key')\n .action(async () => {\n await login();\n });\n\n// logout command\nprogram\n .command('logout')\n .description('logout')\n .action(async () => {\n await logout();\n });\n\n// debug command\nprogram\n .command('debug')\n .description('display debug info')\n .action(() => {\n debug();\n });\n\n// Register process commands\nregisterProcessCommands(program);\n\n// Register search commands\nregisterSearchCommands(program);\n\n// Register assets commands\nregisterAssetsCommands(program);\n\n// Register notifications commands\nregisterNotificationsCommands(program);\n\n// Register listing-approval command\nregisterListingApprovalCommand(program);\n\n// Register events command\nregisterEventsCommand(program);\n\n// Register stripe commands\nregisterStripeCommands(program);\n\n// Register custom help command (to support \"help process list\" syntax)\nprogram\n .command('help [command...]')\n .description('display help for Flex CLI')\n .action((commandPath: string[]) => {\n if (!commandPath || commandPath.length === 0) {\n program.outputHelp();\n return;\n }\n\n // Navigate to the nested command\n let targetCmd: Command = program;\n for (const cmdName of commandPath) {\n const subCmd = targetCmd.commands.find(c => c.name() === cmdName);\n if (!subCmd) {\n console.error(`Unknown command: ${commandPath.join(' ')}`);\n process.exit(1);\n }\n targetCmd = subCmd;\n }\n\n // Show help for the target command\n targetCmd.outputHelp();\n });\n\n// If no command specified, show help and exit with status 0\nif (!routedArgv.slice(2).length) {\n program.outputHelp();\n // Don't call process.exit() - let Commander handle it naturally with exitOverride\n} else {\n // Parse command line arguments with routed argv\n program.parse(routedArgv);\n}\n", "/**\n * Version command - displays the CLI version\n *\n * Must match flex-cli output format exactly\n */\n\nimport { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\n\n/**\n * Finds package.json by traversing up from current file\n */\nfunction findPackageJson(): string {\n const __filename = fileURLToPath(import.meta.url);\n let currentDir = dirname(__filename);\n\n // Traverse up to find package.json\n while (currentDir !== '/') {\n try {\n const pkgPath = join(currentDir, 'package.json');\n const content = readFileSync(pkgPath, 'utf-8');\n return content;\n } catch {\n currentDir = dirname(currentDir);\n }\n }\n\n throw new Error('Could not find package.json');\n}\n\n/**\n * Displays the version of the CLI\n *\n * Output must match flex-cli exactly\n */\nexport function version(): void {\n const packageJson = JSON.parse(findPackageJson());\n console.log(packageJson.version);\n}\n", "/**\n * Login command - interactive API key authentication\n *\n * Must match flex-cli behavior exactly:\n * - Prompt for API key\n * - Store in ~/.config/flex-cli/auth.edn\n * - Display admin email on success\n */\n\nimport inquirer from 'inquirer';\nimport { writeAuth } from 'sharetribe-flex-build-sdk';\n\n/**\n * Executes the login command\n *\n * Prompts for API key and stores it in auth.edn\n */\nexport async function login(): Promise<void> {\n const answers = await inquirer.prompt([\n {\n type: 'password',\n name: 'apiKey',\n message: 'Enter API key:',\n mask: '*',\n validate: (input: string) => {\n if (!input || input.trim().length === 0) {\n return 'API key cannot be empty';\n }\n return true;\n },\n },\n ]);\n\n // Store the API key\n writeAuth({ apiKey: answers.apiKey });\n\n // TODO: Validate API key by making a test request to get admin email\n // For now, just confirm storage\n console.log('Successfully logged in.');\n\n // Note: flex-cli displays admin email after successful login\n // We'll need to implement API client to fetch this\n}\n", "/**\n * Logout command - clears authentication\n *\n * Must match flex-cli behavior exactly\n */\n\nimport { clearAuth } from 'sharetribe-flex-build-sdk';\n\n/**\n * Executes the logout command\n *\n * Clears auth.edn file\n */\nexport async function logout(): Promise<void> {\n await clearAuth();\n console.log('Successfully logged out.');\n}\n", "/**\n * Process list command - lists all transaction processes\n */\n\nimport {\n listProcesses as sdkListProcesses,\n listProcessVersions as sdkListProcessVersions,\n} from 'sharetribe-flex-build-sdk';\nimport { printTable, printError } from '../../util/output.js';\n\n\n/**\n * Formats timestamp to match flex-cli format for process list\n */\nfunction formatProcessTimestamp(timestamp: string): string {\n try {\n const date = new Date(timestamp);\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const timeString = date.toLocaleTimeString('en-US');\n\n return `${year}-${month}-${day} ${timeString}`;\n } catch {\n return timestamp;\n }\n}\n\n/**\n * Lists all processes for a marketplace\n */\nexport async function listProcesses(marketplace: string, processName?: string): Promise<void> {\n try {\n // If processName is specified, show version history for that process\n if (processName) {\n const versions = await sdkListProcessVersions(undefined, marketplace, processName);\n\n if (versions.length === 0) {\n console.log(`No versions found for process: ${processName}`);\n return;\n }\n\n const versionRows = versions.map((v) => ({\n 'Created': formatProcessTimestamp(v.createdAt),\n 'Version': v.version.toString(),\n 'Aliases': v.aliases?.join(', ') || '',\n 'Transactions': v.transactionCount?.toString() || '0',\n }));\n\n printTable(['Created', 'Version', 'Aliases', 'Transactions'], versionRows);\n } else {\n // List all processes\n const processes = await sdkListProcesses(undefined, marketplace);\n\n if (processes.length === 0) {\n console.log('No processes found.');\n return;\n }\n\n const processRows = processes.map((p) => ({\n 'Name': p.name,\n 'Latest version': p.version?.toString() || '',\n }));\n\n printTable(['Name', 'Latest version'], processRows);\n }\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to list processes');\n }\n process.exit(1);\n }\n}\n", "/**\n * Output formatting utilities\n *\n * Must match flex-cli output format exactly\n */\n\nimport chalk from 'chalk';\n\n/**\n * Prints a table with headers and rows\n *\n * Matches flex-cli table formatting exactly\n */\nexport function printTable(headers: string[], rows: Array<Record<string, string>>): void {\n if (rows.length === 0) {\n return;\n }\n\n // Calculate column widths\n // flex-cli uses keywords (e.g., :version) which when stringified include the ':' prefix\n // To match flex-cli widths, we add 1 to header length to simulate the ':' prefix\n const widths: Record<string, number> = {};\n for (const header of headers) {\n widths[header] = header.length + 1; // +1 to match flex-cli keyword string behavior\n }\n\n for (const row of rows) {\n for (const header of headers) {\n const value = row[header] || '';\n widths[header] = Math.max(widths[header] || 0, value.length);\n }\n }\n\n // Print empty line before table (like flex-cli)\n console.log('');\n\n // Print header with bold formatting\n // flex-cli format: each column padded to (max_width + 1), with single space separator between columns\n // Last column: padding but no separator (interpose doesn't add separator after last element)\n const headerParts = headers.map((h, i) => {\n const width = widths[h] || 0;\n const padded = h.padEnd(width + 1);\n return i === headers.length - 1 ? padded : padded + ' ';\n });\n const headerRow = headerParts.join('');\n console.log(chalk.bold.black(headerRow));\n\n // Print rows with same formatting\n for (const row of rows) {\n const rowParts = headers.map((h, i) => {\n const value = row[h] || '';\n const width = widths[h] || 0;\n const padded = value.padEnd(width + 1);\n return i === headers.length - 1 ? padded : padded + ' ';\n });\n const rowStr = rowParts.join('');\n console.log(rowStr);\n }\n\n // Print empty line after table (like flex-cli)\n console.log('');\n}\n\n/**\n * Prints an error message\n */\nexport function printError(message: string): void {\n console.error(chalk.red(`Error: ${message}`));\n}\n\n/**\n * Prints a success message\n */\nexport function printSuccess(message: string): void {\n console.log(chalk.green(message));\n}\n\n/**\n * Prints a warning message\n */\nexport function printWarning(message: string): void {\n console.log(chalk.yellow(`Warning: ${message}`));\n}\n", "/**\n * Process create command\n */\n\nimport { createProcess as sdkCreateProcess } from 'sharetribe-flex-build-sdk';\nimport { printError, printSuccess } from '../../util/output.js';\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/**\n * Creates a new transaction process\n */\nexport async function createProcess(\n marketplace: string,\n processName: string,\n path: string\n): Promise<void> {\n try {\n const processFilePath = join(path, 'process.edn');\n const processContent = readFileSync(processFilePath, 'utf-8');\n\n const result = await sdkCreateProcess(undefined, marketplace, processName, processContent);\n\n printSuccess(\n `Process ${result.name} successfully created with version ${result.version}.`\n );\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to create process');\n }\n process.exit(1);\n }\n}\n", "/**\n * Process push command\n */\n\nimport { pushProcess as sdkPushProcess } from 'sharetribe-flex-build-sdk';\nimport { printError, printSuccess } from '../../util/output.js';\nimport { readFileSync, readdirSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/**\n * Reads email templates from the templates directory\n */\nfunction readTemplates(path: string): Array<{ name: string; html: string; subject: string }> {\n const templatesDir = join(path, 'templates');\n const templates: Array<{ name: string; html: string; subject: string }> = [];\n\n try {\n const templateDirs = readdirSync(templatesDir);\n for (const templateName of templateDirs) {\n const templatePath = join(templatesDir, templateName);\n const htmlFile = join(templatePath, `${templateName}-html.html`);\n const subjectFile = join(templatePath, `${templateName}-subject.txt`);\n\n try {\n const html = readFileSync(htmlFile, 'utf-8');\n const subject = readFileSync(subjectFile, 'utf-8');\n templates.push({ name: templateName, html, subject });\n } catch {\n // Skip if files don't exist\n }\n }\n } catch {\n // No templates directory - return empty array\n }\n\n return templates;\n}\n\n/**\n * Pushes a new version of an existing process\n */\nexport async function pushProcess(\n marketplace: string,\n processName: string,\n path: string\n): Promise<void> {\n try {\n const processFilePath = join(path, 'process.edn');\n const processContent = readFileSync(processFilePath, 'utf-8');\n const templates = readTemplates(path);\n\n const result = await sdkPushProcess(undefined, marketplace, processName, processContent, templates);\n\n if (result.noChanges) {\n console.log('No changes');\n } else {\n printSuccess(`Version ${result.version} successfully saved for process ${processName}.`);\n }\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to push process');\n }\n process.exit(1);\n }\n}\n", "/**\n * Process pull command\n */\n\nimport { getProcess } from 'sharetribe-flex-build-sdk';\nimport { printError, printSuccess } from '../../util/output.js';\nimport { writeFileSync, mkdirSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/**\n * Pulls a process from the server\n */\nexport async function pullProcess(\n marketplace: string,\n processName: string,\n path: string,\n version?: string,\n alias?: string\n): Promise<void> {\n try {\n const process = await getProcess(undefined, marketplace, processName, { version, alias });\n\n if (!process.definition) {\n throw new Error('No process definition in response');\n }\n\n // Ensure directory exists (print message if creating new directory)\n const { existsSync } = await import('node:fs');\n const dirExists = existsSync(path);\n mkdirSync(path, { recursive: true });\n\n if (!dirExists) {\n console.error(`Creating a new directory: ${path}`);\n }\n\n // Write process.edn file\n const processFilePath = join(path, 'process.edn');\n writeFileSync(processFilePath, process.definition, 'utf-8');\n\n // Write email templates if they exist\n const templates = process.emailTemplates || [];\n\n if (templates && Array.isArray(templates) && templates.length > 0) {\n const templatesDir = join(path, 'templates');\n mkdirSync(templatesDir, { recursive: true });\n\n for (const template of templates) {\n const templateName = template.name;\n const htmlContent = template.html;\n const subjectContent = template.subject;\n\n if (templateName) {\n // Create subdirectory for this template\n const templateSubdir = join(templatesDir, templateName);\n mkdirSync(templateSubdir, { recursive: true });\n\n // Write HTML file\n if (htmlContent) {\n const htmlPath = join(templateSubdir, `${templateName}-html.html`);\n writeFileSync(htmlPath, htmlContent, 'utf-8');\n }\n\n // Write subject file\n if (subjectContent) {\n const subjectPath = join(templateSubdir, `${templateName}-subject.txt`);\n writeFileSync(subjectPath, subjectContent, 'utf-8');\n }\n }\n }\n }\n\n console.error(`Saved process to ${path}`);\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to pull process');\n }\n process.exit(1);\n }\n}\n", "/**\n * Process alias commands\n */\n\nimport {\n createAlias as sdkCreateAlias,\n updateAlias as sdkUpdateAlias,\n deleteAlias as sdkDeleteAlias\n} from 'sharetribe-flex-build-sdk';\nimport { printError, printSuccess } from '../../util/output.js';\n\n/**\n * Creates a process alias\n */\nexport async function createAlias(\n marketplace: string,\n processName: string,\n version: number,\n alias: string\n): Promise<void> {\n try {\n const result = await sdkCreateAlias(undefined, marketplace, processName, version, alias);\n\n printSuccess(\n `Alias ${result.alias} successfully created to point to version ${result.version}.`\n );\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to create alias');\n }\n process.exit(1);\n }\n}\n\n/**\n * Updates a process alias\n */\nexport async function updateAlias(\n marketplace: string,\n processName: string,\n version: number,\n alias: string\n): Promise<void> {\n try {\n const result = await sdkUpdateAlias(undefined, marketplace, processName, version, alias);\n\n printSuccess(\n `Alias ${result.alias} successfully updated to point to version ${result.version}.`\n );\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to update alias');\n }\n process.exit(1);\n }\n}\n\n/**\n * Deletes a process alias\n */\nexport async function deleteAlias(\n marketplace: string,\n processName: string,\n alias: string\n): Promise<void> {\n try {\n const result = await sdkDeleteAlias(undefined, marketplace, processName, alias);\n\n printSuccess(`Alias ${result.alias} successfully deleted.`);\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to delete alias');\n }\n process.exit(1);\n }\n}\n", "/**\n * Combined process command - create-or-push-and-create-or-update-alias\n *\n * This is the enhanced \"superset\" feature that combines multiple operations\n * into one atomic command\n */\n\nimport { deployProcess as sdkDeployProcess, parseProcessFile } from 'sharetribe-flex-build-sdk';\nimport { printError, printSuccess } from '../../util/output.js';\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/**\n * Creates or pushes a process and creates or updates an alias\n *\n * This is an atomic operation that:\n * 1. Tries to push a new version (create-version)\n * 2. If process doesn't exist, creates it\n * 3. Then creates or updates the alias\n */\nexport async function createOrPushAndCreateOrUpdateAlias(\n marketplace: string,\n processName: string,\n path: string,\n alias: string\n): Promise<void> {\n try {\n const processFilePath = join(path, 'process.edn');\n const processContent = readFileSync(processFilePath, 'utf-8');\n const processDefinition = parseProcessFile(processContent);\n\n const result = await sdkDeployProcess(\n undefined, // Use auth from file\n marketplace,\n {\n process: processName,\n alias,\n path: processFilePath,\n processDefinition,\n }\n );\n\n if (result.processCreated) {\n printSuccess(`Process ${processName} successfully created.`);\n }\n\n printSuccess(`Version ${result.version} successfully saved for process ${processName}.`);\n\n if (result.aliasCreated) {\n printSuccess(`Alias ${result.alias} successfully created to point to version ${result.version}.`);\n } else {\n printSuccess(`Alias ${result.alias} successfully updated to point to version ${result.version}.`);\n }\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to create/push process and alias');\n }\n process.exit(1);\n }\n}\n", "/**\n * Process command - main entry point for process subcommands\n */\n\nimport { Command } from 'commander';\nimport { listProcesses } from './list.js';\nimport { createProcess } from './create.js';\nimport { pushProcess } from './push.js';\nimport { pullProcess } from './pull.js';\nimport { createAlias, updateAlias, deleteAlias } from './aliases.js';\nimport { createOrPushAndCreateOrUpdateAlias } from './combined.js';\n\n/**\n * Registers all process subcommands\n */\nexport function registerProcessCommands(program: Command): void {\n // Register the parent 'process' command for help display\n const processCmd = program\n .command('process')\n .description('describe a process file')\n .option('--path <PROCESS_DIR>', 'path to the directory where the process.edn file is')\n .option('--transition <TRANSITION_NAME>', 'transition name, e.g. transition/request to get more details of it')\n .action(async (options) => {\n // Process describe functionality\n if (options.path) {\n console.log(`Describing process at: ${options.path}`);\n if (options.transition) {\n console.log(`Transition: ${options.transition}`);\n }\n // TODO: Implement actual process file parsing and description\n console.log('Process description not yet implemented');\n } else {\n // If no options, show help\n processCmd.outputHelp();\n }\n });\n\n // Register subcommands - these are registered as BOTH subcommands (for help) and top-level (for routing)\n\n // process list (as subcommand)\n processCmd\n .command('list')\n .description('list all transaction processes')\n .option('--process <PROCESS_NAME>', 'print version and alias info of a specific process')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await listProcesses(marketplace, options.process);\n });\n\n // process create\n processCmd\n .command('create')\n .description('create a new transaction process')\n .requiredOption('--process <PROCESS_NAME>', 'name for the new process')\n .requiredOption('--path <LOCAL_PROCESS_DIR>', 'path to the directory where the process.edn file is')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await createProcess(marketplace, options.process, options.path);\n });\n\n // process push\n processCmd\n .command('push')\n .description('push a process file to the remote')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--path <LOCAL_PROCESS_DIR>', 'path to the directory where the process.edn file is')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await pushProcess(marketplace, options.process, options.path);\n });\n\n // process pull\n processCmd\n .command('pull')\n .description('fetch a process file')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--path <LOCAL_PROCESS_DIR>', 'path where to save the process')\n .option('--version <VERSION_NUM>', 'version number')\n .option('--alias <PROCESS_ALIAS>', 'alias name')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await pullProcess(marketplace, options.process, options.path, options.version, options.alias);\n });\n\n // process create-alias\n processCmd\n .command('create-alias')\n .description('create a new alias')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--version <VERSION_NUM>', 'version number')\n .requiredOption('--alias <ALIAS>', 'alias name')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .allowUnknownOption(false)\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await createAlias(marketplace, options.process, parseInt(options.version), options.alias);\n });\n\n // process update-alias\n processCmd\n .command('update-alias')\n .description('update an existing alias')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--version <VERSION_NUM>', 'version number')\n .requiredOption('--alias <ALIAS>', 'alias name')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await updateAlias(marketplace, options.process, parseInt(options.version), options.alias);\n });\n\n // process delete-alias\n processCmd\n .command('delete-alias')\n .description('delete an existing alias')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--alias <ALIAS>', 'alias name')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await deleteAlias(marketplace, options.process, options.alias);\n });\n\n // process deploy (combined command: create-or-push-and-create-or-update-alias)\n processCmd\n .command('deploy')\n .description('deploy a process file with alias (create/push + alias create/update)')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--path <LOCAL_PROCESS_DIR>', 'path to the directory with the process files')\n .requiredOption('--alias <ALIAS>', 'alias name')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await createOrPushAndCreateOrUpdateAlias(\n marketplace,\n options.process,\n options.path,\n options.alias\n );\n });\n\n // Register top-level command aliases for routing (hidden from help)\n // These handle the routed commands like 'process-pull' that avoid Commander's parent/child option conflicts\n\n program\n .command('process-list', { hidden: true })\n .description('list all transaction processes')\n .option('--process <PROCESS_NAME>', 'print version and alias info of a specific process')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await listProcesses(marketplace, options.process);\n });\n\n program\n .command('process-create', { hidden: true })\n .description('create a new transaction process')\n .requiredOption('--process <PROCESS_NAME>', 'name for the new process')\n .requiredOption('--path <LOCAL_PROCESS_DIR>', 'path to the directory where the process.edn file is')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await createProcess(marketplace, options.process, options.path);\n });\n\n program\n .command('process-push', { hidden: true })\n .description('push a process file to the remote')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--path <LOCAL_PROCESS_DIR>', 'path to the directory where the process.edn file is')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await pushProcess(marketplace, options.process, options.path);\n });\n\n program\n .command('process-pull', { hidden: true })\n .description('fetch a process file')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--path <LOCAL_PROCESS_DIR>', 'path where to save the process')\n .option('--version <VERSION_NUM>', 'version number')\n .option('--alias <PROCESS_ALIAS>', 'alias name')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await pullProcess(marketplace, options.process, options.path, options.version, options.alias);\n });\n\n program\n .command('process-create-alias', { hidden: true })\n .description('create a new alias')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--version <VERSION_NUM>', 'version number')\n .requiredOption('--alias <ALIAS>', 'alias name')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await createAlias(marketplace, options.process, parseInt(options.version), options.alias);\n });\n\n program\n .command('process-update-alias', { hidden: true })\n .description('update an existing alias')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--version <VERSION_NUM>', 'version number')\n .requiredOption('--alias <ALIAS>', 'alias name')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await updateAlias(marketplace, options.process, parseInt(options.version), options.alias);\n });\n\n program\n .command('process-delete-alias', { hidden: true })\n .description('delete an existing alias')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--alias <ALIAS>', 'alias name')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await deleteAlias(marketplace, options.process, options.alias);\n });\n\n program\n .command('process-deploy', { hidden: true })\n .description('deploy a process file with alias (create/push + alias create/update)')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--path <LOCAL_PROCESS_DIR>', 'path to the directory with the process files')\n .requiredOption('--alias <ALIAS>', 'alias name')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await createOrPushAndCreateOrUpdateAlias(\n marketplace,\n options.process,\n options.path,\n options.alias\n );\n });\n}\n", "/**\n * Search command - manage search schemas\n */\n\nimport { Command } from 'commander';\nimport {\n listSearchSchemas as sdkListSearchSchemas,\n setSearchSchema as sdkSetSearchSchema,\n unsetSearchSchema as sdkUnsetSearchSchema,\n} from 'sharetribe-flex-build-sdk';\nimport { printTable, printError } from '../../util/output.js';\n\ninterface SetSchemaOptions {\n key: string;\n scope: string;\n type: string;\n doc?: string;\n default?: string;\n schemaFor?: string;\n}\n\ninterface UnsetSchemaOptions {\n key: string;\n scope: string;\n schemaFor?: string;\n}\n\n/**\n * Scope label mapping\n */\nconst SCOPE_LABELS: Record<string, string> = {\n metadata: 'Metadata',\n private: 'Private data',\n protected: 'Protected data',\n public: 'Public data',\n};\n\n/**\n * Sets a search schema field\n */\nasync function setSearchSchema(marketplace: string, opts: SetSchemaOptions): Promise<void> {\n try {\n await sdkSetSearchSchema(undefined, marketplace, {\n key: opts.key,\n scope: opts.scope,\n type: opts.type,\n doc: opts.doc,\n defaultValue: opts.default,\n schemaFor: opts.schemaFor,\n });\n\n const schemaFor = opts.schemaFor || 'listing';\n const scopeLabel = SCOPE_LABELS[opts.scope] || opts.scope;\n console.log(`${scopeLabel} schema, ${opts.key} is successfully set for ${schemaFor}.`);\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to set search schema');\n }\n process.exit(1);\n }\n}\n\n/**\n * Unsets a search schema field\n */\nasync function unsetSearchSchema(marketplace: string, opts: UnsetSchemaOptions): Promise<void> {\n try {\n await sdkUnsetSearchSchema(undefined, marketplace, {\n key: opts.key,\n scope: opts.scope,\n schemaFor: opts.schemaFor,\n });\n\n const schemaFor = opts.schemaFor || 'listing';\n const scopeLabel = SCOPE_LABELS[opts.scope] || opts.scope;\n console.log(`${scopeLabel} schema, ${opts.key} is successfully unset for ${schemaFor}.`);\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to unset search schema');\n }\n process.exit(1);\n }\n}\n\n/**\n * Converts default value to display string\n */\nfunction getDefaultValueLabel(value: unknown): string {\n if (value === undefined || value === null) {\n return '';\n }\n\n if (Array.isArray(value)) {\n return value.join(', ');\n }\n\n return String(value);\n}\n\n/**\n * Lists all search schemas\n */\nasync function listSearchSchemas(marketplace: string): Promise<void> {\n try {\n const schemas = await sdkListSearchSchemas(undefined, marketplace);\n\n if (schemas.length === 0) {\n console.log('No search schemas found.');\n return;\n }\n\n // Map and sort the data (by schema-for, scope, key)\n const rows = schemas\n .map((s) => ({\n 'Schema for': s.schemaFor,\n 'Scope': s.scope,\n 'Key': s.key,\n 'Type': s.type,\n 'Default value': getDefaultValueLabel(s.defaultValue),\n 'Doc': s.doc || '',\n }))\n .sort((a, b) => {\n // Sort by schema-for, then scope, then key\n if (a['Schema for'] !== b['Schema for']) {\n return a['Schema for'].localeCompare(b['Schema for']);\n }\n if (a['Scope'] !== b['Scope']) {\n return a['Scope'].localeCompare(b['Scope']);\n }\n return a['Key'].localeCompare(b['Key']);\n });\n\n // Print table using flex-cli compatible formatting\n const headers = ['Schema for', 'Scope', 'Key', 'Type', 'Default value', 'Doc'];\n\n // Calculate column widths\n // flex-cli uses keywords (e.g., :version) which when stringified include the ':' prefix\n // To match flex-cli widths, we add 1 to header length to simulate the ':' prefix\n const widths: Record<string, number> = {};\n for (const h of headers) {\n widths[h] = h.length + 1;\n }\n for (const row of rows) {\n for (const h of headers) {\n const value = row[h] || '';\n widths[h] = Math.max(widths[h], value.length);\n }\n }\n\n // Print empty line before table\n console.log('');\n\n // Print header\n // flex-cli search format: each column padded to max_width, with 2 space separator between columns\n // Last column: padding with trailing space\n const headerParts = headers.map((h, i) => {\n const width = widths[h] || 0;\n const padded = h.padEnd(width);\n return i === headers.length - 1 ? padded + ' ' : padded + ' ';\n });\n console.log(headerParts.join(''));\n\n // Print rows\n for (const row of rows) {\n const rowParts = headers.map((h, i) => {\n const value = row[h] || '';\n const width = widths[h] || 0;\n const padded = value.padEnd(width);\n return i === headers.length - 1 ? padded + ' ' : padded + ' ';\n });\n console.log(rowParts.join(''));\n }\n\n // Print empty line after table\n console.log('');\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to list search schemas');\n }\n process.exit(1);\n }\n}\n\n/**\n * Registers search commands\n */\nexport function registerSearchCommands(program: Command): void {\n const searchCmd = program\n .command('search')\n .description('list all search schemas')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await listSearchSchemas(marketplace);\n });\n\n // search set\n searchCmd\n .command('set')\n .description('set search schema')\n .requiredOption('--key <KEY>', 'key name')\n .requiredOption(\n '--scope <SCOPE>',\n 'extended data scope (either metadata or public for listing schema, metadata, private, protected or public for userProfile schema, metadata or protected for transaction schema)'\n )\n .requiredOption('--type <TYPE>', 'value type (either enum, multi-enum, boolean, long or text)')\n .option('--doc <DOC>', 'description of the schema')\n .option('--default <DEFAULT>', 'default value for search if value is not set')\n .option(\n '--schema-for <SCHEMA_FOR>',\n 'Subject of the schema (either listing, userProfile or transaction, defaults to listing)'\n )\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (opts) => {\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await setSearchSchema(marketplace, {\n key: opts.key,\n scope: opts.scope,\n type: opts.type,\n doc: opts.doc,\n default: opts.default,\n schemaFor: opts.schemaFor,\n });\n });\n\n // search unset\n searchCmd\n .command('unset')\n .description('unset search schema')\n .requiredOption('--key <KEY>', 'key name')\n .requiredOption(\n '--scope <SCOPE>',\n 'extended data scope (either metadata or public for listing schema, metadata, private, protected or public for userProfile schema, metadata or protected for transaction schema)'\n )\n .option(\n '--schema-for <SCHEMA_FOR>',\n 'Subject of the schema (either listing, userProfile or transaction, defaults to listing)'\n )\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (opts) => {\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await unsetSearchSchema(marketplace, {\n key: opts.key,\n scope: opts.scope,\n schemaFor: opts.schemaFor,\n });\n });\n}\n", "/**\n * Assets commands - manage marketplace assets\n */\n\nimport { Command } from 'commander';\nimport {\n pushAssets as sdkPushAssets,\n stageAsset as sdkStageAsset,\n getApiBaseUrl,\n readAuth,\n} from 'sharetribe-flex-build-sdk';\nimport { printError } from '../../util/output.js';\nimport {\n readFileSync,\n writeFileSync,\n existsSync,\n mkdirSync,\n readdirSync,\n statSync,\n unlinkSync,\n createWriteStream,\n} from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { createHash } from 'node:crypto';\nimport * as http from 'node:http';\nimport * as https from 'node:https';\nimport { tmpdir } from 'node:os';\nimport { pipeline } from 'node:stream/promises';\nimport chalk from 'chalk';\nimport edn from 'jsedn';\nimport yauzl from 'yauzl';\n\n\ninterface AssetMetadata {\n version: string;\n assets: Array<{ path: string; 'content-hash': string }>;\n}\n\nconst ASSET_META_FILENAME = 'meta/asset-meta.edn';\nconst ASSETS_DIR = 'assets/';\nconst CLEAR_LINE = '\\x1b[K';\nconst CARRIAGE_RETURN = '\\r';\n\nfunction parseAssetMetadataEdn(content: string): AssetMetadata | null {\n try {\n const parsed = edn.parse(content);\n const version = parsed.at(edn.kw(':version')) || parsed.at(edn.kw(':aliased-version'));\n const assets = parsed.at(edn.kw(':assets'));\n\n const assetList: Array<{ path: string; 'content-hash': string }> = [];\n if (assets && assets.val) {\n for (const asset of assets.val) {\n assetList.push({\n path: asset.at(edn.kw(':path')),\n 'content-hash': asset.at(edn.kw(':content-hash')),\n });\n }\n }\n\n if (!version) {\n return null;\n }\n\n return { version, assets: assetList };\n } catch {\n return null;\n }\n}\n\n/**\n * Reads asset metadata from .flex-cli/asset-meta.edn\n */\nfunction readAssetMetadata(basePath: string): AssetMetadata | null {\n const metaPath = join(basePath, '.flex-cli', 'asset-meta.edn');\n if (!existsSync(metaPath)) {\n return null;\n }\n\n try {\n const content = readFileSync(metaPath, 'utf-8');\n return parseAssetMetadataEdn(content);\n } catch {\n return null;\n }\n}\n\n/**\n * Writes asset metadata to .flex-cli/asset-meta.edn\n */\nfunction writeAssetMetadata(basePath: string, metadata: AssetMetadata): void {\n const metaDir = join(basePath, '.flex-cli');\n if (!existsSync(metaDir)) {\n mkdirSync(metaDir, { recursive: true });\n }\n\n const assets = metadata.assets.map(a =>\n new edn.Map([\n edn.kw(':path'), a.path,\n edn.kw(':content-hash'), a['content-hash']\n ])\n );\n\n const ednMap = new edn.Map([\n edn.kw(':version'), metadata.version,\n edn.kw(':assets'), new edn.Vector(assets)\n ]);\n\n const metaPath = join(basePath, '.flex-cli', 'asset-meta.edn');\n writeFileSync(metaPath, edn.encode(ednMap), 'utf-8');\n}\n\n/**\n * Calculates SHA-1 hash of file content matching backend convention\n * Content is prefixed with `${byte-count}|` before hashing\n */\nfunction calculateHash(data: Buffer): string {\n const prefix = Buffer.from(`${data.length}|`, 'utf-8');\n return createHash('sha1').update(prefix).update(data).digest('hex');\n}\n\n/**\n * Reads all assets from a directory\n */\nfunction readLocalAssets(basePath: string): Array<{ path: string; data: Buffer; hash: string }> {\n const assets: Array<{ path: string; data: Buffer; hash: string }> = [];\n\n function scanDir(dir: string, relativePath: string = '') {\n const entries = readdirSync(dir);\n\n for (const entry of entries) {\n if (entry === '.flex-cli') continue; // Skip metadata directory\n if (entry === '.DS_Store') continue; // Skip .DS_Store files\n\n const fullPath = join(dir, entry);\n const relPath = relativePath ? join(relativePath, entry) : entry;\n const stat = statSync(fullPath);\n\n if (stat.isDirectory()) {\n scanDir(fullPath, relPath);\n } else if (stat.isFile()) {\n const data = readFileSync(fullPath);\n const hash = calculateHash(data);\n assets.push({ path: relPath, data, hash });\n }\n }\n }\n\n scanDir(basePath);\n return assets;\n}\n\n/**\n * Lists local asset paths without reading file data\n */\nfunction listLocalAssetPaths(basePath: string): string[] {\n const assets: string[] = [];\n\n function scanDir(dir: string, relativePath: string = '') {\n const entries = readdirSync(dir);\n\n for (const entry of entries) {\n if (entry === '.flex-cli') continue;\n if (entry === '.DS_Store') continue;\n\n const fullPath = join(dir, entry);\n const relPath = relativePath ? join(relativePath, entry) : entry;\n const stat = statSync(fullPath);\n\n if (stat.isDirectory()) {\n scanDir(fullPath, relPath);\n } else if (stat.isFile()) {\n assets.push(relPath);\n }\n }\n }\n\n scanDir(basePath);\n return assets;\n}\n\n/**\n * Validates JSON files\n */\nfunction validateJsonAssets(assets: Array<{ path: string; data: Buffer }>): void {\n for (const asset of assets) {\n if (asset.path.endsWith('.json')) {\n try {\n JSON.parse(asset.data.toString('utf-8'));\n } catch (error) {\n throw new Error(`Invalid JSON in ${asset.path}: ${error}`);\n }\n }\n }\n}\n\nfunction formatDownloadProgress(bytes: number): string {\n const mb = bytes / 1024 / 1024;\n return `${CARRIAGE_RETURN}${CLEAR_LINE}Downloaded ${mb.toFixed(2)}MB`;\n}\n\nfunction printDownloadProgress(stream: NodeJS.ReadableStream): void {\n let downloaded = 0;\n const printProgress = (): void => {\n process.stderr.write(formatDownloadProgress(downloaded));\n };\n const interval = setInterval(printProgress, 100);\n\n stream.on('data', (chunk: Buffer) => {\n downloaded += chunk.length;\n });\n\n stream.on('end', () => {\n clearInterval(interval);\n printProgress();\n process.stderr.write('\\nFinished downloading assets\\n');\n });\n}\n\nfunction getApiKeyOrThrow(): string {\n const auth = readAuth();\n if (!auth?.apiKey) {\n throw new Error('Not logged in. Please provide apiKey or run: sharetribe-cli login');\n }\n return auth.apiKey;\n}\n\nfunction getAssetsPullUrl(marketplace: string, version?: string): URL {\n const url = new URL(getApiBaseUrl() + '/assets/pull');\n url.searchParams.set('marketplace', marketplace);\n if (version) {\n url.searchParams.set('version', version);\n } else {\n url.searchParams.set('version-alias', 'latest');\n }\n return url;\n}\n\nfunction getErrorMessage(body: string, statusCode: number): string {\n try {\n const parsed = JSON.parse(body) as { errors?: Array<{ message?: string }> };\n const message = parsed.errors?.[0]?.message;\n if (message) {\n return message;\n }\n } catch {\n // Ignore JSON parse errors\n }\n return body || `HTTP ${statusCode}`;\n}\n\nasync function getAssetsZipStream(\n marketplace: string,\n version?: string\n): Promise<http.IncomingMessage> {\n const url = getAssetsPullUrl(marketplace, version);\n const apiKey = getApiKeyOrThrow();\n const isHttps = url.protocol === 'https:';\n const client = isHttps ? https : http;\n\n return new Promise((resolve, reject) => {\n const req = client.request(\n {\n method: 'GET',\n hostname: url.hostname,\n port: url.port || (isHttps ? 443 : 80),\n path: url.pathname + url.search,\n headers: {\n Authorization: `Apikey ${apiKey}`,\n Accept: 'application/zip',\n },\n },\n (res) => {\n const statusCode = res.statusCode || 0;\n if (statusCode < 200 || statusCode >= 300) {\n const chunks: Buffer[] = [];\n res.on('data', (chunk: Buffer) => chunks.push(chunk));\n res.on('end', () => {\n const body = Buffer.concat(chunks).toString('utf-8');\n reject(new Error(getErrorMessage(body, statusCode)));\n });\n return;\n }\n resolve(res);\n }\n );\n\n req.setTimeout(120000, () => {\n req.destroy(new Error('Request timeout'));\n });\n req.on('error', reject);\n req.end();\n });\n}\n\nfunction createTempZipPath(): string {\n return join(tmpdir(), `assets-${Date.now()}.zip`);\n}\n\nfunction removeAssetsDir(filename: string): string {\n if (filename.startsWith(ASSETS_DIR)) {\n return filename.slice(ASSETS_DIR.length);\n }\n return filename;\n}\n\nfunction readStreamToString(stream: NodeJS.ReadableStream): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n stream.on('data', (chunk: Buffer) => chunks.push(chunk));\n stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));\n stream.on('error', reject);\n });\n}\n\nasync function unzipAssets(zipPath: string, basePath: string): Promise<AssetMetadata> {\n return new Promise((resolve, reject) => {\n yauzl.open(zipPath, { lazyEntries: true }, (err, zipfile) => {\n if (err || !zipfile) {\n reject(err || new Error('Failed to open zip file'));\n return;\n }\n\n let assetMeta: AssetMetadata | null = null;\n\n zipfile.on('error', reject);\n zipfile.on('end', () => {\n if (!assetMeta) {\n reject(new Error('Asset metadata not found in zip'));\n return;\n }\n resolve(assetMeta);\n });\n\n zipfile.readEntry();\n zipfile.on('entry', (entry) => {\n if (entry.fileName.endsWith('/')) {\n zipfile.readEntry();\n return;\n }\n\n zipfile.openReadStream(entry, (streamErr, readStream) => {\n if (streamErr || !readStream) {\n reject(streamErr || new Error('Failed to read zip entry'));\n return;\n }\n\n if (entry.fileName === ASSET_META_FILENAME) {\n readStreamToString(readStream)\n .then((content) => {\n assetMeta = parseAssetMetadataEdn(content);\n if (!assetMeta) {\n reject(new Error('Invalid asset metadata'));\n return;\n }\n zipfile.readEntry();\n })\n .catch(reject);\n return;\n }\n\n const assetPath = join(basePath, removeAssetsDir(entry.fileName));\n const assetDir = dirname(assetPath);\n if (!existsSync(assetDir)) {\n mkdirSync(assetDir, { recursive: true });\n }\n\n pipeline(readStream, createWriteStream(assetPath))\n .then(() => zipfile.readEntry())\n .catch(reject);\n });\n });\n });\n });\n}\n\n/**\n * Pulls assets from remote\n */\nasync function pullAssets(\n marketplace: string,\n path: string,\n version?: string,\n prune?: boolean\n): Promise<void> {\n try {\n // Create directory if it doesn't exist\n if (!existsSync(path)) {\n mkdirSync(path, { recursive: true });\n }\n\n const stat = statSync(path);\n if (!stat.isDirectory()) {\n throw new Error(`${path} is not a directory`);\n }\n\n const localAssets = prune ? listLocalAssetPaths(path) : [];\n const currentMeta = readAssetMetadata(path);\n const tempZipPath = createTempZipPath();\n\n try {\n const zipStream = await getAssetsZipStream(marketplace, version);\n printDownloadProgress(zipStream);\n await pipeline(zipStream, createWriteStream(tempZipPath));\n\n const newAssetMeta = await unzipAssets(tempZipPath, path);\n const remoteVersion = newAssetMeta.version;\n\n const deletedPaths = prune\n ? new Set(localAssets.filter(p => !newAssetMeta.assets.some(a => a.path === p)))\n : new Set<string>();\n\n const updated = currentMeta?.version !== remoteVersion;\n const shouldReportUpdate = updated || deletedPaths.size > 0;\n\n if (deletedPaths.size > 0) {\n for (const assetPath of deletedPaths) {\n const fullPath = join(path, assetPath);\n if (existsSync(fullPath)) {\n unlinkSync(fullPath);\n }\n }\n }\n\n if (shouldReportUpdate) {\n writeAssetMetadata(path, {\n version: remoteVersion,\n assets: newAssetMeta.assets,\n });\n console.log(`Version ${remoteVersion} successfully pulled.`);\n } else {\n console.log('Assets are up to date.');\n }\n } finally {\n if (existsSync(tempZipPath)) {\n unlinkSync(tempZipPath);\n }\n }\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to pull assets');\n }\n process.exit(1);\n }\n}\n\n/**\n * Filters assets to only those that have changed\n */\nfunction filterChangedAssets(\n existingMeta: Array<{ path: string; 'content-hash': string }>,\n localAssets: Array<{ path: string; hash: string }>\n): Array<{ path: string; data: Buffer; hash: string }> {\n const hashByPath = new Map(existingMeta.map(a => [a.path, a['content-hash']]));\n \n return localAssets.filter(asset => {\n const storedHash = hashByPath.get(asset.path);\n // Assets without stored metadata are treated as changed\n return !storedHash || storedHash !== asset.hash;\n });\n}\n\n/**\n * Pushes assets to remote\n */\nasync function pushAssets(\n marketplace: string,\n path: string,\n prune?: boolean\n): Promise<void> {\n try {\n // Validate path\n if (!existsSync(path) || !statSync(path).isDirectory()) {\n throw new Error(`${path} is not a valid directory`);\n }\n\n // Read current metadata\n const currentMeta = readAssetMetadata(path);\n const currentVersion = currentMeta?.version || 'nil';\n\n // Read local assets\n const localAssets = readLocalAssets(path);\n\n // Validate JSON files\n validateJsonAssets(localAssets);\n\n // Filter to only changed assets\n const changedAssets = filterChangedAssets(currentMeta?.assets || [], localAssets);\n\n // Separate JSON and non-JSON assets\n const isJsonAsset = (assetPath: string): boolean => {\n return assetPath.toLowerCase().endsWith('.json');\n };\n\n const stageableAssets = changedAssets.filter(a => !isJsonAsset(a.path));\n\n // Find assets to delete (if prune enabled)\n const localAssetMap = new Map(localAssets.map(a => [a.path, a]));\n const deleteOperations: Array<{ path: string; op: 'delete' }> = [];\n if (prune && currentMeta) {\n for (const currentAsset of currentMeta.assets) {\n if (!localAssetMap.has(currentAsset.path)) {\n deleteOperations.push({\n path: currentAsset.path,\n op: 'delete',\n });\n }\n }\n }\n\n // Check if there are any changes\n const noOps = changedAssets.length === 0 && deleteOperations.length === 0;\n if (noOps) {\n console.log('Assets are up to date.');\n return;\n }\n\n // Log changed assets\n if (changedAssets.length > 0) {\n const paths = changedAssets.map(a => a.path).join(', ');\n console.log(chalk.green(`Uploading changed assets: ${paths}`));\n }\n\n // Stage non-JSON assets\n const stagedByPath = new Map<string, string>();\n if (stageableAssets.length > 0) {\n const paths = stageableAssets.map(a => a.path).join(', ');\n console.log(chalk.green(`Staging assets: ${paths}`));\n\n for (const asset of stageableAssets) {\n try {\n const stagingResult = await sdkStageAsset(\n undefined,\n marketplace,\n asset.data,\n asset.path\n );\n stagedByPath.set(asset.path, stagingResult.stagingId);\n } catch (error) {\n if (error && typeof error === 'object' && 'code' in error && error.code === 'asset-invalid-content') {\n const detail = 'message' in error ? error.message : 'The file is missing or uses an unsupported format.';\n throw new Error(`Failed to stage image ${asset.path}: ${detail}\\nFix the file and rerun assets push to retry staging.`);\n }\n throw error;\n }\n }\n }\n\n // Build upsert operations\n const upsertOperations = changedAssets.map(asset => {\n const stagingId = stagedByPath.get(asset.path);\n return {\n path: asset.path,\n op: 'upsert' as const,\n ...(stagingId\n ? { stagingId }\n : { data: asset.data, filename: asset.path }),\n };\n });\n\n // Upload to API\n const result = await sdkPushAssets(\n undefined,\n marketplace,\n currentVersion,\n [...upsertOperations, ...deleteOperations]\n );\n\n // Update local metadata\n writeAssetMetadata(path, {\n version: result.version,\n assets: result.assets.map(a => ({\n path: a.path,\n 'content-hash': a.contentHash,\n })),\n });\n\n console.log(`New version ${result.version} successfully created.`);\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to push assets');\n }\n process.exit(1);\n }\n}\n\n/**\n * Registers assets commands\n */\nexport function registerAssetsCommands(program: Command): void {\n const assetsCmd = program.command('assets').description('manage marketplace assets');\n\n // assets pull\n assetsCmd\n .command('pull')\n .description('pull assets from remote')\n .requiredOption('--path <PATH>', 'path to directory where assets will be stored')\n .option('--version <VERSION>', 'version of assets to pull')\n .option('--prune', 'delete local files no longer present as remote assets')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (opts) => {\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await pullAssets(marketplace, opts.path, opts.version, opts.prune);\n });\n\n // assets push\n assetsCmd\n .command('push')\n .description('push assets to remote')\n .requiredOption('--path <PATH>', 'path to directory with assets')\n .option('--prune', 'delete remote assets no longer present locally')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (opts) => {\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await pushAssets(marketplace, opts.path, opts.prune);\n });\n}\n\nexport const __test__ = {\n formatDownloadProgress,\n removeAssetsDir,\n parseAssetMetadataEdn,\n};\n", "/**\n * Notifications commands - manage email notifications\n */\n\nimport { Command } from 'commander';\nimport {\n sendNotification as sdkSendNotification,\n previewNotification as sdkPreviewNotification,\n} from 'sharetribe-flex-build-sdk';\nimport { printError } from '../../util/output.js';\nimport { readFileSync, existsSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { createServer, IncomingMessage, ServerResponse } from 'node:http';\n\n\n/**\n * Reads a notification template from a directory\n */\nfunction readTemplate(templatePath: string): { html: string; subject: string } {\n if (!existsSync(templatePath) || !statSync(templatePath).isDirectory()) {\n throw new Error(`Template directory not found: ${templatePath}`);\n }\n\n const htmlPath = join(templatePath, 'template.html');\n const subjectPath = join(templatePath, 'template-subject.txt');\n\n if (!existsSync(htmlPath)) {\n throw new Error(`template.html not found in ${templatePath}`);\n }\n\n if (!existsSync(subjectPath)) {\n throw new Error(`template-subject.txt not found in ${templatePath}`);\n }\n\n const html = readFileSync(htmlPath, 'utf-8');\n const subject = readFileSync(subjectPath, 'utf-8').trim();\n\n return { html, subject };\n}\n\n/**\n * Reads template context JSON file\n */\nfunction readContext(contextPath?: string): unknown {\n if (!contextPath) {\n return undefined;\n }\n\n if (!existsSync(contextPath)) {\n throw new Error(`Context file not found: ${contextPath}`);\n }\n\n const content = readFileSync(contextPath, 'utf-8');\n try {\n return JSON.parse(content);\n } catch (error) {\n throw new Error(`Invalid JSON in context file: ${error}`);\n }\n}\n\n/**\n * Sends a preview email to the marketplace admin\n */\nasync function sendNotification(\n marketplace: string,\n templatePath: string,\n contextPath?: string\n): Promise<void> {\n try {\n const template = readTemplate(templatePath);\n const context = readContext(contextPath);\n\n const result = await sdkSendNotification(undefined, marketplace, { template, context });\n\n console.log(`Preview successfully sent to ${result.adminEmail}`);\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to send notification');\n }\n process.exit(1);\n }\n}\n\n/**\n * Previews a notification in the browser\n */\nasync function previewNotification(\n marketplace: string,\n templatePath: string,\n contextPath?: string\n): Promise<void> {\n try {\n const template = readTemplate(templatePath);\n const context = readContext(contextPath);\n\n console.log(`Template: ${templatePath}`);\n console.log(`Subject: ${template.subject}`);\n console.log('');\n console.log('Starting preview server at http://localhost:3535');\n console.log('Press Ctrl+C to stop');\n console.log('');\n\n let previewHtml: string | null = null;\n\n // Fetch preview from API\n const fetchPreview = async () => {\n try {\n const result = await sdkPreviewNotification(undefined, marketplace, { template, context });\n\n // Inject title into HTML\n const html = result.html;\n const titleTag = `<title>${template.subject}</title>`;\n\n if (html.includes('<head>')) {\n previewHtml = html.replace('<head>', `<head>\\n${titleTag}`);\n } else if (html.includes('<html>')) {\n previewHtml = html.replace('<html>', `<html>\\n<head>${titleTag}</head>`);\n } else {\n previewHtml = `<html><head>${titleTag}</head><body>${html}</body></html>`;\n }\n } catch (error) {\n const errorMessage = error && typeof error === 'object' && 'message' in error\n ? (error.message as string)\n : 'Failed to preview notification';\n\n previewHtml = `\n <html>\n <head><title>Error</title></head>\n <body style=\"font-family: sans-serif; padding: 20px;\">\n <h1 style=\"color: #d32f2f;\">Error</h1>\n <pre style=\"background: #f5f5f5; padding: 15px; border-radius: 4px;\">${errorMessage}</pre>\n </body>\n </html>\n `;\n }\n };\n\n // Initial fetch\n await fetchPreview();\n\n // Create HTTP server\n const server = createServer(async (req: IncomingMessage, res: ServerResponse) => {\n if (req.url === '/' || req.url === '') {\n // Refresh preview on each request\n await fetchPreview();\n\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(previewHtml);\n } else {\n res.writeHead(404, { 'Content-Type': 'text/plain' });\n res.end('Not Found');\n }\n });\n\n server.listen(3535, () => {\n console.log('Preview server started. Open http://localhost:3535 in your browser.');\n });\n\n // Handle graceful shutdown\n const shutdown = () => {\n console.log('\\nShutting down preview server...');\n server.close(() => {\n process.exit(0);\n });\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to preview notification');\n }\n process.exit(1);\n }\n}\n\n/**\n * Registers notifications commands\n */\nexport function registerNotificationsCommands(program: Command): void {\n const notificationsCmd = program\n .command('notifications')\n .description('manage email notifications');\n\n // notifications preview\n notificationsCmd\n .command('preview')\n .description('render a preview of an email template')\n .requiredOption('--template <TEMPLATE_DIR>', 'path to template directory')\n .option('--context <CONTEXT_FILE>', 'path to email rendering context JSON file')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (opts) => {\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await previewNotification(marketplace, opts.template, opts.context);\n });\n\n // notifications send\n notificationsCmd\n .command('send')\n .description('send a preview of an email template to the logged in admin')\n .requiredOption('--template <TEMPLATE_DIR>', 'path to template directory')\n .option('--context <CONTEXT_FILE>', 'path to email rendering context JSON file')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (opts) => {\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await sendNotification(marketplace, opts.template, opts.context);\n });\n}\n", "/**\n * Listing approval command - DEPRECATED\n *\n * This command is deprecated and should not be used.\n * Use the Sharetribe Console instead.\n */\n\nimport { Command } from 'commander';\nimport {\n getListingApprovalStatus as sdkGetStatus,\n enableListingApproval as sdkEnable,\n disableListingApproval as sdkDisable,\n} from 'sharetribe-flex-build-sdk';\nimport { printError } from '../util/output.js';\n\n/**\n * Gets current listing approval status\n */\nasync function getStatus(marketplace: string): Promise<void> {\n try {\n const result = await sdkGetStatus(undefined, marketplace);\n\n if (result.enabled) {\n console.log(`Listing approvals are enabled in ${marketplace}`);\n } else {\n console.log(`Listing approvals are disabled in ${marketplace}`);\n }\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to get listing approval status');\n }\n process.exit(1);\n }\n}\n\n/**\n * Enables listing approvals\n */\nasync function enableApprovals(marketplace: string): Promise<void> {\n try {\n await sdkEnable(undefined, marketplace);\n console.log(`Successfully enabled listing approvals in ${marketplace}`);\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to enable listing approvals');\n }\n process.exit(1);\n }\n}\n\n/**\n * Disables listing approvals\n */\nasync function disableApprovals(marketplace: string): Promise<void> {\n try {\n await sdkDisable(undefined, marketplace);\n console.log(`Successfully disabled listing approvals in ${marketplace}`);\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to disable listing approvals');\n }\n process.exit(1);\n }\n}\n\n/**\n * Registers listing-approval command\n */\nexport function registerListingApprovalCommand(program: Command): void {\n const cmd = program\n .command('listing-approval')\n .description('manage listing approvals (DEPRECATED - use Console instead)')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier');\n\n // Default action - show status\n cmd.action(async (opts) => {\n console.warn('Warning: CLI command `listing-approval` is deprecated. Use Console instead.');\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await getStatus(marketplace);\n });\n\n // Enable subcommand\n cmd\n .command('enable')\n .description('enable listing approvals')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (opts) => {\n console.warn('Warning: CLI command `listing-approval` is deprecated. Use Console instead.');\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await enableApprovals(marketplace);\n });\n\n // Disable subcommand\n cmd\n .command('disable')\n .description('disable listing approvals')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (opts) => {\n console.warn('Warning: CLI command `listing-approval` is deprecated. Use Console instead.');\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await disableApprovals(marketplace);\n });\n}\n", "/**\n * Events command - query marketplace events\n */\n\nimport { Command } from 'commander';\nimport { printTable, printError } from '../../util/output.js';\nimport {\n queryEvents as sdkQueryEvents,\n pollEvents as sdkPollEvents,\n type EventData as SdkEventData\n} from 'sharetribe-flex-build-sdk';\n\ninterface EventsQueryOptions {\n resourceId?: string;\n relatedResourceId?: string;\n eventTypes?: string;\n sequenceId?: number;\n afterSeqId?: number;\n beforeSeqId?: number;\n afterTs?: string;\n beforeTs?: string;\n limit?: number;\n json?: boolean;\n jsonPretty?: boolean;\n}\n\n/**\n * Validates query parameters\n */\nfunction validateParams(opts: EventsQueryOptions): void {\n const exclusiveParams = [\n opts.sequenceId !== undefined,\n opts.afterSeqId !== undefined,\n opts.beforeSeqId !== undefined,\n opts.afterTs !== undefined,\n opts.beforeTs !== undefined,\n ];\n\n if (exclusiveParams.filter(Boolean).length > 1) {\n throw new Error(\n 'Only one of --seqid, --after-seqid, --before-seqid, --after-ts, or --before-ts can be specified'\n );\n }\n\n if (opts.resourceId && opts.relatedResourceId) {\n throw new Error('Only one of --resource or --related-resource can be specified');\n }\n}\n\n/**\n * Formats timestamp to match flex-cli format: YYYY-MM-DD H:MM:SS AM/PM\n */\nfunction formatTimestamp(timestamp: string): string {\n try {\n const date = new Date(timestamp);\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const timeString = date.toLocaleTimeString('en-US');\n\n return `${year}-${month}-${day} ${timeString}`;\n } catch {\n return timestamp;\n }\n}\n\n/**\n * Queries events from API\n */\nasync function queryEvents(\n marketplace: string,\n opts: EventsQueryOptions\n): Promise<void> {\n try {\n validateParams(opts);\n\n const events = await sdkQueryEvents(\n undefined, // Use auth from file\n marketplace,\n {\n resourceId: opts.resourceId,\n relatedResourceId: opts.relatedResourceId,\n eventTypes: opts.eventTypes,\n sequenceId: opts.sequenceId,\n afterSeqId: opts.afterSeqId,\n beforeSeqId: opts.beforeSeqId,\n afterTs: opts.afterTs,\n beforeTs: opts.beforeTs,\n limit: opts.limit,\n }\n );\n\n if (events.length === 0) {\n console.log('No events found.');\n return;\n }\n\n // Output format\n if (opts.json) {\n for (const event of events) {\n // Exclude auditEmails to match flex-cli JSON format\n const { auditEmails, ...eventWithoutEmails } = event;\n console.log(JSON.stringify(eventWithoutEmails));\n }\n } else if (opts.jsonPretty) {\n for (const event of events) {\n // Exclude auditEmails to match flex-cli JSON format\n const { auditEmails, ...eventWithoutEmails } = event;\n console.log(JSON.stringify(eventWithoutEmails, null, 2));\n }\n } else {\n printTable(\n ['Seq ID', 'Resource ID', 'Event type', 'Created at local time', 'Source', 'Actor'],\n events.map((event) => {\n const actor = event.auditEmails?.userEmail || event.auditEmails?.adminEmail || '';\n const source = event.source?.replace('source/', '') || '';\n\n return {\n 'Seq ID': event.sequenceId.toString(),\n 'Resource ID': event.resourceId,\n 'Event type': event.eventType,\n 'Created at local time': formatTimestamp(event.createdAt),\n 'Source': source,\n 'Actor': actor,\n };\n })\n );\n }\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to query events');\n }\n process.exit(1);\n }\n}\n\n/**\n * Tails events (live streaming)\n */\nasync function tailEvents(\n marketplace: string,\n opts: EventsQueryOptions\n): Promise<void> {\n try {\n validateParams(opts);\n\n console.log('Tailing events... Press Ctrl+C to stop');\n console.log('');\n\n const stopPolling = sdkPollEvents(\n undefined, // Use auth from file\n marketplace,\n {\n resourceId: opts.resourceId,\n relatedResourceId: opts.relatedResourceId,\n eventTypes: opts.eventTypes,\n limit: opts.limit || 10,\n },\n (events: SdkEventData[]) => {\n // Output events\n if (opts.json) {\n for (const event of events) {\n // Exclude auditEmails to match flex-cli JSON format\n const { auditEmails, ...eventWithoutEmails } = event;\n console.log(JSON.stringify(eventWithoutEmails));\n }\n } else if (opts.jsonPretty) {\n for (const event of events) {\n // Exclude auditEmails to match flex-cli JSON format\n const { auditEmails, ...eventWithoutEmails } = event;\n console.log(JSON.stringify(eventWithoutEmails, null, 2));\n }\n } else {\n printTable(\n ['Seq ID', 'Resource ID', 'Event type', 'Created at local time', 'Source', 'Actor'],\n events.map((event) => {\n const actor = event.auditEmails?.userEmail || event.auditEmails?.adminEmail || '';\n const source = event.source?.replace('source/', '') || '';\n\n return {\n 'Seq ID': event.sequenceId.toString(),\n 'Resource ID': event.resourceId,\n 'Event type': event.eventType,\n 'Created at local time': formatTimestamp(event.createdAt),\n 'Source': source,\n 'Actor': actor,\n };\n })\n );\n }\n },\n 5000 // 5 second poll interval\n );\n\n // Handle graceful shutdown\n const shutdown = () => {\n console.log('\\nStopping tail...');\n stopPolling();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to tail events');\n }\n process.exit(1);\n }\n}\n\n/**\n * Registers events command\n */\nexport function registerEventsCommand(program: Command): void {\n const cmd = program\n .command('events')\n .description('Get a list of events.')\n .option('--resource <RESOURCE_ID>', 'show events for specific resource ID')\n .option('--related-resource <RELATED_RESOURCE_ID>', 'show events related to specific resource ID')\n .option('--filter <EVENT_TYPES>', 'filter by event types (comma-separated)')\n .option('--seqid <SEQUENCE_ID>', 'get event with specific sequence ID', parseInt)\n .option('--after-seqid <SEQUENCE_ID>', 'show events after sequence ID (exclusive)', parseInt)\n .option('--before-seqid <SEQUENCE_ID>', 'show events before sequence ID (exclusive)', parseInt)\n .option('--after-ts <TIMESTAMP>', 'show events after timestamp')\n .option('--before-ts <TIMESTAMP>', 'show events before timestamp')\n .option('-l, --limit <NUMBER>', 'limit results (default: 100, max: 100)', parseInt)\n .option('--json', 'output as single-line JSON strings')\n .option('--json-pretty', 'output as indented multi-line JSON')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier');\n\n // Default action - query\n cmd.action(async (opts) => {\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Could not parse arguments:');\n console.error('--marketplace is required');\n process.exit(1);\n }\n\n await queryEvents(marketplace, {\n resourceId: opts.resource,\n relatedResourceId: opts.relatedResource,\n eventTypes: opts.filter,\n sequenceId: opts.seqid,\n afterSeqId: opts.afterSeqid,\n beforeSeqId: opts.beforeSeqid,\n afterTs: opts.afterTs,\n beforeTs: opts.beforeTs,\n limit: opts.limit || 100,\n json: opts.json,\n jsonPretty: opts.jsonPretty,\n });\n });\n\n // tail subcommand\n cmd\n .command('tail')\n .description('Tail events live as they happen')\n .option('--resource <RESOURCE_ID>', 'show events for specific resource ID')\n .option('--related-resource <RELATED_RESOURCE_ID>', 'show events related to specific resource ID')\n .option('--filter <EVENT_TYPES>', 'filter by event types (comma-separated)')\n .option('-l, --limit <NUMBER>', 'limit results per poll (default: 10, max: 100)', parseInt)\n .option('--json', 'output as single-line JSON strings')\n .option('--json-pretty', 'output as indented multi-line JSON')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (opts) => {\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Could not parse arguments:');\n console.error('--marketplace is required');\n process.exit(1);\n }\n\n await tailEvents(marketplace, {\n resourceId: opts.resource,\n relatedResourceId: opts.relatedResource,\n eventTypes: opts.filter,\n limit: opts.limit || 10,\n json: opts.json,\n jsonPretty: opts.jsonPretty,\n });\n });\n}\n", "/**\n * Stripe command - manage Stripe integration\n */\n\nimport { Command } from 'commander';\nimport { updateStripeVersion as sdkUpdateStripeVersion, SUPPORTED_STRIPE_VERSIONS } from 'sharetribe-flex-build-sdk';\nimport { printError } from '../../util/output.js';\nimport inquirer from 'inquirer';\n\n\n/**\n * Prompts for version selection\n */\nasync function promptForVersion(): Promise<string> {\n const answers = await inquirer.prompt([\n {\n type: 'list',\n name: 'version',\n message: 'Select Stripe API version:',\n choices: [...SUPPORTED_STRIPE_VERSIONS],\n },\n ]);\n\n return answers.version;\n}\n\n/**\n * Prompts for confirmation\n */\nasync function promptForConfirmation(): Promise<boolean> {\n console.log('');\n console.log('WARNING: Changing Stripe API version may affect your integration.');\n console.log('');\n console.log('After updating the Stripe API version, you may need to:');\n console.log('- Handle new Capabilities requirements');\n console.log('- Update identity verification settings');\n console.log('');\n console.log('See Stripe documentation for details:');\n console.log('https://stripe.com/docs/connect/capabilities-overview');\n console.log('https://stripe.com/docs/connect/identity-verification');\n console.log('');\n\n const answers = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirmed',\n message: 'Do you want to continue?',\n default: false,\n },\n ]);\n\n return answers.confirmed;\n}\n\n/**\n * Updates Stripe API version\n */\nasync function updateStripeVersion(\n marketplace: string,\n version?: string,\n force?: boolean\n): Promise<void> {\n try {\n // Get version if not provided\n let selectedVersion = version;\n if (!selectedVersion) {\n selectedVersion = await promptForVersion();\n }\n\n // Get confirmation unless --force flag is used\n if (!force) {\n const confirmed = await promptForConfirmation();\n if (!confirmed) {\n console.log('Cancelled.');\n process.exit(0);\n }\n }\n\n // Update via API (SDK validates version)\n await sdkUpdateStripeVersion(undefined, marketplace, selectedVersion);\n\n console.log(`Stripe API version successfully changed to ${selectedVersion}`);\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to update Stripe API version');\n }\n process.exit(1);\n }\n}\n\n/**\n * Registers stripe commands\n */\nexport function registerStripeCommands(program: Command): void {\n const stripeCmd = program.command('stripe').description('manage Stripe integration');\n\n // stripe update-version\n stripeCmd\n .command('update-version')\n .description('update Stripe API version in use')\n .option('--version <VERSION>', 'Stripe API version to update to')\n .option('-f, --force', 'skip confirmation prompt and force update')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (opts) => {\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await updateStripeVersion(marketplace, opts.version, opts.force);\n });\n}\n", "/**\n * Debug command - display config and auth info\n */\n\nimport { getConfigMap, readAuth } from 'sharetribe-flex-build-sdk';\n\nfunction maskLast4(value: string): string {\n if (value.length <= 4) {\n return `...${value}`;\n }\n return `...${value.slice(-4)}`;\n}\n\nexport function debug(): void {\n const auth = readAuth();\n const apiKey = auth?.apiKey ? maskLast4(auth.apiKey) : 'No API key set';\n const confMap = getConfigMap();\n\n const confMapEntries = Object.keys(confMap)\n .sort()\n .map((key) => `:${key} ${confMap[key]}`)\n .join(' ');\n const confMapFormatted = confMapEntries ? `{${confMapEntries}}` : '{}';\n\n console.log(`{:api-key ${apiKey}, :conf-map ${confMapFormatted}}`);\n}\n", "/**\n * Custom help formatter to match flex-cli output exactly\n */\n\nimport { Command, Help } from 'commander';\nimport chalk from 'chalk';\n\n/**\n * Formats help text to match flex-cli style\n *\n * flex-cli format:\n * - Description (no label)\n * - VERSION section (for main help only)\n * - USAGE section\n * - COMMANDS section (flattened list of all leaf commands)\n * - OPTIONS section (for subcommands only, not main)\n * - Subcommand help instructions\n *\n * @param cmd - Commander command instance\n * @returns Formatted help text matching flex-cli\n */\nexport function formatHelp(cmd: Command): string {\n const parts: string[] = [];\n const isRootCommand = !cmd.parent;\n\n // Description (no label, just the text)\n const description = cmd.description();\n if (description) {\n parts.push(description);\n parts.push('');\n }\n\n // VERSION section (only for root command)\n if (isRootCommand) {\n const version = cmd.version();\n if (version) {\n parts.push('VERSION');\n parts.push(` ${version}`);\n parts.push('');\n }\n }\n\n // USAGE section\n parts.push('USAGE');\n const usage = formatUsage(cmd);\n parts.push(` $ ${usage}`);\n parts.push('');\n\n // COMMANDS section\n // Note: If command has an action (options), don't show COMMANDS section (like flex-cli)\n const allCommands = collectAllLeafCommands(cmd);\n const hasAction = cmd.options.length > 0 && !isRootCommand;\n\n if (allCommands.length > 0 && !hasAction) {\n parts.push('COMMANDS');\n\n // Calculate max command name length for alignment\n const maxLength = Math.max(...allCommands.map(c => c.name.length));\n\n for (const cmdInfo of allCommands) {\n const paddedName = cmdInfo.name.padEnd(maxLength + 2);\n parts.push(` ${paddedName}${cmdInfo.description}`);\n }\n parts.push('');\n }\n\n // OPTIONS section (only for subcommands, not root)\n if (!isRootCommand) {\n const options = cmd.options;\n if (options.length > 0) {\n parts.push('OPTIONS');\n\n // Calculate max option flags length for alignment\n const maxFlagsLength = Math.max(...options.map(opt => formatOptionFlags(opt).length));\n\n for (const opt of options) {\n const flags = formatOptionFlags(opt);\n const paddedFlags = flags.padEnd(maxFlagsLength + 2);\n const desc = opt.description || '';\n parts.push(` ${paddedFlags}${desc}`);\n }\n parts.push('');\n }\n }\n\n // Subcommand help instructions (only for main and group commands without actions)\n if (allCommands.length > 0 && !hasAction) {\n parts.push('Subcommand help:');\n const cmdName = getCommandName(cmd);\n parts.push(` $ ${cmdName} help [COMMAND]`);\n }\n\n // Always add empty line at end to match flex-cli\n parts.push('');\n\n return parts.join('\\n');\n}\n\n/**\n * Recursively collects all commands (both parent and leaf commands)\n *\n * flex-cli shows ALL commands, including parent commands that have their own actions\n * Example: both \"events\" and \"events tail\" are shown\n *\n * @param cmd - Commander command instance\n * @returns Array of command info objects with name and description\n */\nfunction collectAllLeafCommands(cmd: Command): Array<{ name: string; description: string }> {\n const results: Array<{ name: string; description: string }> = [];\n const commands = cmd.commands.filter(c => !c._hidden && c.name() !== 'help');\n\n for (const subCmd of commands) {\n const fullName = getCommandFullName(subCmd);\n const subCommands = subCmd.commands.filter(c => !c._hidden);\n\n // Add this command if it has an action or description\n if (subCmd.description()) {\n results.push({\n name: fullName,\n description: subCmd.description() || ''\n });\n }\n\n // If it has subcommands, recurse and add those too\n if (subCommands.length > 0) {\n const subResults = collectAllLeafCommands(subCmd);\n for (const sub of subResults) {\n results.push(sub);\n }\n }\n }\n\n // Add \"help\" command at the beginning if this is root\n if (!cmd.parent) {\n results.unshift({\n name: 'help',\n description: 'display help for Flex CLI'\n });\n }\n\n // Sort alphabetically by command name\n results.sort((a, b) => a.name.localeCompare(b.name));\n\n return results;\n}\n\n/**\n * Gets the command name for usage (flex-cli vs sharetribe-cli)\n *\n * @param cmd - Commander command instance\n * @returns Command name (e.g., \"sharetribe-cli\" or \"sharetribe-cli process\")\n */\nfunction getCommandName(cmd: Command): string {\n const names: string[] = [];\n let current: Command | null = cmd;\n\n while (current) {\n if (current.name()) {\n names.unshift(current.name());\n }\n current = current.parent;\n }\n\n // Replace first name with \"sharetribe-cli\" (or \"flex-cli\" for reference)\n if (names.length > 0) {\n names[0] = 'sharetribe-cli';\n }\n\n return names.join(' ');\n}\n\n/**\n * Formats the USAGE line\n *\n * @param cmd - Commander command instance\n * @returns Usage string (e.g., \"sharetribe-cli [COMMAND]\" or \"sharetribe-cli process list\")\n */\nfunction formatUsage(cmd: Command): string {\n const cmdName = getCommandName(cmd);\n const commands = cmd.commands.filter(c => !c._hidden);\n const hasOptions = cmd.options.length > 0;\n const isRoot = !cmd.parent;\n\n // Root command always shows [COMMAND] if it has subcommands\n if (isRoot && commands.length > 0) {\n return `${cmdName} [COMMAND]`;\n }\n\n // If command has options (its own action), don't show [COMMAND] even if it has subcommands\n // This matches flex-cli behavior for commands like \"process\" which have both action and subcommands\n if (commands.length > 0 && !hasOptions) {\n // Has subcommands but no action\n return `${cmdName} [COMMAND]`;\n } else {\n // Leaf command or command with action - just show the command path\n return cmdName;\n }\n}\n\n/**\n * Gets the full command name including parent path\n *\n * @param cmd - Commander command instance\n * @returns Full command name (e.g., \"process list\" or \"events tail\")\n */\nfunction getCommandFullName(cmd: Command): string {\n const names: string[] = [];\n let current: Command | null = cmd;\n\n while (current && current.parent) {\n if (current.name()) {\n names.unshift(current.name());\n }\n current = current.parent;\n }\n\n return names.join(' ');\n}\n\n/**\n * Formats option flags for display\n *\n * @param opt - Commander option instance\n * @returns Formatted flags string (e.g., \"-m, --marketplace=MARKETPLACE_ID\")\n */\nfunction formatOptionFlags(opt: any): string {\n // Commander option flags are in opt.flags (e.g., \"-m, --marketplace <MARKETPLACE_ID>\")\n // We need to parse and reformat this to match flex-cli style\n const flagsStr = opt.flags || '';\n\n // Parse the flags string\n // Format: \"-m, --marketplace <VALUE>\" or \"--flag\" or \"-f\"\n const parts = flagsStr.split(/,\\s*/);\n const formatted: string[] = [];\n\n for (const part of parts) {\n const trimmed = part.trim();\n\n // Check if it has a value placeholder (angle brackets or square brackets)\n const valueMatch = trimmed.match(/^((?:-{1,2}[\\w-]+))\\s*[<\\[]([^\\]>]+)[\\]>]/);\n if (valueMatch) {\n // Has a value: \"-m <MARKETPLACE_ID>\" or \"--marketplace <MARKETPLACE_ID>\"\n const flag = valueMatch[1];\n const valueName = valueMatch[2];\n formatted.push(`${flag}=${valueName}`);\n } else {\n // No value: just the flag\n formatted.push(trimmed);\n }\n }\n\n return formatted.join(', ');\n}\n\n/**\n * Configures Commander.js to use custom help formatter\n *\n * @param program - Commander program instance\n */\nexport function configureHelp(program: Command): void {\n program.configureHelp({\n formatHelp: (cmd: Command, helper: Help) => {\n return formatHelp(cmd);\n }\n });\n}\n", "/**\n * Custom command router to handle Commander.js limitations\n *\n * Commander.js cannot handle parent and child commands with the same option names.\n * This router intercepts argv and routes to the correct command handler.\n */\n\n/**\n * Routes process subcommands to avoid Commander parent/child option conflicts\n *\n * This is necessary because Commander validates parent command options before\n * subcommand actions run, causing conflicts when both use --path.\n */\nexport function routeProcessCommand(argv: string[]): string[] {\n // Check if this is a process subcommand\n const processIndex = argv.findIndex(arg => arg === 'process');\n if (processIndex === -1) {\n return argv;\n }\n\n // Check for subcommands\n const nextArg = argv[processIndex + 1];\n const subcommands = ['list', 'create', 'push', 'pull', 'create-alias', 'update-alias', 'delete-alias', 'deploy'];\n\n if (nextArg && subcommands.includes(nextArg)) {\n // This is a subcommand - remove 'process' from argv and make the subcommand top-level\n // e.g. ['node', 'cli', 'process', 'pull', ...] => ['node', 'cli', 'process-pull', ...]\n const newArgv = [\n ...argv.slice(0, processIndex),\n `process-${nextArg}`,\n ...argv.slice(processIndex + 2)\n ];\n\n // Special handling: If this is an alias command with --version option,\n // we need to filter out the global --version flag from program\n // by ensuring the routed command is properly isolated\n return newArgv;\n }\n\n return argv;\n}\n"],
5
- "mappings": "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",
6
- "names": ["Command", "readFileSync", "fileURLToPath", "dirname", "join", "readFileSync", "fileURLToPath", "dirname", "join", "findPackageJson", "__filename", "currentDir", "pkgPath", "version", "packageJson", "inquirer", "writeAuth", "login", "answers", "input", "clearAuth", "logout", "sdkListProcesses", "sdkListProcessVersions", "chalk", "printTable", "headers", "rows", "widths", "header", "row", "value", "headerRow", "h", "width", "padded", "rowStr", "i", "printError", "message", "printSuccess", "formatProcessTimestamp", "timestamp", "date", "year", "month", "day", "timeString", "listProcesses", "marketplace", "processName", "versions", "sdkListProcessVersions", "versionRows", "v", "printTable", "processes", "sdkListProcesses", "processRows", "p", "error", "printError", "sdkCreateProcess", "readFileSync", "join", "createProcess", "marketplace", "processName", "path", "processFilePath", "processContent", "result", "sdkCreateProcess", "printSuccess", "error", "printError", "sdkPushProcess", "readFileSync", "readdirSync", "join", "readTemplates", "path", "templatesDir", "templates", "templateDirs", "templateName", "templatePath", "htmlFile", "subjectFile", "html", "subject", "pushProcess", "marketplace", "processName", "processFilePath", "processContent", "result", "sdkPushProcess", "printSuccess", "error", "printError", "getProcess", "writeFileSync", "mkdirSync", "join", "pullProcess", "marketplace", "processName", "path", "version", "alias", "process", "getProcess", "existsSync", "dirExists", "processFilePath", "templates", "templatesDir", "template", "templateName", "htmlContent", "subjectContent", "templateSubdir", "htmlPath", "subjectPath", "error", "printError", "sdkCreateAlias", "sdkUpdateAlias", "sdkDeleteAlias", "createAlias", "marketplace", "processName", "version", "alias", "result", "sdkCreateAlias", "printSuccess", "error", "printError", "updateAlias", "sdkUpdateAlias", "deleteAlias", "sdkDeleteAlias", "sdkDeployProcess", "parseProcessFile", "readFileSync", "join", "createOrPushAndCreateOrUpdateAlias", "marketplace", "processName", "path", "alias", "processFilePath", "processContent", "processDefinition", "parseProcessFile", "result", "sdkDeployProcess", "printSuccess", "error", "printError", "registerProcessCommands", "program", "processCmd", "options", "marketplace", "listProcesses", "createProcess", "pushProcess", "pullProcess", "createAlias", "updateAlias", "deleteAlias", "createOrPushAndCreateOrUpdateAlias", "sdkListSearchSchemas", "sdkSetSearchSchema", "sdkUnsetSearchSchema", "SCOPE_LABELS", "setSearchSchema", "marketplace", "opts", "sdkSetSearchSchema", "schemaFor", "scopeLabel", "error", "printError", "unsetSearchSchema", "sdkUnsetSearchSchema", "getDefaultValueLabel", "value", "listSearchSchemas", "schemas", "sdkListSearchSchemas", "rows", "s", "a", "b", "headers", "widths", "h", "row", "headerParts", "i", "width", "padded", "rowParts", "registerSearchCommands", "program", "searchCmd", "options", "sdkPushAssets", "sdkStageAsset", "getApiBaseUrl", "readAuth", "readFileSync", "writeFileSync", "existsSync", "mkdirSync", "readdirSync", "statSync", "unlinkSync", "createWriteStream", "join", "dirname", "createHash", "http", "https", "tmpdir", "pipeline", "chalk", "edn", "yauzl", "ASSET_META_FILENAME", "ASSETS_DIR", "CLEAR_LINE", "CARRIAGE_RETURN", "parseAssetMetadataEdn", "content", "parsed", "version", "assets", "assetList", "asset", "readAssetMetadata", "basePath", "metaPath", "writeAssetMetadata", "metadata", "metaDir", "a", "ednMap", "calculateHash", "data", "prefix", "readLocalAssets", "scanDir", "dir", "relativePath", "entries", "entry", "fullPath", "relPath", "stat", "hash", "listLocalAssetPaths", "validateJsonAssets", "error", "formatDownloadProgress", "bytes", "mb", "printDownloadProgress", "stream", "downloaded", "printProgress", "interval", "chunk", "getApiKeyOrThrow", "auth", "readAuth", "getAssetsPullUrl", "marketplace", "url", "getApiBaseUrl", "getErrorMessage", "body", "statusCode", "message", "getAssetsZipStream", "apiKey", "isHttps", "client", "resolve", "reject", "req", "res", "chunks", "createTempZipPath", "removeAssetsDir", "filename", "readStreamToString", "unzipAssets", "zipPath", "err", "zipfile", "assetMeta", "streamErr", "readStream", "assetPath", "assetDir", "pullAssets", "path", "prune", "localAssets", "currentMeta", "tempZipPath", "zipStream", "newAssetMeta", "remoteVersion", "deletedPaths", "p", "shouldReportUpdate", "printError", "filterChangedAssets", "existingMeta", "hashByPath", "storedHash", "pushAssets", "currentVersion", "changedAssets", "isJsonAsset", "stageableAssets", "localAssetMap", "deleteOperations", "currentAsset", "paths", "stagedByPath", "stagingResult", "sdkStageAsset", "detail", "upsertOperations", "stagingId", "result", "sdkPushAssets", "registerAssetsCommands", "program", "assetsCmd", "opts", "sdkSendNotification", "sdkPreviewNotification", "readFileSync", "existsSync", "statSync", "join", "createServer", "readTemplate", "templatePath", "htmlPath", "subjectPath", "html", "subject", "readContext", "contextPath", "content", "error", "sendNotification", "marketplace", "template", "context", "result", "sdkSendNotification", "printError", "previewNotification", "previewHtml", "fetchPreview", "sdkPreviewNotification", "titleTag", "server", "req", "res", "shutdown", "registerNotificationsCommands", "program", "notificationsCmd", "opts", "sdkGetStatus", "sdkEnable", "sdkDisable", "getStatus", "marketplace", "sdkGetStatus", "error", "printError", "enableApprovals", "sdkEnable", "disableApprovals", "sdkDisable", "registerListingApprovalCommand", "program", "cmd", "opts", "sdkQueryEvents", "sdkPollEvents", "validateParams", "opts", "formatTimestamp", "timestamp", "date", "year", "month", "day", "timeString", "queryEvents", "marketplace", "events", "event", "auditEmails", "eventWithoutEmails", "printTable", "actor", "source", "error", "printError", "tailEvents", "stopPolling", "shutdown", "registerEventsCommand", "program", "cmd", "sdkUpdateStripeVersion", "SUPPORTED_STRIPE_VERSIONS", "inquirer", "promptForVersion", "SUPPORTED_STRIPE_VERSIONS", "promptForConfirmation", "updateStripeVersion", "marketplace", "version", "force", "selectedVersion", "sdkUpdateStripeVersion", "error", "printError", "registerStripeCommands", "program", "opts", "getConfigMap", "readAuth", "maskLast4", "value", "debug", "auth", "apiKey", "confMap", "confMapEntries", "key", "confMapFormatted", "formatHelp", "cmd", "parts", "isRootCommand", "description", "version", "usage", "formatUsage", "allCommands", "collectAllLeafCommands", "hasAction", "maxLength", "c", "cmdInfo", "paddedName", "options", "maxFlagsLength", "opt", "formatOptionFlags", "paddedFlags", "desc", "cmdName", "getCommandName", "results", "commands", "subCmd", "fullName", "getCommandFullName", "subCommands", "subResults", "sub", "a", "b", "names", "current", "hasOptions", "formatted", "part", "trimmed", "valueMatch", "flag", "valueName", "configureHelp", "program", "helper", "routeProcessCommand", "argv", "processIndex", "arg", "nextArg", "__filename", "fileURLToPath", "__dirname", "dirname", "packageJson", "readFileSync", "join", "routedArgv", "routeProcessCommand", "program", "Command", "configureHelp", "str", "version", "login", "logout", "debug", "registerProcessCommands", "registerSearchCommands", "registerAssetsCommands", "registerNotificationsCommands", "registerListingApprovalCommand", "registerEventsCommand", "registerStripeCommands", "commandPath", "targetCmd", "cmdName", "subCmd", "c"]
4
+ "sourcesContent": ["/**\n * Sharetribe CLI - Unofficial 100% compatible implementation\n *\n * Main entry point for the CLI application\n */\n\nimport { Command } from 'commander';\nimport { readFileSync, existsSync, writeFileSync, mkdirSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport { homedir } from 'node:os';\nimport chalk from 'chalk';\nimport { version } from './commands/version.js';\nimport { login } from './commands/login.js';\nimport { logout } from './commands/logout.js';\nimport { registerProcessCommands } from './commands/process/index.js';\nimport { registerSearchCommands } from './commands/search/index.js';\nimport { registerAssetsCommands } from './commands/assets/index.js';\nimport { registerNotificationsCommands } from './commands/notifications/index.js';\nimport { registerListingApprovalCommand } from './commands/listing-approval.js';\nimport { registerEventsCommand } from './commands/events/index.js';\nimport { registerStripeCommands } from './commands/stripe/index.js';\nimport { debug } from './commands/debug.js';\nimport { configureHelp } from './util/help-formatter.js';\nimport { routeProcessCommand } from './util/command-router.js';\n\n// Get package.json for version info\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst packageJson = JSON.parse(\n readFileSync(join(__dirname, '../package.json'), 'utf-8')\n);\n\n// Print unofficial notice to stderr on first run only\nconst configDir = join(homedir(), '.config', 'flex-cli');\nconst noticeShownMarker = join(configDir, '.sharetribe-cli-notice-shown');\nif (!existsSync(noticeShownMarker)) {\n console.error(chalk.yellow('\u26A0\uFE0F NOTICE: This is an UNOFFICIAL Sharetribe CLI (community reimplementation).'));\n console.error(chalk.yellow(' For the official CLI, install: ') + chalk.cyan('npm install -g flex-cli') + '\\n');\n try {\n mkdirSync(configDir, { recursive: true });\n writeFileSync(noticeShownMarker, new Date().toISOString());\n } catch {\n // Ignore errors writing marker file\n }\n}\n\n// Route argv to handle process subcommands\nconst routedArgv = routeProcessCommand(process.argv);\n\nconst program = new Command();\n\n// Configure custom help formatter to match flex-cli\nconfigureHelp(program);\n\n// Configure output to add trailing newline (flex-cli behavior)\nprogram.configureOutput({\n writeOut: (str) => process.stdout.write(str + '\\n'),\n writeErr: (str) => process.stderr.write(str + '\\n'),\n});\n\n// Configure the main program\nprogram\n .name('sharetribe-cli')\n .description('CLI to interact with Sharetribe Flex')\n .version(packageJson.version, '-V', 'output the version number')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier');\n\n// Register commands\n\n// version command\nprogram\n .command('version')\n .description('show version')\n .action(() => {\n version();\n });\n\n// login command\nprogram\n .command('login')\n .description('log in with API key')\n .action(async () => {\n await login();\n });\n\n// logout command\nprogram\n .command('logout')\n .description('logout')\n .action(async () => {\n await logout();\n });\n\n// debug command\nprogram\n .command('debug')\n .description('display debug info')\n .action(() => {\n debug();\n });\n\n// Register process commands\nregisterProcessCommands(program);\n\n// Register search commands\nregisterSearchCommands(program);\n\n// Register assets commands\nregisterAssetsCommands(program);\n\n// Register notifications commands\nregisterNotificationsCommands(program);\n\n// Register listing-approval command\nregisterListingApprovalCommand(program);\n\n// Register events command\nregisterEventsCommand(program);\n\n// Register stripe commands\nregisterStripeCommands(program);\n\n// Register custom help command (to support \"help process list\" syntax)\nprogram\n .command('help [command...]')\n .description('display help for Flex CLI')\n .action((commandPath: string[]) => {\n if (!commandPath || commandPath.length === 0) {\n program.outputHelp();\n return;\n }\n\n // Navigate to the nested command\n let targetCmd: Command = program;\n for (const cmdName of commandPath) {\n const subCmd = targetCmd.commands.find(c => c.name() === cmdName);\n if (!subCmd) {\n console.error(`Unknown command: ${commandPath.join(' ')}`);\n process.exit(1);\n }\n targetCmd = subCmd;\n }\n\n // Show help for the target command\n targetCmd.outputHelp();\n });\n\n// If no command specified, show help and exit with status 0\nif (!routedArgv.slice(2).length) {\n program.outputHelp();\n // Don't call process.exit() - let Commander handle it naturally with exitOverride\n} else {\n // Parse command line arguments with routed argv\n program.parse(routedArgv);\n}\n", "/**\n * Version command - displays the CLI version\n *\n * Must match flex-cli output format exactly\n */\n\nimport { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\n\n/**\n * Finds package.json by traversing up from current file\n */\nfunction findPackageJson(): string {\n const __filename = fileURLToPath(import.meta.url);\n let currentDir = dirname(__filename);\n\n // Traverse up to find package.json\n while (currentDir !== '/') {\n try {\n const pkgPath = join(currentDir, 'package.json');\n const content = readFileSync(pkgPath, 'utf-8');\n return content;\n } catch {\n currentDir = dirname(currentDir);\n }\n }\n\n throw new Error('Could not find package.json');\n}\n\n/**\n * Displays the version of the CLI\n *\n * Output must match flex-cli exactly\n */\nexport function version(): void {\n const packageJson = JSON.parse(findPackageJson());\n console.log(packageJson.version);\n}\n", "/**\n * Login command - interactive API key authentication\n *\n * Must match flex-cli behavior exactly:\n * - Prompt for API key\n * - Store in ~/.config/flex-cli/auth.edn\n * - Display admin email on success\n */\n\nimport inquirer from 'inquirer';\nimport { writeAuth } from 'sharetribe-flex-build-sdk';\n\n/**\n * Executes the login command\n *\n * Prompts for API key and stores it in auth.edn\n */\nexport async function login(): Promise<void> {\n const answers = await inquirer.prompt([\n {\n type: 'password',\n name: 'apiKey',\n message: 'Enter API key:',\n mask: '*',\n validate: (input: string) => {\n if (!input || input.trim().length === 0) {\n return 'API key cannot be empty';\n }\n return true;\n },\n },\n ]);\n\n // Store the API key\n writeAuth({ apiKey: answers.apiKey });\n\n // TODO: Validate API key by making a test request to get admin email\n // For now, just confirm storage\n console.log('Successfully logged in.');\n\n // Note: flex-cli displays admin email after successful login\n // We'll need to implement API client to fetch this\n}\n", "/**\n * Logout command - clears authentication\n *\n * Must match flex-cli behavior exactly\n */\n\nimport { clearAuth } from 'sharetribe-flex-build-sdk';\n\n/**\n * Executes the logout command\n *\n * Clears auth.edn file\n */\nexport async function logout(): Promise<void> {\n await clearAuth();\n console.log('Successfully logged out.');\n}\n", "/**\n * Process list command - lists all transaction processes\n */\n\nimport {\n listProcesses as sdkListProcesses,\n listProcessVersions as sdkListProcessVersions,\n} from 'sharetribe-flex-build-sdk';\nimport { printTable, printError } from '../../util/output.js';\n\n\n/**\n * Formats timestamp to match flex-cli format for process list\n */\nfunction formatProcessTimestamp(timestamp: string): string {\n try {\n const date = new Date(timestamp);\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const timeString = date.toLocaleTimeString('en-US');\n\n return `${year}-${month}-${day} ${timeString}`;\n } catch {\n return timestamp;\n }\n}\n\n/**\n * Lists all processes for a marketplace\n */\nexport async function listProcesses(marketplace: string, processName?: string): Promise<void> {\n try {\n // If processName is specified, show version history for that process\n if (processName) {\n const versions = await sdkListProcessVersions(undefined, marketplace, processName);\n\n if (versions.length === 0) {\n console.log(`No versions found for process: ${processName}`);\n return;\n }\n\n const versionRows = versions.map((v) => ({\n 'Created': formatProcessTimestamp(v.createdAt),\n 'Version': v.version.toString(),\n 'Aliases': v.aliases?.join(', ') || '',\n 'Transactions': v.transactionCount?.toString() || '0',\n }));\n\n printTable(['Created', 'Version', 'Aliases', 'Transactions'], versionRows);\n } else {\n // List all processes\n const processes = await sdkListProcesses(undefined, marketplace);\n\n if (processes.length === 0) {\n console.log('No processes found.');\n return;\n }\n\n const processRows = processes.map((p) => ({\n 'Name': p.name,\n 'Latest version': p.version?.toString() || '',\n }));\n\n printTable(['Name', 'Latest version'], processRows);\n }\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to list processes');\n }\n process.exit(1);\n }\n}\n", "/**\n * Output formatting utilities\n *\n * Must match flex-cli output format exactly\n */\n\nimport chalk from 'chalk';\n\n/**\n * Prints a table with headers and rows\n *\n * Matches flex-cli table formatting exactly\n */\nexport function printTable(headers: string[], rows: Array<Record<string, string>>): void {\n if (rows.length === 0) {\n return;\n }\n\n // Calculate column widths\n // flex-cli uses keywords (e.g., :version) which when stringified include the ':' prefix\n // To match flex-cli widths, we add 1 to header length to simulate the ':' prefix\n const widths: Record<string, number> = {};\n for (const header of headers) {\n widths[header] = header.length + 1; // +1 to match flex-cli keyword string behavior\n }\n\n for (const row of rows) {\n for (const header of headers) {\n const value = row[header] || '';\n widths[header] = Math.max(widths[header] || 0, value.length);\n }\n }\n\n // Print empty line before table (like flex-cli)\n console.log('');\n\n // Print header with bold formatting\n // flex-cli format: each column padded to (max_width + 1), with single space separator between columns\n // Last column: padding but no separator (interpose doesn't add separator after last element)\n const headerParts = headers.map((h, i) => {\n const width = widths[h] || 0;\n const padded = h.padEnd(width + 1);\n return i === headers.length - 1 ? padded : padded + ' ';\n });\n const headerRow = headerParts.join('');\n console.log(chalk.bold.black(headerRow));\n\n // Print rows with same formatting\n for (const row of rows) {\n const rowParts = headers.map((h, i) => {\n const value = row[h] || '';\n const width = widths[h] || 0;\n const padded = value.padEnd(width + 1);\n return i === headers.length - 1 ? padded : padded + ' ';\n });\n const rowStr = rowParts.join('');\n console.log(rowStr);\n }\n\n // Print empty line after table (like flex-cli)\n console.log('');\n}\n\n/**\n * Prints an error message\n */\nexport function printError(message: string): void {\n console.error(chalk.red(`Error: ${message}`));\n}\n\n/**\n * Prints a success message\n */\nexport function printSuccess(message: string): void {\n console.log(chalk.green(message));\n}\n\n/**\n * Prints a warning message\n */\nexport function printWarning(message: string): void {\n console.log(chalk.yellow(`Warning: ${message}`));\n}\n", "/**\n * Process create command\n */\n\nimport { createProcess as sdkCreateProcess } from 'sharetribe-flex-build-sdk';\nimport { printError, printSuccess } from '../../util/output.js';\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/**\n * Creates a new transaction process\n */\nexport async function createProcess(\n marketplace: string,\n processName: string,\n path: string\n): Promise<void> {\n try {\n const processFilePath = join(path, 'process.edn');\n const processContent = readFileSync(processFilePath, 'utf-8');\n\n const result = await sdkCreateProcess(undefined, marketplace, processName, processContent);\n\n printSuccess(\n `Process ${result.name} successfully created with version ${result.version}.`\n );\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to create process');\n }\n process.exit(1);\n }\n}\n", "/**\n * Process push command\n */\n\nimport { pushProcess as sdkPushProcess } from 'sharetribe-flex-build-sdk';\nimport { printError, printSuccess } from '../../util/output.js';\nimport { readFileSync, readdirSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/**\n * Reads email templates from the templates directory\n */\nfunction readTemplates(path: string): Array<{ name: string; html: string; subject: string }> {\n const templatesDir = join(path, 'templates');\n const templates: Array<{ name: string; html: string; subject: string }> = [];\n\n try {\n const templateDirs = readdirSync(templatesDir);\n for (const templateName of templateDirs) {\n const templatePath = join(templatesDir, templateName);\n const htmlFile = join(templatePath, `${templateName}-html.html`);\n const subjectFile = join(templatePath, `${templateName}-subject.txt`);\n\n try {\n const html = readFileSync(htmlFile, 'utf-8');\n const subject = readFileSync(subjectFile, 'utf-8');\n templates.push({ name: templateName, html, subject });\n } catch {\n // Skip if files don't exist\n }\n }\n } catch {\n // No templates directory - return empty array\n }\n\n return templates;\n}\n\n/**\n * Pushes a new version of an existing process\n */\nexport async function pushProcess(\n marketplace: string,\n processName: string,\n path: string\n): Promise<void> {\n try {\n const processFilePath = join(path, 'process.edn');\n const processContent = readFileSync(processFilePath, 'utf-8');\n const templates = readTemplates(path);\n\n const result = await sdkPushProcess(undefined, marketplace, processName, processContent, templates);\n\n if (result.noChanges) {\n console.log('No changes');\n } else {\n printSuccess(`Version ${result.version} successfully saved for process ${processName}.`);\n }\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to push process');\n }\n process.exit(1);\n }\n}\n", "/**\n * Process pull command\n */\n\nimport { getProcess } from 'sharetribe-flex-build-sdk';\nimport { printError, printSuccess } from '../../util/output.js';\nimport { writeFileSync, mkdirSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/**\n * Pulls a process from the server\n */\nexport async function pullProcess(\n marketplace: string,\n processName: string,\n path: string,\n version?: string,\n alias?: string\n): Promise<void> {\n try {\n const process = await getProcess(undefined, marketplace, processName, { version, alias });\n\n if (!process.definition) {\n throw new Error('No process definition in response');\n }\n\n // Ensure directory exists (print message if creating new directory)\n const { existsSync } = await import('node:fs');\n const dirExists = existsSync(path);\n mkdirSync(path, { recursive: true });\n\n if (!dirExists) {\n console.error(`Creating a new directory: ${path}`);\n }\n\n // Write process.edn file\n const processFilePath = join(path, 'process.edn');\n writeFileSync(processFilePath, process.definition, 'utf-8');\n\n // Write email templates if they exist\n const templates = process.emailTemplates || [];\n\n if (templates && Array.isArray(templates) && templates.length > 0) {\n const templatesDir = join(path, 'templates');\n mkdirSync(templatesDir, { recursive: true });\n\n for (const template of templates) {\n const templateName = template.name;\n const htmlContent = template.html;\n const subjectContent = template.subject;\n\n if (templateName) {\n // Create subdirectory for this template\n const templateSubdir = join(templatesDir, templateName);\n mkdirSync(templateSubdir, { recursive: true });\n\n // Write HTML file\n if (htmlContent) {\n const htmlPath = join(templateSubdir, `${templateName}-html.html`);\n writeFileSync(htmlPath, htmlContent, 'utf-8');\n }\n\n // Write subject file\n if (subjectContent) {\n const subjectPath = join(templateSubdir, `${templateName}-subject.txt`);\n writeFileSync(subjectPath, subjectContent, 'utf-8');\n }\n }\n }\n }\n\n console.error(`Saved process to ${path}`);\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to pull process');\n }\n process.exit(1);\n }\n}\n", "/**\n * Process alias commands\n */\n\nimport {\n createAlias as sdkCreateAlias,\n updateAlias as sdkUpdateAlias,\n deleteAlias as sdkDeleteAlias\n} from 'sharetribe-flex-build-sdk';\nimport { printError, printSuccess } from '../../util/output.js';\n\n/**\n * Creates a process alias\n */\nexport async function createAlias(\n marketplace: string,\n processName: string,\n version: number,\n alias: string\n): Promise<void> {\n try {\n const result = await sdkCreateAlias(undefined, marketplace, processName, version, alias);\n\n printSuccess(\n `Alias ${result.alias} successfully created to point to version ${result.version}.`\n );\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to create alias');\n }\n process.exit(1);\n }\n}\n\n/**\n * Updates a process alias\n */\nexport async function updateAlias(\n marketplace: string,\n processName: string,\n version: number,\n alias: string\n): Promise<void> {\n try {\n const result = await sdkUpdateAlias(undefined, marketplace, processName, version, alias);\n\n printSuccess(\n `Alias ${result.alias} successfully updated to point to version ${result.version}.`\n );\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to update alias');\n }\n process.exit(1);\n }\n}\n\n/**\n * Deletes a process alias\n */\nexport async function deleteAlias(\n marketplace: string,\n processName: string,\n alias: string\n): Promise<void> {\n try {\n const result = await sdkDeleteAlias(undefined, marketplace, processName, alias);\n\n printSuccess(`Alias ${result.alias} successfully deleted.`);\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to delete alias');\n }\n process.exit(1);\n }\n}\n", "/**\n * Combined process command - create-or-push-and-create-or-update-alias\n *\n * This is the enhanced \"superset\" feature that combines multiple operations\n * into one atomic command\n */\n\nimport { deployProcess as sdkDeployProcess, parseProcessFile } from 'sharetribe-flex-build-sdk';\nimport { printError, printSuccess } from '../../util/output.js';\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/**\n * Creates or pushes a process and creates or updates an alias\n *\n * This is an atomic operation that:\n * 1. Tries to push a new version (create-version)\n * 2. If process doesn't exist, creates it\n * 3. Then creates or updates the alias\n */\nexport async function createOrPushAndCreateOrUpdateAlias(\n marketplace: string,\n processName: string,\n path: string,\n alias: string\n): Promise<void> {\n try {\n const processFilePath = join(path, 'process.edn');\n const processContent = readFileSync(processFilePath, 'utf-8');\n const processDefinition = parseProcessFile(processContent);\n\n const result = await sdkDeployProcess(\n undefined, // Use auth from file\n marketplace,\n {\n process: processName,\n alias,\n path: processFilePath,\n processDefinition,\n }\n );\n\n if (result.processCreated) {\n printSuccess(`Process ${processName} successfully created.`);\n }\n\n printSuccess(`Version ${result.version} successfully saved for process ${processName}.`);\n\n if (result.aliasCreated) {\n printSuccess(`Alias ${result.alias} successfully created to point to version ${result.version}.`);\n } else {\n printSuccess(`Alias ${result.alias} successfully updated to point to version ${result.version}.`);\n }\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to create/push process and alias');\n }\n process.exit(1);\n }\n}\n", "/**\n * Process command - main entry point for process subcommands\n */\n\nimport { Command } from 'commander';\nimport { listProcesses } from './list.js';\nimport { createProcess } from './create.js';\nimport { pushProcess } from './push.js';\nimport { pullProcess } from './pull.js';\nimport { createAlias, updateAlias, deleteAlias } from './aliases.js';\nimport { createOrPushAndCreateOrUpdateAlias } from './combined.js';\n\n/**\n * Registers all process subcommands\n */\nexport function registerProcessCommands(program: Command): void {\n // Register the parent 'process' command for help display\n const processCmd = program\n .command('process')\n .description('describe a process file')\n .option('--path <PROCESS_DIR>', 'path to the directory where the process.edn file is')\n .option('--transition <TRANSITION_NAME>', 'transition name, e.g. transition/request to get more details of it')\n .action(async (options) => {\n // Process describe functionality\n if (options.path) {\n console.log(`Describing process at: ${options.path}`);\n if (options.transition) {\n console.log(`Transition: ${options.transition}`);\n }\n // TODO: Implement actual process file parsing and description\n console.log('Process description not yet implemented');\n } else {\n // If no options, show help\n processCmd.outputHelp();\n }\n });\n\n // Register subcommands - these are registered as BOTH subcommands (for help) and top-level (for routing)\n\n // process list (as subcommand)\n processCmd\n .command('list')\n .description('list all transaction processes')\n .option('--process <PROCESS_NAME>', 'print version and alias info of a specific process')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await listProcesses(marketplace, options.process);\n });\n\n // process create\n processCmd\n .command('create')\n .description('create a new transaction process')\n .requiredOption('--process <PROCESS_NAME>', 'name for the new process')\n .requiredOption('--path <LOCAL_PROCESS_DIR>', 'path to the directory where the process.edn file is')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await createProcess(marketplace, options.process, options.path);\n });\n\n // process push\n processCmd\n .command('push')\n .description('push a process file to the remote')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--path <LOCAL_PROCESS_DIR>', 'path to the directory where the process.edn file is')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await pushProcess(marketplace, options.process, options.path);\n });\n\n // process pull\n processCmd\n .command('pull')\n .description('fetch a process file')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--path <LOCAL_PROCESS_DIR>', 'path where to save the process')\n .option('--version <VERSION_NUM>', 'version number')\n .option('--alias <PROCESS_ALIAS>', 'alias name')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await pullProcess(marketplace, options.process, options.path, options.version, options.alias);\n });\n\n // process create-alias\n processCmd\n .command('create-alias')\n .description('create a new alias')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--version <VERSION_NUM>', 'version number')\n .requiredOption('--alias <ALIAS>', 'alias name')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .allowUnknownOption(false)\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await createAlias(marketplace, options.process, parseInt(options.version), options.alias);\n });\n\n // process update-alias\n processCmd\n .command('update-alias')\n .description('update an existing alias')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--version <VERSION_NUM>', 'version number')\n .requiredOption('--alias <ALIAS>', 'alias name')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await updateAlias(marketplace, options.process, parseInt(options.version), options.alias);\n });\n\n // process delete-alias\n processCmd\n .command('delete-alias')\n .description('delete an existing alias')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--alias <ALIAS>', 'alias name')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await deleteAlias(marketplace, options.process, options.alias);\n });\n\n // process deploy (combined command: create-or-push-and-create-or-update-alias)\n processCmd\n .command('deploy')\n .description('deploy a process file with alias (create/push + alias create/update)')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--path <LOCAL_PROCESS_DIR>', 'path to the directory with the process files')\n .requiredOption('--alias <ALIAS>', 'alias name')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await createOrPushAndCreateOrUpdateAlias(\n marketplace,\n options.process,\n options.path,\n options.alias\n );\n });\n\n // Register top-level command aliases for routing (hidden from help)\n // These handle the routed commands like 'process-pull' that avoid Commander's parent/child option conflicts\n\n program\n .command('process-list', { hidden: true })\n .description('list all transaction processes')\n .option('--process <PROCESS_NAME>', 'print version and alias info of a specific process')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await listProcesses(marketplace, options.process);\n });\n\n program\n .command('process-create', { hidden: true })\n .description('create a new transaction process')\n .requiredOption('--process <PROCESS_NAME>', 'name for the new process')\n .requiredOption('--path <LOCAL_PROCESS_DIR>', 'path to the directory where the process.edn file is')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await createProcess(marketplace, options.process, options.path);\n });\n\n program\n .command('process-push', { hidden: true })\n .description('push a process file to the remote')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--path <LOCAL_PROCESS_DIR>', 'path to the directory where the process.edn file is')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await pushProcess(marketplace, options.process, options.path);\n });\n\n program\n .command('process-pull', { hidden: true })\n .description('fetch a process file')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--path <LOCAL_PROCESS_DIR>', 'path where to save the process')\n .option('--version <VERSION_NUM>', 'version number')\n .option('--alias <PROCESS_ALIAS>', 'alias name')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await pullProcess(marketplace, options.process, options.path, options.version, options.alias);\n });\n\n program\n .command('process-create-alias', { hidden: true })\n .description('create a new alias')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--version <VERSION_NUM>', 'version number')\n .requiredOption('--alias <ALIAS>', 'alias name')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await createAlias(marketplace, options.process, parseInt(options.version), options.alias);\n });\n\n program\n .command('process-update-alias', { hidden: true })\n .description('update an existing alias')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--version <VERSION_NUM>', 'version number')\n .requiredOption('--alias <ALIAS>', 'alias name')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await updateAlias(marketplace, options.process, parseInt(options.version), options.alias);\n });\n\n program\n .command('process-delete-alias', { hidden: true })\n .description('delete an existing alias')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--alias <ALIAS>', 'alias name')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await deleteAlias(marketplace, options.process, options.alias);\n });\n\n program\n .command('process-deploy', { hidden: true })\n .description('deploy a process file with alias (create/push + alias create/update)')\n .requiredOption('--process <PROCESS_NAME>', 'name of the process')\n .requiredOption('--path <LOCAL_PROCESS_DIR>', 'path to the directory with the process files')\n .requiredOption('--alias <ALIAS>', 'alias name')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await createOrPushAndCreateOrUpdateAlias(\n marketplace,\n options.process,\n options.path,\n options.alias\n );\n });\n}\n", "/**\n * Search command - manage search schemas\n */\n\nimport { Command } from 'commander';\nimport {\n listSearchSchemas as sdkListSearchSchemas,\n setSearchSchema as sdkSetSearchSchema,\n unsetSearchSchema as sdkUnsetSearchSchema,\n} from 'sharetribe-flex-build-sdk';\nimport { printTable, printError } from '../../util/output.js';\n\ninterface SetSchemaOptions {\n key: string;\n scope: string;\n type: string;\n doc?: string;\n default?: string;\n schemaFor?: string;\n}\n\ninterface UnsetSchemaOptions {\n key: string;\n scope: string;\n schemaFor?: string;\n}\n\n/**\n * Scope label mapping\n */\nconst SCOPE_LABELS: Record<string, string> = {\n metadata: 'Metadata',\n private: 'Private data',\n protected: 'Protected data',\n public: 'Public data',\n};\n\n/**\n * Sets a search schema field\n */\nasync function setSearchSchema(marketplace: string, opts: SetSchemaOptions): Promise<void> {\n try {\n await sdkSetSearchSchema(undefined, marketplace, {\n key: opts.key,\n scope: opts.scope,\n type: opts.type,\n doc: opts.doc,\n defaultValue: opts.default,\n schemaFor: opts.schemaFor,\n });\n\n const schemaFor = opts.schemaFor || 'listing';\n const scopeLabel = SCOPE_LABELS[opts.scope] || opts.scope;\n console.log(`${scopeLabel} schema, ${opts.key} is successfully set for ${schemaFor}.`);\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to set search schema');\n }\n process.exit(1);\n }\n}\n\n/**\n * Unsets a search schema field\n */\nasync function unsetSearchSchema(marketplace: string, opts: UnsetSchemaOptions): Promise<void> {\n try {\n await sdkUnsetSearchSchema(undefined, marketplace, {\n key: opts.key,\n scope: opts.scope,\n schemaFor: opts.schemaFor,\n });\n\n const schemaFor = opts.schemaFor || 'listing';\n const scopeLabel = SCOPE_LABELS[opts.scope] || opts.scope;\n console.log(`${scopeLabel} schema, ${opts.key} is successfully unset for ${schemaFor}.`);\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to unset search schema');\n }\n process.exit(1);\n }\n}\n\n/**\n * Converts default value to display string\n */\nfunction getDefaultValueLabel(value: unknown): string {\n if (value === undefined || value === null) {\n return '';\n }\n\n if (Array.isArray(value)) {\n return value.join(', ');\n }\n\n return String(value);\n}\n\n/**\n * Lists all search schemas\n */\nasync function listSearchSchemas(marketplace: string): Promise<void> {\n try {\n const schemas = await sdkListSearchSchemas(undefined, marketplace);\n\n if (schemas.length === 0) {\n console.log('No search schemas found.');\n return;\n }\n\n // Map and sort the data (by schema-for, scope, key)\n const rows = schemas\n .map((s) => ({\n 'Schema for': s.schemaFor,\n 'Scope': s.scope,\n 'Key': s.key,\n 'Type': s.type,\n 'Default value': getDefaultValueLabel(s.defaultValue),\n 'Doc': s.doc || '',\n }))\n .sort((a, b) => {\n // Sort by schema-for, then scope, then key\n if (a['Schema for'] !== b['Schema for']) {\n return a['Schema for'].localeCompare(b['Schema for']);\n }\n if (a['Scope'] !== b['Scope']) {\n return a['Scope'].localeCompare(b['Scope']);\n }\n return a['Key'].localeCompare(b['Key']);\n });\n\n // Print table using flex-cli compatible formatting\n const headers = ['Schema for', 'Scope', 'Key', 'Type', 'Default value', 'Doc'];\n\n // Calculate column widths\n // flex-cli uses keywords (e.g., :version) which when stringified include the ':' prefix\n // To match flex-cli widths, we add 1 to header length to simulate the ':' prefix\n const widths: Record<string, number> = {};\n for (const h of headers) {\n widths[h] = h.length + 1;\n }\n for (const row of rows) {\n for (const h of headers) {\n const value = row[h] || '';\n widths[h] = Math.max(widths[h], value.length);\n }\n }\n\n // Print empty line before table\n console.log('');\n\n // Print header\n // flex-cli search format: each column padded to max_width, with 2 space separator between columns\n // Last column: padding with trailing space\n const headerParts = headers.map((h, i) => {\n const width = widths[h] || 0;\n const padded = h.padEnd(width);\n return i === headers.length - 1 ? padded + ' ' : padded + ' ';\n });\n console.log(headerParts.join(''));\n\n // Print rows\n for (const row of rows) {\n const rowParts = headers.map((h, i) => {\n const value = row[h] || '';\n const width = widths[h] || 0;\n const padded = value.padEnd(width);\n return i === headers.length - 1 ? padded + ' ' : padded + ' ';\n });\n console.log(rowParts.join(''));\n }\n\n // Print empty line after table\n console.log('');\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to list search schemas');\n }\n process.exit(1);\n }\n}\n\n/**\n * Registers search commands\n */\nexport function registerSearchCommands(program: Command): void {\n const searchCmd = program\n .command('search')\n .description('list all search schemas')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (options) => {\n const marketplace = options.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await listSearchSchemas(marketplace);\n });\n\n // search set\n searchCmd\n .command('set')\n .description('set search schema')\n .requiredOption('--key <KEY>', 'key name')\n .requiredOption(\n '--scope <SCOPE>',\n 'extended data scope (either metadata or public for listing schema, metadata, private, protected or public for userProfile schema, metadata or protected for transaction schema)'\n )\n .requiredOption('--type <TYPE>', 'value type (either enum, multi-enum, boolean, long or text)')\n .option('--doc <DOC>', 'description of the schema')\n .option('--default <DEFAULT>', 'default value for search if value is not set')\n .option(\n '--schema-for <SCHEMA_FOR>',\n 'Subject of the schema (either listing, userProfile or transaction, defaults to listing)'\n )\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (opts) => {\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await setSearchSchema(marketplace, {\n key: opts.key,\n scope: opts.scope,\n type: opts.type,\n doc: opts.doc,\n default: opts.default,\n schemaFor: opts.schemaFor,\n });\n });\n\n // search unset\n searchCmd\n .command('unset')\n .description('unset search schema')\n .requiredOption('--key <KEY>', 'key name')\n .requiredOption(\n '--scope <SCOPE>',\n 'extended data scope (either metadata or public for listing schema, metadata, private, protected or public for userProfile schema, metadata or protected for transaction schema)'\n )\n .option(\n '--schema-for <SCHEMA_FOR>',\n 'Subject of the schema (either listing, userProfile or transaction, defaults to listing)'\n )\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (opts) => {\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await unsetSearchSchema(marketplace, {\n key: opts.key,\n scope: opts.scope,\n schemaFor: opts.schemaFor,\n });\n });\n}\n", "/**\n * Assets commands - manage marketplace assets\n */\n\nimport { Command } from 'commander';\nimport {\n pushAssets as sdkPushAssets,\n stageAsset as sdkStageAsset,\n getApiBaseUrl,\n readAuth,\n} from 'sharetribe-flex-build-sdk';\nimport { printError } from '../../util/output.js';\nimport {\n readFileSync,\n writeFileSync,\n existsSync,\n mkdirSync,\n readdirSync,\n statSync,\n unlinkSync,\n createWriteStream,\n} from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { createHash } from 'node:crypto';\nimport * as http from 'node:http';\nimport * as https from 'node:https';\nimport { tmpdir } from 'node:os';\nimport { pipeline } from 'node:stream/promises';\nimport chalk from 'chalk';\nimport edn from 'jsedn';\nimport yauzl from 'yauzl';\n\n\ninterface AssetMetadata {\n version: string;\n assets: Array<{ path: string; 'content-hash': string }>;\n}\n\nconst ASSET_META_FILENAME = 'meta/asset-meta.edn';\nconst ASSETS_DIR = 'assets/';\nconst CLEAR_LINE = '\\x1b[K';\nconst CARRIAGE_RETURN = '\\r';\n\nfunction parseAssetMetadataEdn(content: string): AssetMetadata | null {\n try {\n const parsed = edn.parse(content);\n const version = parsed.at(edn.kw(':version')) || parsed.at(edn.kw(':aliased-version'));\n const assets = parsed.at(edn.kw(':assets'));\n\n const assetList: Array<{ path: string; 'content-hash': string }> = [];\n if (assets && assets.val) {\n for (const asset of assets.val) {\n assetList.push({\n path: asset.at(edn.kw(':path')),\n 'content-hash': asset.at(edn.kw(':content-hash')),\n });\n }\n }\n\n if (!version) {\n return null;\n }\n\n return { version, assets: assetList };\n } catch {\n return null;\n }\n}\n\n/**\n * Reads asset metadata from .flex-cli/asset-meta.edn\n */\nfunction readAssetMetadata(basePath: string): AssetMetadata | null {\n const metaPath = join(basePath, '.flex-cli', 'asset-meta.edn');\n if (!existsSync(metaPath)) {\n return null;\n }\n\n try {\n const content = readFileSync(metaPath, 'utf-8');\n return parseAssetMetadataEdn(content);\n } catch {\n return null;\n }\n}\n\n/**\n * Writes asset metadata to .flex-cli/asset-meta.edn\n */\nfunction writeAssetMetadata(basePath: string, metadata: AssetMetadata): void {\n const metaDir = join(basePath, '.flex-cli');\n if (!existsSync(metaDir)) {\n mkdirSync(metaDir, { recursive: true });\n }\n\n const assets = metadata.assets.map(a =>\n new edn.Map([\n edn.kw(':path'), a.path,\n edn.kw(':content-hash'), a['content-hash']\n ])\n );\n\n const ednMap = new edn.Map([\n edn.kw(':version'), metadata.version,\n edn.kw(':assets'), new edn.Vector(assets)\n ]);\n\n const metaPath = join(basePath, '.flex-cli', 'asset-meta.edn');\n writeFileSync(metaPath, edn.encode(ednMap), 'utf-8');\n}\n\n/**\n * Calculates SHA-1 hash of file content matching backend convention\n * Content is prefixed with `${byte-count}|` before hashing\n */\nfunction calculateHash(data: Buffer): string {\n const prefix = Buffer.from(`${data.length}|`, 'utf-8');\n return createHash('sha1').update(prefix).update(data).digest('hex');\n}\n\n/**\n * Reads all assets from a directory\n */\nfunction readLocalAssets(basePath: string): Array<{ path: string; data: Buffer; hash: string }> {\n const assets: Array<{ path: string; data: Buffer; hash: string }> = [];\n\n function scanDir(dir: string, relativePath: string = '') {\n const entries = readdirSync(dir);\n\n for (const entry of entries) {\n if (entry === '.flex-cli') continue; // Skip metadata directory\n if (entry === '.DS_Store') continue; // Skip .DS_Store files\n\n const fullPath = join(dir, entry);\n const relPath = relativePath ? join(relativePath, entry) : entry;\n const stat = statSync(fullPath);\n\n if (stat.isDirectory()) {\n scanDir(fullPath, relPath);\n } else if (stat.isFile()) {\n const data = readFileSync(fullPath);\n const hash = calculateHash(data);\n assets.push({ path: relPath, data, hash });\n }\n }\n }\n\n scanDir(basePath);\n return assets;\n}\n\n/**\n * Lists local asset paths without reading file data\n */\nfunction listLocalAssetPaths(basePath: string): string[] {\n const assets: string[] = [];\n\n function scanDir(dir: string, relativePath: string = '') {\n const entries = readdirSync(dir);\n\n for (const entry of entries) {\n if (entry === '.flex-cli') continue;\n if (entry === '.DS_Store') continue;\n\n const fullPath = join(dir, entry);\n const relPath = relativePath ? join(relativePath, entry) : entry;\n const stat = statSync(fullPath);\n\n if (stat.isDirectory()) {\n scanDir(fullPath, relPath);\n } else if (stat.isFile()) {\n assets.push(relPath);\n }\n }\n }\n\n scanDir(basePath);\n return assets;\n}\n\n/**\n * Validates JSON files\n */\nfunction validateJsonAssets(assets: Array<{ path: string; data: Buffer }>): void {\n for (const asset of assets) {\n if (asset.path.endsWith('.json')) {\n try {\n JSON.parse(asset.data.toString('utf-8'));\n } catch (error) {\n throw new Error(`Invalid JSON in ${asset.path}: ${error}`);\n }\n }\n }\n}\n\nfunction formatDownloadProgress(bytes: number): string {\n const mb = bytes / 1024 / 1024;\n return `${CARRIAGE_RETURN}${CLEAR_LINE}Downloaded ${mb.toFixed(2)}MB`;\n}\n\nfunction printDownloadProgress(stream: NodeJS.ReadableStream): void {\n let downloaded = 0;\n const printProgress = (): void => {\n process.stderr.write(formatDownloadProgress(downloaded));\n };\n const interval = setInterval(printProgress, 100);\n\n stream.on('data', (chunk: Buffer) => {\n downloaded += chunk.length;\n });\n\n stream.on('end', () => {\n clearInterval(interval);\n printProgress();\n process.stderr.write('\\nFinished downloading assets\\n');\n });\n}\n\nfunction getApiKeyOrThrow(): string {\n const auth = readAuth();\n if (!auth?.apiKey) {\n throw new Error('Not logged in. Please provide apiKey or run: sharetribe-cli login');\n }\n return auth.apiKey;\n}\n\nfunction getAssetsPullUrl(marketplace: string, version?: string): URL {\n const url = new URL(getApiBaseUrl() + '/assets/pull');\n url.searchParams.set('marketplace', marketplace);\n if (version) {\n url.searchParams.set('version', version);\n } else {\n url.searchParams.set('version-alias', 'latest');\n }\n return url;\n}\n\nfunction getErrorMessage(body: string, statusCode: number): string {\n try {\n const parsed = JSON.parse(body) as { errors?: Array<{ message?: string }> };\n const message = parsed.errors?.[0]?.message;\n if (message) {\n return message;\n }\n } catch {\n // Ignore JSON parse errors\n }\n return body || `HTTP ${statusCode}`;\n}\n\nasync function getAssetsZipStream(\n marketplace: string,\n version?: string\n): Promise<http.IncomingMessage> {\n const url = getAssetsPullUrl(marketplace, version);\n const apiKey = getApiKeyOrThrow();\n const isHttps = url.protocol === 'https:';\n const client = isHttps ? https : http;\n\n return new Promise((resolve, reject) => {\n const req = client.request(\n {\n method: 'GET',\n hostname: url.hostname,\n port: url.port || (isHttps ? 443 : 80),\n path: url.pathname + url.search,\n headers: {\n Authorization: `Apikey ${apiKey}`,\n Accept: 'application/zip',\n },\n },\n (res) => {\n const statusCode = res.statusCode || 0;\n if (statusCode < 200 || statusCode >= 300) {\n const chunks: Buffer[] = [];\n res.on('data', (chunk: Buffer) => chunks.push(chunk));\n res.on('end', () => {\n const body = Buffer.concat(chunks).toString('utf-8');\n reject(new Error(getErrorMessage(body, statusCode)));\n });\n return;\n }\n resolve(res);\n }\n );\n\n req.setTimeout(120000, () => {\n req.destroy(new Error('Request timeout'));\n });\n req.on('error', reject);\n req.end();\n });\n}\n\nfunction createTempZipPath(): string {\n return join(tmpdir(), `assets-${Date.now()}.zip`);\n}\n\nfunction removeAssetsDir(filename: string): string {\n if (filename.startsWith(ASSETS_DIR)) {\n return filename.slice(ASSETS_DIR.length);\n }\n return filename;\n}\n\nfunction readStreamToString(stream: NodeJS.ReadableStream): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n stream.on('data', (chunk: Buffer) => chunks.push(chunk));\n stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));\n stream.on('error', reject);\n });\n}\n\nasync function unzipAssets(zipPath: string, basePath: string): Promise<AssetMetadata> {\n return new Promise((resolve, reject) => {\n yauzl.open(zipPath, { lazyEntries: true }, (err, zipfile) => {\n if (err || !zipfile) {\n reject(err || new Error('Failed to open zip file'));\n return;\n }\n\n let assetMeta: AssetMetadata | null = null;\n\n zipfile.on('error', reject);\n zipfile.on('end', () => {\n if (!assetMeta) {\n reject(new Error('Asset metadata not found in zip'));\n return;\n }\n resolve(assetMeta);\n });\n\n zipfile.readEntry();\n zipfile.on('entry', (entry) => {\n if (entry.fileName.endsWith('/')) {\n zipfile.readEntry();\n return;\n }\n\n zipfile.openReadStream(entry, (streamErr, readStream) => {\n if (streamErr || !readStream) {\n reject(streamErr || new Error('Failed to read zip entry'));\n return;\n }\n\n if (entry.fileName === ASSET_META_FILENAME) {\n readStreamToString(readStream)\n .then((content) => {\n assetMeta = parseAssetMetadataEdn(content);\n if (!assetMeta) {\n reject(new Error('Invalid asset metadata'));\n return;\n }\n zipfile.readEntry();\n })\n .catch(reject);\n return;\n }\n\n const assetPath = join(basePath, removeAssetsDir(entry.fileName));\n const assetDir = dirname(assetPath);\n if (!existsSync(assetDir)) {\n mkdirSync(assetDir, { recursive: true });\n }\n\n pipeline(readStream, createWriteStream(assetPath))\n .then(() => zipfile.readEntry())\n .catch(reject);\n });\n });\n });\n });\n}\n\n/**\n * Pulls assets from remote\n */\nasync function pullAssets(\n marketplace: string,\n path: string,\n version?: string,\n prune?: boolean\n): Promise<void> {\n try {\n // Create directory if it doesn't exist\n if (!existsSync(path)) {\n mkdirSync(path, { recursive: true });\n }\n\n const stat = statSync(path);\n if (!stat.isDirectory()) {\n throw new Error(`${path} is not a directory`);\n }\n\n const localAssets = prune ? listLocalAssetPaths(path) : [];\n const currentMeta = readAssetMetadata(path);\n const tempZipPath = createTempZipPath();\n\n try {\n const zipStream = await getAssetsZipStream(marketplace, version);\n printDownloadProgress(zipStream);\n await pipeline(zipStream, createWriteStream(tempZipPath));\n\n const newAssetMeta = await unzipAssets(tempZipPath, path);\n const remoteVersion = newAssetMeta.version;\n\n const deletedPaths = prune\n ? new Set(localAssets.filter(p => !newAssetMeta.assets.some(a => a.path === p)))\n : new Set<string>();\n\n const updated = currentMeta?.version !== remoteVersion;\n const shouldReportUpdate = updated || deletedPaths.size > 0;\n\n if (deletedPaths.size > 0) {\n for (const assetPath of deletedPaths) {\n const fullPath = join(path, assetPath);\n if (existsSync(fullPath)) {\n unlinkSync(fullPath);\n }\n }\n }\n\n if (shouldReportUpdate) {\n writeAssetMetadata(path, {\n version: remoteVersion,\n assets: newAssetMeta.assets,\n });\n console.log(`Version ${remoteVersion} successfully pulled.`);\n } else {\n console.log('Assets are up to date.');\n }\n } finally {\n if (existsSync(tempZipPath)) {\n unlinkSync(tempZipPath);\n }\n }\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to pull assets');\n }\n process.exit(1);\n }\n}\n\n/**\n * Filters assets to only those that have changed\n */\nfunction filterChangedAssets(\n existingMeta: Array<{ path: string; 'content-hash': string }>,\n localAssets: Array<{ path: string; hash: string }>\n): Array<{ path: string; data: Buffer; hash: string }> {\n const hashByPath = new Map(existingMeta.map(a => [a.path, a['content-hash']]));\n \n return localAssets.filter(asset => {\n const storedHash = hashByPath.get(asset.path);\n // Assets without stored metadata are treated as changed\n return !storedHash || storedHash !== asset.hash;\n });\n}\n\n/**\n * Pushes assets to remote\n */\nasync function pushAssets(\n marketplace: string,\n path: string,\n prune?: boolean\n): Promise<void> {\n try {\n // Validate path\n if (!existsSync(path) || !statSync(path).isDirectory()) {\n throw new Error(`${path} is not a valid directory`);\n }\n\n // Read current metadata\n const currentMeta = readAssetMetadata(path);\n const currentVersion = currentMeta?.version || 'nil';\n\n // Read local assets\n const localAssets = readLocalAssets(path);\n\n // Validate JSON files\n validateJsonAssets(localAssets);\n\n // Filter to only changed assets\n const changedAssets = filterChangedAssets(currentMeta?.assets || [], localAssets);\n\n // Separate JSON and non-JSON assets\n const isJsonAsset = (assetPath: string): boolean => {\n return assetPath.toLowerCase().endsWith('.json');\n };\n\n const stageableAssets = changedAssets.filter(a => !isJsonAsset(a.path));\n\n // Find assets to delete (if prune enabled)\n const localAssetMap = new Map(localAssets.map(a => [a.path, a]));\n const deleteOperations: Array<{ path: string; op: 'delete' }> = [];\n if (prune && currentMeta) {\n for (const currentAsset of currentMeta.assets) {\n if (!localAssetMap.has(currentAsset.path)) {\n deleteOperations.push({\n path: currentAsset.path,\n op: 'delete',\n });\n }\n }\n }\n\n // Check if there are any changes\n const noOps = changedAssets.length === 0 && deleteOperations.length === 0;\n if (noOps) {\n console.log('Assets are up to date.');\n return;\n }\n\n // Log changed assets\n if (changedAssets.length > 0) {\n const paths = changedAssets.map(a => a.path).join(', ');\n console.log(chalk.green(`Uploading changed assets: ${paths}`));\n }\n\n // Stage non-JSON assets\n const stagedByPath = new Map<string, string>();\n if (stageableAssets.length > 0) {\n const paths = stageableAssets.map(a => a.path).join(', ');\n console.log(chalk.green(`Staging assets: ${paths}`));\n\n for (const asset of stageableAssets) {\n try {\n const stagingResult = await sdkStageAsset(\n undefined,\n marketplace,\n asset.data,\n asset.path\n );\n stagedByPath.set(asset.path, stagingResult.stagingId);\n } catch (error) {\n if (error && typeof error === 'object' && 'code' in error && error.code === 'asset-invalid-content') {\n const detail = 'message' in error ? error.message : 'The file is missing or uses an unsupported format.';\n throw new Error(`Failed to stage image ${asset.path}: ${detail}\\nFix the file and rerun assets push to retry staging.`);\n }\n throw error;\n }\n }\n }\n\n // Build upsert operations\n const upsertOperations = changedAssets.map(asset => {\n const stagingId = stagedByPath.get(asset.path);\n return {\n path: asset.path,\n op: 'upsert' as const,\n ...(stagingId\n ? { stagingId }\n : { data: asset.data, filename: asset.path }),\n };\n });\n\n // Upload to API\n const result = await sdkPushAssets(\n undefined,\n marketplace,\n currentVersion,\n [...upsertOperations, ...deleteOperations]\n );\n\n // Update local metadata\n writeAssetMetadata(path, {\n version: result.version,\n assets: result.assets.map(a => ({\n path: a.path,\n 'content-hash': a.contentHash,\n })),\n });\n\n console.log(`New version ${result.version} successfully created.`);\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to push assets');\n }\n process.exit(1);\n }\n}\n\n/**\n * Registers assets commands\n */\nexport function registerAssetsCommands(program: Command): void {\n const assetsCmd = program.command('assets').description('manage marketplace assets');\n\n // assets pull\n assetsCmd\n .command('pull')\n .description('pull assets from remote')\n .requiredOption('--path <PATH>', 'path to directory where assets will be stored')\n .option('--version <VERSION>', 'version of assets to pull')\n .option('--prune', 'delete local files no longer present as remote assets')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (opts) => {\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await pullAssets(marketplace, opts.path, opts.version, opts.prune);\n });\n\n // assets push\n assetsCmd\n .command('push')\n .description('push assets to remote')\n .requiredOption('--path <PATH>', 'path to directory with assets')\n .option('--prune', 'delete remote assets no longer present locally')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (opts) => {\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await pushAssets(marketplace, opts.path, opts.prune);\n });\n}\n\nexport const __test__ = {\n formatDownloadProgress,\n removeAssetsDir,\n parseAssetMetadataEdn,\n};\n", "/**\n * Notifications commands - manage email notifications\n */\n\nimport { Command } from 'commander';\nimport {\n sendNotification as sdkSendNotification,\n previewNotification as sdkPreviewNotification,\n} from 'sharetribe-flex-build-sdk';\nimport { printError } from '../../util/output.js';\nimport { readFileSync, existsSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { createServer, IncomingMessage, ServerResponse } from 'node:http';\n\n\n/**\n * Reads a notification template from a directory\n */\nfunction readTemplate(templatePath: string): { html: string; subject: string } {\n if (!existsSync(templatePath) || !statSync(templatePath).isDirectory()) {\n throw new Error(`Template directory not found: ${templatePath}`);\n }\n\n const htmlPath = join(templatePath, 'template.html');\n const subjectPath = join(templatePath, 'template-subject.txt');\n\n if (!existsSync(htmlPath)) {\n throw new Error(`template.html not found in ${templatePath}`);\n }\n\n if (!existsSync(subjectPath)) {\n throw new Error(`template-subject.txt not found in ${templatePath}`);\n }\n\n const html = readFileSync(htmlPath, 'utf-8');\n const subject = readFileSync(subjectPath, 'utf-8').trim();\n\n return { html, subject };\n}\n\n/**\n * Reads template context JSON file\n */\nfunction readContext(contextPath?: string): unknown {\n if (!contextPath) {\n return undefined;\n }\n\n if (!existsSync(contextPath)) {\n throw new Error(`Context file not found: ${contextPath}`);\n }\n\n const content = readFileSync(contextPath, 'utf-8');\n try {\n return JSON.parse(content);\n } catch (error) {\n throw new Error(`Invalid JSON in context file: ${error}`);\n }\n}\n\n/**\n * Sends a preview email to the marketplace admin\n */\nasync function sendNotification(\n marketplace: string,\n templatePath: string,\n contextPath?: string\n): Promise<void> {\n try {\n const template = readTemplate(templatePath);\n const context = readContext(contextPath);\n\n const result = await sdkSendNotification(undefined, marketplace, { template, context });\n\n console.log(`Preview successfully sent to ${result.adminEmail}`);\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to send notification');\n }\n process.exit(1);\n }\n}\n\n/**\n * Previews a notification in the browser\n */\nasync function previewNotification(\n marketplace: string,\n templatePath: string,\n contextPath?: string\n): Promise<void> {\n try {\n const template = readTemplate(templatePath);\n const context = readContext(contextPath);\n\n console.log(`Template: ${templatePath}`);\n console.log(`Subject: ${template.subject}`);\n console.log('');\n console.log('Starting preview server at http://localhost:3535');\n console.log('Press Ctrl+C to stop');\n console.log('');\n\n let previewHtml: string | null = null;\n\n // Fetch preview from API\n const fetchPreview = async () => {\n try {\n const result = await sdkPreviewNotification(undefined, marketplace, { template, context });\n\n // Inject title into HTML\n const html = result.html;\n const titleTag = `<title>${template.subject}</title>`;\n\n if (html.includes('<head>')) {\n previewHtml = html.replace('<head>', `<head>\\n${titleTag}`);\n } else if (html.includes('<html>')) {\n previewHtml = html.replace('<html>', `<html>\\n<head>${titleTag}</head>`);\n } else {\n previewHtml = `<html><head>${titleTag}</head><body>${html}</body></html>`;\n }\n } catch (error) {\n const errorMessage = error && typeof error === 'object' && 'message' in error\n ? (error.message as string)\n : 'Failed to preview notification';\n\n previewHtml = `\n <html>\n <head><title>Error</title></head>\n <body style=\"font-family: sans-serif; padding: 20px;\">\n <h1 style=\"color: #d32f2f;\">Error</h1>\n <pre style=\"background: #f5f5f5; padding: 15px; border-radius: 4px;\">${errorMessage}</pre>\n </body>\n </html>\n `;\n }\n };\n\n // Initial fetch\n await fetchPreview();\n\n // Create HTTP server\n const server = createServer(async (req: IncomingMessage, res: ServerResponse) => {\n if (req.url === '/' || req.url === '') {\n // Refresh preview on each request\n await fetchPreview();\n\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(previewHtml);\n } else {\n res.writeHead(404, { 'Content-Type': 'text/plain' });\n res.end('Not Found');\n }\n });\n\n server.listen(3535, () => {\n console.log('Preview server started. Open http://localhost:3535 in your browser.');\n });\n\n // Handle graceful shutdown\n const shutdown = () => {\n console.log('\\nShutting down preview server...');\n server.close(() => {\n process.exit(0);\n });\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to preview notification');\n }\n process.exit(1);\n }\n}\n\n/**\n * Registers notifications commands\n */\nexport function registerNotificationsCommands(program: Command): void {\n const notificationsCmd = program\n .command('notifications')\n .description('manage email notifications');\n\n // notifications preview\n notificationsCmd\n .command('preview')\n .description('render a preview of an email template')\n .requiredOption('--template <TEMPLATE_DIR>', 'path to template directory')\n .option('--context <CONTEXT_FILE>', 'path to email rendering context JSON file')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (opts) => {\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await previewNotification(marketplace, opts.template, opts.context);\n });\n\n // notifications send\n notificationsCmd\n .command('send')\n .description('send a preview of an email template to the logged in admin')\n .requiredOption('--template <TEMPLATE_DIR>', 'path to template directory')\n .option('--context <CONTEXT_FILE>', 'path to email rendering context JSON file')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (opts) => {\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await sendNotification(marketplace, opts.template, opts.context);\n });\n}\n", "/**\n * Listing approval command - DEPRECATED\n *\n * This command is deprecated and should not be used.\n * Use the Sharetribe Console instead.\n */\n\nimport { Command } from 'commander';\nimport {\n getListingApprovalStatus as sdkGetStatus,\n enableListingApproval as sdkEnable,\n disableListingApproval as sdkDisable,\n} from 'sharetribe-flex-build-sdk';\nimport { printError } from '../util/output.js';\n\n/**\n * Gets current listing approval status\n */\nasync function getStatus(marketplace: string): Promise<void> {\n try {\n const result = await sdkGetStatus(undefined, marketplace);\n\n if (result.enabled) {\n console.log(`Listing approvals are enabled in ${marketplace}`);\n } else {\n console.log(`Listing approvals are disabled in ${marketplace}`);\n }\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to get listing approval status');\n }\n process.exit(1);\n }\n}\n\n/**\n * Enables listing approvals\n */\nasync function enableApprovals(marketplace: string): Promise<void> {\n try {\n await sdkEnable(undefined, marketplace);\n console.log(`Successfully enabled listing approvals in ${marketplace}`);\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to enable listing approvals');\n }\n process.exit(1);\n }\n}\n\n/**\n * Disables listing approvals\n */\nasync function disableApprovals(marketplace: string): Promise<void> {\n try {\n await sdkDisable(undefined, marketplace);\n console.log(`Successfully disabled listing approvals in ${marketplace}`);\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to disable listing approvals');\n }\n process.exit(1);\n }\n}\n\n/**\n * Registers listing-approval command\n */\nexport function registerListingApprovalCommand(program: Command): void {\n const cmd = program\n .command('listing-approval')\n .description('manage listing approvals (DEPRECATED - use Console instead)')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier');\n\n // Default action - show status\n cmd.action(async (opts) => {\n console.warn('Warning: CLI command `listing-approval` is deprecated. Use Console instead.');\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await getStatus(marketplace);\n });\n\n // Enable subcommand\n cmd\n .command('enable')\n .description('enable listing approvals')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (opts) => {\n console.warn('Warning: CLI command `listing-approval` is deprecated. Use Console instead.');\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await enableApprovals(marketplace);\n });\n\n // Disable subcommand\n cmd\n .command('disable')\n .description('disable listing approvals')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (opts) => {\n console.warn('Warning: CLI command `listing-approval` is deprecated. Use Console instead.');\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await disableApprovals(marketplace);\n });\n}\n", "/**\n * Events command - query marketplace events\n */\n\nimport { Command } from 'commander';\nimport { printTable, printError } from '../../util/output.js';\nimport {\n queryEvents as sdkQueryEvents,\n pollEvents as sdkPollEvents,\n type EventData as SdkEventData\n} from 'sharetribe-flex-build-sdk';\n\ninterface EventsQueryOptions {\n resourceId?: string;\n relatedResourceId?: string;\n eventTypes?: string;\n sequenceId?: number;\n afterSeqId?: number;\n beforeSeqId?: number;\n afterTs?: string;\n beforeTs?: string;\n limit?: number;\n json?: boolean;\n jsonPretty?: boolean;\n}\n\n/**\n * Validates query parameters\n */\nfunction validateParams(opts: EventsQueryOptions): void {\n const exclusiveParams = [\n opts.sequenceId !== undefined,\n opts.afterSeqId !== undefined,\n opts.beforeSeqId !== undefined,\n opts.afterTs !== undefined,\n opts.beforeTs !== undefined,\n ];\n\n if (exclusiveParams.filter(Boolean).length > 1) {\n throw new Error(\n 'Only one of --seqid, --after-seqid, --before-seqid, --after-ts, or --before-ts can be specified'\n );\n }\n\n if (opts.resourceId && opts.relatedResourceId) {\n throw new Error('Only one of --resource or --related-resource can be specified');\n }\n}\n\n/**\n * Formats timestamp to match flex-cli format: YYYY-MM-DD H:MM:SS AM/PM\n */\nfunction formatTimestamp(timestamp: string): string {\n try {\n const date = new Date(timestamp);\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const timeString = date.toLocaleTimeString('en-US');\n\n return `${year}-${month}-${day} ${timeString}`;\n } catch {\n return timestamp;\n }\n}\n\n/**\n * Queries events from API\n */\nasync function queryEvents(\n marketplace: string,\n opts: EventsQueryOptions\n): Promise<void> {\n try {\n validateParams(opts);\n\n const events = await sdkQueryEvents(\n undefined, // Use auth from file\n marketplace,\n {\n resourceId: opts.resourceId,\n relatedResourceId: opts.relatedResourceId,\n eventTypes: opts.eventTypes,\n sequenceId: opts.sequenceId,\n afterSeqId: opts.afterSeqId,\n beforeSeqId: opts.beforeSeqId,\n afterTs: opts.afterTs,\n beforeTs: opts.beforeTs,\n limit: opts.limit,\n }\n );\n\n if (events.length === 0) {\n console.log('No events found.');\n return;\n }\n\n // Output format\n if (opts.json) {\n for (const event of events) {\n // Exclude auditEmails to match flex-cli JSON format\n const { auditEmails, ...eventWithoutEmails } = event;\n console.log(JSON.stringify(eventWithoutEmails));\n }\n } else if (opts.jsonPretty) {\n for (const event of events) {\n // Exclude auditEmails to match flex-cli JSON format\n const { auditEmails, ...eventWithoutEmails } = event;\n console.log(JSON.stringify(eventWithoutEmails, null, 2));\n }\n } else {\n printTable(\n ['Seq ID', 'Resource ID', 'Event type', 'Created at local time', 'Source', 'Actor'],\n events.map((event) => {\n const actor = event.auditEmails?.userEmail || event.auditEmails?.adminEmail || '';\n const source = event.source?.replace('source/', '') || '';\n\n return {\n 'Seq ID': event.sequenceId.toString(),\n 'Resource ID': event.resourceId,\n 'Event type': event.eventType,\n 'Created at local time': formatTimestamp(event.createdAt),\n 'Source': source,\n 'Actor': actor,\n };\n })\n );\n }\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to query events');\n }\n process.exit(1);\n }\n}\n\n/**\n * Tails events (live streaming)\n */\nasync function tailEvents(\n marketplace: string,\n opts: EventsQueryOptions\n): Promise<void> {\n try {\n validateParams(opts);\n\n console.log('Tailing events... Press Ctrl+C to stop');\n console.log('');\n\n const stopPolling = sdkPollEvents(\n undefined, // Use auth from file\n marketplace,\n {\n resourceId: opts.resourceId,\n relatedResourceId: opts.relatedResourceId,\n eventTypes: opts.eventTypes,\n limit: opts.limit || 10,\n },\n (events: SdkEventData[]) => {\n // Output events\n if (opts.json) {\n for (const event of events) {\n // Exclude auditEmails to match flex-cli JSON format\n const { auditEmails, ...eventWithoutEmails } = event;\n console.log(JSON.stringify(eventWithoutEmails));\n }\n } else if (opts.jsonPretty) {\n for (const event of events) {\n // Exclude auditEmails to match flex-cli JSON format\n const { auditEmails, ...eventWithoutEmails } = event;\n console.log(JSON.stringify(eventWithoutEmails, null, 2));\n }\n } else {\n printTable(\n ['Seq ID', 'Resource ID', 'Event type', 'Created at local time', 'Source', 'Actor'],\n events.map((event) => {\n const actor = event.auditEmails?.userEmail || event.auditEmails?.adminEmail || '';\n const source = event.source?.replace('source/', '') || '';\n\n return {\n 'Seq ID': event.sequenceId.toString(),\n 'Resource ID': event.resourceId,\n 'Event type': event.eventType,\n 'Created at local time': formatTimestamp(event.createdAt),\n 'Source': source,\n 'Actor': actor,\n };\n })\n );\n }\n },\n 5000 // 5 second poll interval\n );\n\n // Handle graceful shutdown\n const shutdown = () => {\n console.log('\\nStopping tail...');\n stopPolling();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to tail events');\n }\n process.exit(1);\n }\n}\n\n/**\n * Registers events command\n */\nexport function registerEventsCommand(program: Command): void {\n const cmd = program\n .command('events')\n .description('Get a list of events.')\n .option('--resource <RESOURCE_ID>', 'show events for specific resource ID')\n .option('--related-resource <RELATED_RESOURCE_ID>', 'show events related to specific resource ID')\n .option('--filter <EVENT_TYPES>', 'filter by event types (comma-separated)')\n .option('--seqid <SEQUENCE_ID>', 'get event with specific sequence ID', parseInt)\n .option('--after-seqid <SEQUENCE_ID>', 'show events after sequence ID (exclusive)', parseInt)\n .option('--before-seqid <SEQUENCE_ID>', 'show events before sequence ID (exclusive)', parseInt)\n .option('--after-ts <TIMESTAMP>', 'show events after timestamp')\n .option('--before-ts <TIMESTAMP>', 'show events before timestamp')\n .option('-l, --limit <NUMBER>', 'limit results (default: 100, max: 100)', parseInt)\n .option('--json', 'output as single-line JSON strings')\n .option('--json-pretty', 'output as indented multi-line JSON')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier');\n\n // Default action - query\n cmd.action(async (opts) => {\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Could not parse arguments:');\n console.error('--marketplace is required');\n process.exit(1);\n }\n\n await queryEvents(marketplace, {\n resourceId: opts.resource,\n relatedResourceId: opts.relatedResource,\n eventTypes: opts.filter,\n sequenceId: opts.seqid,\n afterSeqId: opts.afterSeqid,\n beforeSeqId: opts.beforeSeqid,\n afterTs: opts.afterTs,\n beforeTs: opts.beforeTs,\n limit: opts.limit || 100,\n json: opts.json,\n jsonPretty: opts.jsonPretty,\n });\n });\n\n // tail subcommand\n cmd\n .command('tail')\n .description('Tail events live as they happen')\n .option('--resource <RESOURCE_ID>', 'show events for specific resource ID')\n .option('--related-resource <RELATED_RESOURCE_ID>', 'show events related to specific resource ID')\n .option('--filter <EVENT_TYPES>', 'filter by event types (comma-separated)')\n .option('-l, --limit <NUMBER>', 'limit results per poll (default: 10, max: 100)', parseInt)\n .option('--json', 'output as single-line JSON strings')\n .option('--json-pretty', 'output as indented multi-line JSON')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (opts) => {\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Could not parse arguments:');\n console.error('--marketplace is required');\n process.exit(1);\n }\n\n await tailEvents(marketplace, {\n resourceId: opts.resource,\n relatedResourceId: opts.relatedResource,\n eventTypes: opts.filter,\n limit: opts.limit || 10,\n json: opts.json,\n jsonPretty: opts.jsonPretty,\n });\n });\n}\n", "/**\n * Stripe command - manage Stripe integration\n */\n\nimport { Command } from 'commander';\nimport { updateStripeVersion as sdkUpdateStripeVersion, SUPPORTED_STRIPE_VERSIONS } from 'sharetribe-flex-build-sdk';\nimport { printError } from '../../util/output.js';\nimport inquirer from 'inquirer';\n\n\n/**\n * Prompts for version selection\n */\nasync function promptForVersion(): Promise<string> {\n const answers = await inquirer.prompt([\n {\n type: 'list',\n name: 'version',\n message: 'Select Stripe API version:',\n choices: [...SUPPORTED_STRIPE_VERSIONS],\n },\n ]);\n\n return answers.version;\n}\n\n/**\n * Prompts for confirmation\n */\nasync function promptForConfirmation(): Promise<boolean> {\n console.log('');\n console.log('WARNING: Changing Stripe API version may affect your integration.');\n console.log('');\n console.log('After updating the Stripe API version, you may need to:');\n console.log('- Handle new Capabilities requirements');\n console.log('- Update identity verification settings');\n console.log('');\n console.log('See Stripe documentation for details:');\n console.log('https://stripe.com/docs/connect/capabilities-overview');\n console.log('https://stripe.com/docs/connect/identity-verification');\n console.log('');\n\n const answers = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirmed',\n message: 'Do you want to continue?',\n default: false,\n },\n ]);\n\n return answers.confirmed;\n}\n\n/**\n * Updates Stripe API version\n */\nasync function updateStripeVersion(\n marketplace: string,\n version?: string,\n force?: boolean\n): Promise<void> {\n try {\n // Get version if not provided\n let selectedVersion = version;\n if (!selectedVersion) {\n selectedVersion = await promptForVersion();\n }\n\n // Get confirmation unless --force flag is used\n if (!force) {\n const confirmed = await promptForConfirmation();\n if (!confirmed) {\n console.log('Cancelled.');\n process.exit(0);\n }\n }\n\n // Update via API (SDK validates version)\n await sdkUpdateStripeVersion(undefined, marketplace, selectedVersion);\n\n console.log(`Stripe API version successfully changed to ${selectedVersion}`);\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error) {\n printError(error.message as string);\n } else {\n printError('Failed to update Stripe API version');\n }\n process.exit(1);\n }\n}\n\n/**\n * Registers stripe commands\n */\nexport function registerStripeCommands(program: Command): void {\n const stripeCmd = program.command('stripe').description('manage Stripe integration');\n\n // stripe update-version\n stripeCmd\n .command('update-version')\n .description('update Stripe API version in use')\n .option('--version <VERSION>', 'Stripe API version to update to')\n .option('-f, --force', 'skip confirmation prompt and force update')\n .option('-m, --marketplace <MARKETPLACE_ID>', 'marketplace identifier')\n .action(async (opts) => {\n const marketplace = opts.marketplace || program.opts().marketplace;\n if (!marketplace) {\n console.error('Error: --marketplace is required');\n process.exit(1);\n }\n await updateStripeVersion(marketplace, opts.version, opts.force);\n });\n}\n", "/**\n * Debug command - display config and auth info\n */\n\nimport { getConfigMap, readAuth } from 'sharetribe-flex-build-sdk';\n\nfunction maskLast4(value: string): string {\n if (value.length <= 4) {\n return `...${value}`;\n }\n return `...${value.slice(-4)}`;\n}\n\nexport function debug(): void {\n const auth = readAuth();\n const apiKey = auth?.apiKey ? maskLast4(auth.apiKey) : 'No API key set';\n const confMap = getConfigMap();\n\n const confMapEntries = Object.keys(confMap)\n .sort()\n .map((key) => `:${key} ${confMap[key]}`)\n .join(' ');\n const confMapFormatted = confMapEntries ? `{${confMapEntries}}` : '{}';\n\n console.log(`{:api-key ${apiKey}, :conf-map ${confMapFormatted}}`);\n}\n", "/**\n * Custom help formatter to match flex-cli output exactly\n */\n\nimport { Command, Help } from 'commander';\nimport chalk from 'chalk';\n\n/**\n * Formats help text to match flex-cli style\n *\n * flex-cli format:\n * - Description (no label)\n * - VERSION section (for main help only)\n * - USAGE section\n * - COMMANDS section (flattened list of all leaf commands)\n * - OPTIONS section (for subcommands only, not main)\n * - Subcommand help instructions\n *\n * @param cmd - Commander command instance\n * @returns Formatted help text matching flex-cli\n */\nexport function formatHelp(cmd: Command): string {\n const parts: string[] = [];\n const isRootCommand = !cmd.parent;\n\n // Description (no label, just the text)\n const description = cmd.description();\n if (description) {\n parts.push(description);\n parts.push('');\n }\n\n // VERSION section (only for root command)\n if (isRootCommand) {\n const version = cmd.version();\n if (version) {\n parts.push('VERSION');\n parts.push(` ${version}`);\n parts.push('');\n }\n }\n\n // USAGE section\n parts.push('USAGE');\n const usage = formatUsage(cmd);\n parts.push(` $ ${usage}`);\n parts.push('');\n\n // COMMANDS section\n // Note: If command has an action (options), don't show COMMANDS section (like flex-cli)\n const allCommands = collectAllLeafCommands(cmd);\n const hasAction = cmd.options.length > 0 && !isRootCommand;\n\n if (allCommands.length > 0 && !hasAction) {\n parts.push('COMMANDS');\n\n // Calculate max command name length for alignment\n const maxLength = Math.max(...allCommands.map(c => c.name.length));\n\n for (const cmdInfo of allCommands) {\n const paddedName = cmdInfo.name.padEnd(maxLength + 2);\n parts.push(` ${paddedName}${cmdInfo.description}`);\n }\n parts.push('');\n }\n\n // OPTIONS section (only for subcommands, not root)\n if (!isRootCommand) {\n const options = cmd.options;\n if (options.length > 0) {\n parts.push('OPTIONS');\n\n // Calculate max option flags length for alignment\n const maxFlagsLength = Math.max(...options.map(opt => formatOptionFlags(opt).length));\n\n for (const opt of options) {\n const flags = formatOptionFlags(opt);\n const paddedFlags = flags.padEnd(maxFlagsLength + 2);\n const desc = opt.description || '';\n parts.push(` ${paddedFlags}${desc}`);\n }\n parts.push('');\n }\n }\n\n // Subcommand help instructions (only for main and group commands without actions)\n if (allCommands.length > 0 && !hasAction) {\n parts.push('Subcommand help:');\n const cmdName = getCommandName(cmd);\n parts.push(` $ ${cmdName} help [COMMAND]`);\n }\n\n // Always add empty line at end to match flex-cli\n parts.push('');\n\n return parts.join('\\n');\n}\n\n/**\n * Recursively collects all commands (both parent and leaf commands)\n *\n * flex-cli shows ALL commands, including parent commands that have their own actions\n * Example: both \"events\" and \"events tail\" are shown\n *\n * @param cmd - Commander command instance\n * @returns Array of command info objects with name and description\n */\nfunction collectAllLeafCommands(cmd: Command): Array<{ name: string; description: string }> {\n const results: Array<{ name: string; description: string }> = [];\n const commands = cmd.commands.filter(c => !c._hidden && c.name() !== 'help');\n\n for (const subCmd of commands) {\n const fullName = getCommandFullName(subCmd);\n const subCommands = subCmd.commands.filter(c => !c._hidden);\n\n // Add this command if it has an action or description\n if (subCmd.description()) {\n results.push({\n name: fullName,\n description: subCmd.description() || ''\n });\n }\n\n // If it has subcommands, recurse and add those too\n if (subCommands.length > 0) {\n const subResults = collectAllLeafCommands(subCmd);\n for (const sub of subResults) {\n results.push(sub);\n }\n }\n }\n\n // Add \"help\" command at the beginning if this is root\n if (!cmd.parent) {\n results.unshift({\n name: 'help',\n description: 'display help for Flex CLI'\n });\n }\n\n // Sort alphabetically by command name\n results.sort((a, b) => a.name.localeCompare(b.name));\n\n return results;\n}\n\n/**\n * Gets the command name for usage (flex-cli vs sharetribe-cli)\n *\n * @param cmd - Commander command instance\n * @returns Command name (e.g., \"sharetribe-cli\" or \"sharetribe-cli process\")\n */\nfunction getCommandName(cmd: Command): string {\n const names: string[] = [];\n let current: Command | null = cmd;\n\n while (current) {\n if (current.name()) {\n names.unshift(current.name());\n }\n current = current.parent;\n }\n\n // Replace first name with \"sharetribe-cli\" (or \"flex-cli\" for reference)\n if (names.length > 0) {\n names[0] = 'sharetribe-cli';\n }\n\n return names.join(' ');\n}\n\n/**\n * Formats the USAGE line\n *\n * @param cmd - Commander command instance\n * @returns Usage string (e.g., \"sharetribe-cli [COMMAND]\" or \"sharetribe-cli process list\")\n */\nfunction formatUsage(cmd: Command): string {\n const cmdName = getCommandName(cmd);\n const commands = cmd.commands.filter(c => !c._hidden);\n const hasOptions = cmd.options.length > 0;\n const isRoot = !cmd.parent;\n\n // Root command always shows [COMMAND] if it has subcommands\n if (isRoot && commands.length > 0) {\n return `${cmdName} [COMMAND]`;\n }\n\n // If command has options (its own action), don't show [COMMAND] even if it has subcommands\n // This matches flex-cli behavior for commands like \"process\" which have both action and subcommands\n if (commands.length > 0 && !hasOptions) {\n // Has subcommands but no action\n return `${cmdName} [COMMAND]`;\n } else {\n // Leaf command or command with action - just show the command path\n return cmdName;\n }\n}\n\n/**\n * Gets the full command name including parent path\n *\n * @param cmd - Commander command instance\n * @returns Full command name (e.g., \"process list\" or \"events tail\")\n */\nfunction getCommandFullName(cmd: Command): string {\n const names: string[] = [];\n let current: Command | null = cmd;\n\n while (current && current.parent) {\n if (current.name()) {\n names.unshift(current.name());\n }\n current = current.parent;\n }\n\n return names.join(' ');\n}\n\n/**\n * Formats option flags for display\n *\n * @param opt - Commander option instance\n * @returns Formatted flags string (e.g., \"-m, --marketplace=MARKETPLACE_ID\")\n */\nfunction formatOptionFlags(opt: any): string {\n // Commander option flags are in opt.flags (e.g., \"-m, --marketplace <MARKETPLACE_ID>\")\n // We need to parse and reformat this to match flex-cli style\n const flagsStr = opt.flags || '';\n\n // Parse the flags string\n // Format: \"-m, --marketplace <VALUE>\" or \"--flag\" or \"-f\"\n const parts = flagsStr.split(/,\\s*/);\n const formatted: string[] = [];\n\n for (const part of parts) {\n const trimmed = part.trim();\n\n // Check if it has a value placeholder (angle brackets or square brackets)\n const valueMatch = trimmed.match(/^((?:-{1,2}[\\w-]+))\\s*[<\\[]([^\\]>]+)[\\]>]/);\n if (valueMatch) {\n // Has a value: \"-m <MARKETPLACE_ID>\" or \"--marketplace <MARKETPLACE_ID>\"\n const flag = valueMatch[1];\n const valueName = valueMatch[2];\n formatted.push(`${flag}=${valueName}`);\n } else {\n // No value: just the flag\n formatted.push(trimmed);\n }\n }\n\n return formatted.join(', ');\n}\n\n/**\n * Configures Commander.js to use custom help formatter\n *\n * @param program - Commander program instance\n */\nexport function configureHelp(program: Command): void {\n program.configureHelp({\n formatHelp: (cmd: Command, helper: Help) => {\n return formatHelp(cmd);\n }\n });\n}\n", "/**\n * Custom command router to handle Commander.js limitations\n *\n * Commander.js cannot handle parent and child commands with the same option names.\n * This router intercepts argv and routes to the correct command handler.\n */\n\n/**\n * Routes process subcommands to avoid Commander parent/child option conflicts\n *\n * This is necessary because Commander validates parent command options before\n * subcommand actions run, causing conflicts when both use --path.\n */\nexport function routeProcessCommand(argv: string[]): string[] {\n // Check if this is a process subcommand\n const processIndex = argv.findIndex(arg => arg === 'process');\n if (processIndex === -1) {\n return argv;\n }\n\n // Check for subcommands\n const nextArg = argv[processIndex + 1];\n const subcommands = ['list', 'create', 'push', 'pull', 'create-alias', 'update-alias', 'delete-alias', 'deploy'];\n\n if (nextArg && subcommands.includes(nextArg)) {\n // This is a subcommand - remove 'process' from argv and make the subcommand top-level\n // e.g. ['node', 'cli', 'process', 'pull', ...] => ['node', 'cli', 'process-pull', ...]\n const newArgv = [\n ...argv.slice(0, processIndex),\n `process-${nextArg}`,\n ...argv.slice(processIndex + 2)\n ];\n\n // Special handling: If this is an alias command with --version option,\n // we need to filter out the global --version flag from program\n // by ensuring the routed command is properly isolated\n return newArgv;\n }\n\n return argv;\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["Command", "readFileSync", "existsSync", "writeFileSync", "mkdirSync", "fileURLToPath", "dirname", "join", "homedir", "chalk", "readFileSync", "fileURLToPath", "dirname", "join", "findPackageJson", "__filename", "currentDir", "pkgPath", "version", "packageJson", "inquirer", "writeAuth", "login", "answers", "input", "clearAuth", "logout", "sdkListProcesses", "sdkListProcessVersions", "chalk", "printTable", "headers", "rows", "widths", "header", "row", "value", "headerRow", "h", "width", "padded", "rowStr", "i", "printError", "message", "printSuccess", "formatProcessTimestamp", "timestamp", "date", "year", "month", "day", "timeString", "listProcesses", "marketplace", "processName", "versions", "sdkListProcessVersions", "versionRows", "v", "printTable", "processes", "sdkListProcesses", "processRows", "p", "error", "printError", "sdkCreateProcess", "readFileSync", "join", "createProcess", "marketplace", "processName", "path", "processFilePath", "processContent", "result", "sdkCreateProcess", "printSuccess", "error", "printError", "sdkPushProcess", "readFileSync", "readdirSync", "join", "readTemplates", "path", "templatesDir", "templates", "templateDirs", "templateName", "templatePath", "htmlFile", "subjectFile", "html", "subject", "pushProcess", "marketplace", "processName", "processFilePath", "processContent", "result", "sdkPushProcess", "printSuccess", "error", "printError", "getProcess", "writeFileSync", "mkdirSync", "join", "pullProcess", "marketplace", "processName", "path", "version", "alias", "process", "getProcess", "existsSync", "dirExists", "processFilePath", "templates", "templatesDir", "template", "templateName", "htmlContent", "subjectContent", "templateSubdir", "htmlPath", "subjectPath", "error", "printError", "sdkCreateAlias", "sdkUpdateAlias", "sdkDeleteAlias", "createAlias", "marketplace", "processName", "version", "alias", "result", "sdkCreateAlias", "printSuccess", "error", "printError", "updateAlias", "sdkUpdateAlias", "deleteAlias", "sdkDeleteAlias", "sdkDeployProcess", "parseProcessFile", "readFileSync", "join", "createOrPushAndCreateOrUpdateAlias", "marketplace", "processName", "path", "alias", "processFilePath", "processContent", "processDefinition", "parseProcessFile", "result", "sdkDeployProcess", "printSuccess", "error", "printError", "registerProcessCommands", "program", "processCmd", "options", "marketplace", "listProcesses", "createProcess", "pushProcess", "pullProcess", "createAlias", "updateAlias", "deleteAlias", "createOrPushAndCreateOrUpdateAlias", "sdkListSearchSchemas", "sdkSetSearchSchema", "sdkUnsetSearchSchema", "SCOPE_LABELS", "setSearchSchema", "marketplace", "opts", "sdkSetSearchSchema", "schemaFor", "scopeLabel", "error", "printError", "unsetSearchSchema", "sdkUnsetSearchSchema", "getDefaultValueLabel", "value", "listSearchSchemas", "schemas", "sdkListSearchSchemas", "rows", "s", "a", "b", "headers", "widths", "h", "row", "headerParts", "i", "width", "padded", "rowParts", "registerSearchCommands", "program", "searchCmd", "options", "sdkPushAssets", "sdkStageAsset", "getApiBaseUrl", "readAuth", "readFileSync", "writeFileSync", "existsSync", "mkdirSync", "readdirSync", "statSync", "unlinkSync", "createWriteStream", "join", "dirname", "createHash", "http", "https", "tmpdir", "pipeline", "chalk", "edn", "yauzl", "ASSET_META_FILENAME", "ASSETS_DIR", "CLEAR_LINE", "CARRIAGE_RETURN", "parseAssetMetadataEdn", "content", "parsed", "version", "assets", "assetList", "asset", "readAssetMetadata", "basePath", "metaPath", "writeAssetMetadata", "metadata", "metaDir", "a", "ednMap", "calculateHash", "data", "prefix", "readLocalAssets", "scanDir", "dir", "relativePath", "entries", "entry", "fullPath", "relPath", "stat", "hash", "listLocalAssetPaths", "validateJsonAssets", "error", "formatDownloadProgress", "bytes", "mb", "printDownloadProgress", "stream", "downloaded", "printProgress", "interval", "chunk", "getApiKeyOrThrow", "auth", "readAuth", "getAssetsPullUrl", "marketplace", "url", "getApiBaseUrl", "getErrorMessage", "body", "statusCode", "message", "getAssetsZipStream", "apiKey", "isHttps", "client", "resolve", "reject", "req", "res", "chunks", "createTempZipPath", "removeAssetsDir", "filename", "readStreamToString", "unzipAssets", "zipPath", "err", "zipfile", "assetMeta", "streamErr", "readStream", "assetPath", "assetDir", "pullAssets", "path", "prune", "localAssets", "currentMeta", "tempZipPath", "zipStream", "newAssetMeta", "remoteVersion", "deletedPaths", "p", "shouldReportUpdate", "printError", "filterChangedAssets", "existingMeta", "hashByPath", "storedHash", "pushAssets", "currentVersion", "changedAssets", "isJsonAsset", "stageableAssets", "localAssetMap", "deleteOperations", "currentAsset", "paths", "stagedByPath", "stagingResult", "sdkStageAsset", "detail", "upsertOperations", "stagingId", "result", "sdkPushAssets", "registerAssetsCommands", "program", "assetsCmd", "opts", "sdkSendNotification", "sdkPreviewNotification", "readFileSync", "existsSync", "statSync", "join", "createServer", "readTemplate", "templatePath", "htmlPath", "subjectPath", "html", "subject", "readContext", "contextPath", "content", "error", "sendNotification", "marketplace", "template", "context", "result", "sdkSendNotification", "printError", "previewNotification", "previewHtml", "fetchPreview", "sdkPreviewNotification", "titleTag", "server", "req", "res", "shutdown", "registerNotificationsCommands", "program", "notificationsCmd", "opts", "sdkGetStatus", "sdkEnable", "sdkDisable", "getStatus", "marketplace", "sdkGetStatus", "error", "printError", "enableApprovals", "sdkEnable", "disableApprovals", "sdkDisable", "registerListingApprovalCommand", "program", "cmd", "opts", "sdkQueryEvents", "sdkPollEvents", "validateParams", "opts", "formatTimestamp", "timestamp", "date", "year", "month", "day", "timeString", "queryEvents", "marketplace", "events", "event", "auditEmails", "eventWithoutEmails", "printTable", "actor", "source", "error", "printError", "tailEvents", "stopPolling", "shutdown", "registerEventsCommand", "program", "cmd", "sdkUpdateStripeVersion", "SUPPORTED_STRIPE_VERSIONS", "inquirer", "promptForVersion", "SUPPORTED_STRIPE_VERSIONS", "promptForConfirmation", "updateStripeVersion", "marketplace", "version", "force", "selectedVersion", "sdkUpdateStripeVersion", "error", "printError", "registerStripeCommands", "program", "opts", "getConfigMap", "readAuth", "maskLast4", "value", "debug", "auth", "apiKey", "confMap", "confMapEntries", "key", "confMapFormatted", "formatHelp", "cmd", "parts", "isRootCommand", "description", "version", "usage", "formatUsage", "allCommands", "collectAllLeafCommands", "hasAction", "maxLength", "c", "cmdInfo", "paddedName", "options", "maxFlagsLength", "opt", "formatOptionFlags", "paddedFlags", "desc", "cmdName", "getCommandName", "results", "commands", "subCmd", "fullName", "getCommandFullName", "subCommands", "subResults", "sub", "a", "b", "names", "current", "hasOptions", "formatted", "part", "trimmed", "valueMatch", "flag", "valueName", "configureHelp", "program", "helper", "routeProcessCommand", "argv", "processIndex", "arg", "nextArg", "__filename", "fileURLToPath", "__dirname", "dirname", "packageJson", "readFileSync", "join", "configDir", "homedir", "noticeShownMarker", "existsSync", "chalk", "mkdirSync", "writeFileSync", "routedArgv", "routeProcessCommand", "program", "Command", "configureHelp", "str", "version", "login", "logout", "debug", "registerProcessCommands", "registerSearchCommands", "registerAssetsCommands", "registerNotificationsCommands", "registerListingApprovalCommand", "registerEventsCommand", "registerStripeCommands", "commandPath", "targetCmd", "cmdName", "subCmd", "c"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sharetribe-cli",
3
- "version": "1.16.6",
3
+ "version": "1.16.8",
4
4
  "description": "UNOFFICIAL Sharetribe CLI reimplementation built on sharetribe-flex-build-sdk - 100% compatible with official flex-cli",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -24,7 +24,7 @@
24
24
  "format": "prettier --write \"src/**/*.ts\"",
25
25
  "format:check": "prettier --check \"src/**/*.ts\"",
26
26
  "typecheck": "tsc --noEmit",
27
- "postinstall": "echo '' >&2 && echo '⚠️ NOTICE: This is an UNOFFICIAL Sharetribe CLI (community reimplementation).' >&2 && echo ' For the official CLI, install: npm install -g flex-cli' >&2 && echo '' >&2",
27
+ "postinstall": "printf '\\n\\033[33m⚠️ NOTICE: This is an UNOFFICIAL Sharetribe CLI (community reimplementation).\\033[0m\\n\\033[33m For the official CLI, install: \\033[36mnpm install -g flex-cli\\033[0m\\n\\n' >&2",
28
28
  "prepublishOnly": "npm run build"
29
29
  },
30
30
  "keywords": [
@@ -48,7 +48,7 @@
48
48
  "commander": "^12.1.0",
49
49
  "inquirer": "^9.2.23",
50
50
  "jsedn": "^0.4.1",
51
- "sharetribe-flex-build-sdk": "^1.16.6",
51
+ "sharetribe-flex-build-sdk": "^1.16.8",
52
52
  "yargs": "^18.0.0",
53
53
  "yauzl": "^3.2.0"
54
54
  },