fimo 2.1.0-staging.1 → 2.1.0-staging.2
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/cli/bundle.json +1 -1
- package/dist/cli/index.js +1 -1
- package/package.json +7 -7
- package/templates/astro/package.json +2 -2
- package/templates/nextjs/package.json +3 -3
- package/templates/react-router/package.json +4 -4
- package/templates/sveltekit/package.json +2 -2
- package/templates/vite/package.json +4 -4
package/dist/cli/bundle.json
CHANGED
package/dist/cli/index.js
CHANGED
|
@@ -1290,7 +1290,7 @@ ${failure.stderr}`});break}}__name(emitPushFailure,"emitPushFailure");function e
|
|
|
1290
1290
|
Purchase: ${formatPrice(pricing.price)} \xD7 ${effectiveYears} year${effectiveYears===1?"":"s"} = ${formatPrice(totalCents)}
|
|
1291
1291
|
Renewal: ${formatPrice(pricing.renewalPrice)}/year${autoRenew===!1?" (auto-renew off)":" (auto-renews)"}`);let confirmed=await ot2({message:`Create a checkout invoice for ${domain}?`,initialValue:!1});if(q(confirmed)||!confirmed){ui.info({command:"domains buy",message:"Cancelled."});return}}let purchased;try{purchased=await api.purchaseRegisteredDomain(organizationId,{domain,years:effectiveYears,autoRenew})}catch(err){rethrowCliAuthError(err);let featureMsg=featureDisabledMessage(err);if(featureMsg){ui.error({command:"domains buy",code:"DOMAIN_PURCHASE_DISABLED",message:featureMsg});return}if(err instanceof ApiRequestError){if(err.status===403){ui.error({command:"domains buy",code:"PURCHASE_FORBIDDEN",message:"You don't have permission to buy domains for this organization.",hint:"Org admins only."});return}ui.error({command:"domains buy",code:"PURCHASE_FAILED",message:`Purchase failed: ${err.detail}`});return}throw err}ui.result({command:"domains buy",data:purchased,render:__name(()=>{let lines=[];return lines.push(""),lines.push(`Invoice created for ${purchased.domain} (${formatPrice(purchased.price)}).`),lines.push("Pay to complete registration:"),lines.push(""),lines.push(` ${purchased.checkoutUrl??"(checkout URL pending \u2014 refresh in a moment)"}`),lines.push(""),lines.push("No money moves until you complete payment in the browser."),lines.push(`Once paid, ${purchased.domain} registers automatically and shows up in \`fimo domains owned\`.`),lines.join(`
|
|
1292
1292
|
`)},"render")}),options.open&&purchased.checkoutUrl&&await open_default(purchased.checkoutUrl).catch(()=>{});let{enabled:waitEnabled,timeoutMs}=parseWait(options,!1);waitEnabled&&await pollPurchasePayment(api,organizationId,purchased,timeoutMs)}__name(domainsBuyCommand,"domainsBuyCommand");async function pollPurchasePayment(api,organizationId,initial,timeoutMs){let start=Date.now(),sp=spinner(`Waiting for payment (status: ${initial.status})`),current=initial;for(;Date.now()-start<timeoutMs;){if(current.status==="owned")return sp.succeed(`Registered \u2014 ${current.domain} is now yours.`),current;if(current.status==="registration_failed"||current.status==="payment_failed")return sp.fail(`${current.status==="payment_failed"?"Payment":"Registration"} failed for ${current.domain}.`),current;await new Promise(resolve10=>setTimeout(resolve10,5e3));try{current=await api.refreshRegisteredDomainPayment(organizationId,current.id),sp.update(`Waiting (status: ${current.status})`)}catch(err){return rethrowCliAuthError(err,()=>sp.fail("Authentication required")),sp.fail(`Refresh failed: ${err instanceof Error?err.message:String(err)}`),current}}return sp.fail("Timed out. Run `fimo domains owned` later to check status."),current}__name(pollPurchasePayment,"pollPurchasePayment");async function domainsOwnedCommand(options){let cfg=loadConfig(),api=new FimoApiClient(cfg),organizationId=resolveOrgId(options),domains2;try{domains2=await api.listOwnedRegisteredDomains(organizationId)}catch(err){rethrowCliAuthError(err);let featureMsg=featureDisabledMessage(err);if(featureMsg){ui.error({command:"domains owned",code:"DOMAIN_PURCHASE_DISABLED",message:featureMsg});return}if(err instanceof ApiRequestError&&err.status===403){ui.error({command:"domains owned",code:"OWNED_DOMAINS_FORBIDDEN",message:"You don't have access to this organization's domains.",hint:"Org admins only."});return}throw err}let statusFilter=options.status?.split(",").map(s=>s.trim().toLowerCase()).filter(s=>s.length>0),limit=options.limit?parseInt(options.limit,10):null,filtered=domains2;if(statusFilter&&statusFilter.length>0&&(filtered=filtered.filter(d3=>statusFilter.includes(d3.status.toLowerCase()))),limit!==null&&Number.isFinite(limit)&&limit>0&&(filtered=filtered.slice(0,limit)),filtered.length===0){ui.info({command:"domains owned",message:"No domains registered through Fimo yet.",hint:"Try `fimo domains search <keyword>`."});return}ui.result({command:"domains owned",data:{domains:filtered,total:filtered.length},render:__name(()=>{let nameW=Math.max(8,...filtered.map(d3=>d3.domain.length)),statusW=Math.max(8,...filtered.map(d3=>d3.status.length)),lines=[];lines.push(` ${pad("DOMAIN",nameW)} ${pad("STATUS",statusW)} EXPIRES`);for(let d3 of filtered){let expires=d3.expirationDate?new Date(d3.expirationDate).toISOString().slice(0,10):"\u2014";lines.push(` ${pad(d3.domain,nameW)} ${pad(d3.status,statusW)} ${expires}`)}return lines.join(`
|
|
1293
|
-
`)},"render")})}__name(domainsOwnedCommand,"domainsOwnedCommand");init_dist();init_api();init_project_context();init_project();import fs33 from"node:fs";import path32 from"node:path";function selectedInputSources(options,inlineFlag){return[options.body!==void 0?inlineFlag:void 0,options.file?"--file":void 0,options.stdin?"--stdin":void 0].filter(source=>!!source)}__name(selectedInputSources,"selectedInputSources");async function readContentInputSource(options,createError,inlineFlag="--body"){if(selectedInputSources(options,inlineFlag).length!==1)throw createError(`Pass exactly one of ${inlineFlag}, --file, or --stdin.`);if(options.body!==void 0)return options.body;if(options.file){let filePath=path32.resolve(resolveProjectCwd(options.cwd),options.file);try{return fs33.readFileSync(filePath,"utf8")}catch(error){throw createError(error instanceof Error?error.message:`Could not read ${filePath}.`)}}if(process.stdin.isTTY)throw createError("Pipe input to the command when using --stdin.");let chunks=[];for await(let chunk of process.stdin)chunks.push(Buffer.isBuffer(chunk)?chunk:Buffer.from(chunk));return Buffer.concat(chunks).toString("utf8")}__name(readContentInputSource,"readContentInputSource");function renderPrettyJson5(data2){return JSON.stringify(data2,null,2)}__name(renderPrettyJson5,"renderPrettyJson");var EntriesInputError=class extends Error{static{__name(this,"EntriesInputError")}constructor(message){super(message),this.name="EntriesInputError"}},DEFAULT_BULK_CHUNK_SIZE=100,MAX_BULK_CHUNK_SIZE=1e3;function parseJsonObject(value){let parsed=JSON.parse(value);if(!parsed||typeof parsed!="object"||Array.isArray(parsed))throw new Error("Expected a JSON object");return parsed}__name(parseJsonObject,"parseJsonObject");function parseJsonArray(value){let parsed;try{parsed=JSON.parse(value)}catch(error){throw new EntriesInputError(error instanceof Error?`Invalid JSON: ${error.message}`:"Invalid JSON.")}if(!Array.isArray(parsed))throw new EntriesInputError("Expected a JSON array.");return parsed}__name(parseJsonArray,"parseJsonArray");function parseChunkSize(value){if(value===void 0)return DEFAULT_BULK_CHUNK_SIZE;let size=Number(value);if(!Number.isInteger(size)||size<1||size>MAX_BULK_CHUNK_SIZE)throw new EntriesInputError(`--chunk-size must be an integer from 1 to ${MAX_BULK_CHUNK_SIZE}.`);return size}__name(parseChunkSize,"parseChunkSize");function chunksOf(items,size){let chunks=[];for(let offset=0;offset<items.length;offset+=size)chunks.push(items.slice(offset,offset+size));return chunks}__name(chunksOf,"chunksOf");function parseEntryInput(value,index2){if(!value||typeof value!="object"||Array.isArray(value))throw new EntriesInputError(`Entry ${index2+1} must be a JSON object.`);let input=value;if(!input.data||typeof input.data!="object"||Array.isArray(input.data))throw new EntriesInputError(`Entry ${index2+1} must include a data object.`);return input}__name(parseEntryInput,"parseEntryInput");function identityValue(input,field,index2){let value=field==="slug"?input.data.slug??input.data[field]:input.data[field];if(typeof value!="string"||value.length===0)throw new EntriesInputError(`Entry ${index2+1} needs a non-empty data.${field} for --upsert-by ${field}.`);return value}__name(identityValue,"identityValue");function identityKey(value,locale){return`${locale??""}\0${value}`}__name(identityKey,"identityKey");async function listEntriesByIdentity(api,projectId,typeName,field,inputs){let byLocale=new Map;for(let[index2,input]of inputs.entries()){let values=byLocale.get(input.locale)??new Set;values.add(identityValue(input,field,index2)),byLocale.set(input.locale,values)}let found=new Map;for(let[locale,values]of byLocale){let result=await api.listEntries(projectId,typeName,{limit:"100",where:JSON.stringify({[field]:{$in:[...values]}}),fields:`id,documentId,${field},locale`,...locale?{locale}:{}});if(result.meta.hasMore)throw new EntriesInputError(`More than 100 ${typeName} entries matched this ${field} batch; reduce --chunk-size.`);for(let entry of result.data){let value=entry[field];if(typeof value!="string")continue;let key=identityKey(value,locale);found.set(key,[...found.get(key)??[],entry])}}return found}__name(listEntriesByIdentity,"listEntriesByIdentity");async function createWithReconciliation(api,projectId,typeName,field,inputs){let pending=inputs,created=0,reconciled=0;for(let attempt=0;attempt<2&&pending.length>0;attempt+=1)try{let result=await api.bulkCreateEntries(projectId,typeName,pending);created+=result.meta.created,pending=[]}catch(error){if(!(error instanceof ApiRequestError)||error.status!==504)throw error;let existing=await listEntriesByIdentity(api,projectId,typeName,field,pending),absent=pending.filter((input,index2)=>{let key=identityKey(identityValue(input,field,index2),input.locale);return(existing.get(key)?.length??0)===0});reconciled+=pending.length-absent.length,pending=absent}if(pending.length>0)throw new EntriesInputError(`${pending.length} entries remain absent after reconciling an ambiguous 504; rerun the same upsert input safely.`);return{created,reconciled}}__name(createWithReconciliation,"createWithReconciliation");async function upsertChunk(api,projectId,typeName,field,inputs,chunk,identityCounts){let existing=await listEntriesByIdentity(api,projectId,typeName,field,inputs),creates=[],updates=[],conflicts=0;for(let[index2,input]of inputs.entries()){let key=identityKey(identityValue(input,field,index2),input.locale),matches=existing.get(key)??[];if((identityCounts.get(key)??0)>1||matches.length>1){conflicts+=1;continue}matches.length===1?updates.push({id:matches[0].documentId,body:input}):creates.push(input)}let updated=0;if(updates.length>0)try{let result=await api.bulkUpdateEntries(projectId,typeName,{updates});updated=result.meta.updated,conflicts+=result.meta.missing.length}catch(error){throw!(error instanceof ApiRequestError)||error.status!==504?error:(await listEntriesByIdentity(api,projectId,typeName,field,inputs),new EntriesInputError(`${updates.length} updates had an ambiguous 504; identities were reread without replay. Rerun the same upsert input safely.`))}let createResult=await createWithReconciliation(api,projectId,typeName,field,creates);return{chunk,input:inputs.length,created:createResult.created,updated,conflicts,reconciled:createResult.reconciled}}__name(upsertChunk,"upsertChunk");function parseBulkJsonObject(value){try{return parseJsonObject(value)}catch(error){throw new EntriesInputError(error instanceof Error?error.message:"Expected a JSON object.")}}__name(parseBulkJsonObject,"parseBulkJsonObject");function parseIds(value){let ids=[...new Set(value.split(",").map(id=>id.trim()).filter(Boolean))];if(ids.length===0)throw new EntriesInputError("--ids must include at least one ID.");return ids}__name(parseIds,"parseIds");function missingIdWarnings(result,action){let{missing}=result.meta;if(missing.length===0)return[];let changed=action==="updated"?result.meta.updated:result.meta.deleted,ids=missing.join(", ");if(changed===0)return missing.length===1?[`No entries were ${action}; the requested ID was not found: ${ids}.`]:[`No entries were ${action}; all ${missing.length} requested IDs were not found: ${ids}.`];let subject=missing.length===1?"ID was":"IDs were";return[`${missing.length} requested ${subject} not found: ${ids}.`]}__name(missingIdWarnings,"missingIdWarnings");function addDefinedMetadata(body,metadata){for(let[key,value]of Object.entries(metadata))value!==void 0&&(body[key]=value);return body}__name(addDefinedMetadata,"addDefinedMetadata");async function entriesListCommand(typeName,options,cmd){let{ctx,api}=await bootstrapProjectCommand(options,cmd);await requireOperation("cms.list",{projectId:ctx.projectId,env:ctx.env});let params={};options.limit&&(params.limit=options.limit),options.offset&&(params.offset=options.offset),options.search&&(params.search=options.search),options.sort&&(params.sort=options.sort),!options.sort&&options.sortBy&&(params.sortBy=options.sortBy),!options.sort&&options.sortDirection&&(params.sortDirection=options.sortDirection),options.where&&(JSON.parse(options.where),params.where=options.where),options.fields&&(params.fields=options.fields),options.populate&&(params.populate=options.populate),options.locale&&(params.locale=options.locale);let result=await api.listEntries(ctx.projectId,typeName,Object.keys(params).length>0?params:void 0);ui.result({command:"entries list",data:result,render:__name(()=>renderPrettyJson5(result),"render")})}__name(entriesListCommand,"entriesListCommand");async function entriesGetCommand(typeName,id,options,cmd){let{ctx,api}=await bootstrapProjectCommand(options,cmd);await requireOperation("cms.get",{projectId:ctx.projectId,env:ctx.env});let result=await api.getEntry(ctx.projectId,typeName,id,options.locale);ui.result({command:"entries get",data:result,render:__name(()=>renderPrettyJson5(result),"render")})}__name(entriesGetCommand,"entriesGetCommand");async function entriesCreateCommand(typeName,options,cmd){let{ctx,api}=await bootstrapProjectCommand(options,cmd,{refuseReadOnly:!0});await requireOperation("cms.create",{projectId:ctx.projectId,env:ctx.env});let data2=addDefinedMetadata(parseJsonObject(options.body),{locale:options.locale,documentId:options.documentId}),result=await api.createEntry(ctx.projectId,typeName,data2);ui.result({command:"entries create",data:result,render:__name(()=>renderPrettyJson5(result),"render")})}__name(entriesCreateCommand,"entriesCreateCommand");async function entriesUpdateCommand(typeName,id,options,cmd){let{ctx,api}=await bootstrapProjectCommand(options,cmd,{refuseReadOnly:!0});await requireOperation("cms.update",{projectId:ctx.projectId,env:ctx.env});let data2=parseJsonObject(options.body),result=await api.updateEntry(ctx.projectId,typeName,id,options.locale,data2);ui.result({command:"entries update",data:result,render:__name(()=>renderPrettyJson5(result),"render")})}__name(entriesUpdateCommand,"entriesUpdateCommand");async function entriesDeleteCommand(typeName,id,options,cmd){let{ctx,api}=await bootstrapProjectCommand(options,cmd,{refuseReadOnly:!0});await requireOperation("cms.delete",{projectId:ctx.projectId,env:ctx.env});let result=await api.deleteEntry(ctx.projectId,typeName,id,options.locale);ui.result({command:"entries delete",data:result,render:__name(()=>renderPrettyJson5(result),"render")})}__name(entriesDeleteCommand,"entriesDeleteCommand");async function entriesQueryCommand(options,cmd){let{ctx,api}=await bootstrapProjectCommand(options,cmd);await requireOperation("cms.query",{projectId:ctx.projectId,env:ctx.env});let sql=await readContentInputSource({...options,body:options.sql},message=>new EntriesInputError(message),"--sql"),result=await api.queryEntries(ctx.projectId,sql);ui.result({command:"entries query",data:result,render:__name(()=>renderPrettyJson5(result),"render")})}__name(entriesQueryCommand,"entriesQueryCommand");async function entriesBulkCreateCommand(typeName,options,cmd){let{ctx,api}=await bootstrapProjectCommand(options,cmd,{refuseReadOnly:!0});await requireOperation("cms.bulk_create",{projectId:ctx.projectId,env:ctx.env}),options.upsertBy&&(await requireOperation("cms.list",{projectId:ctx.projectId,env:ctx.env}),await requireOperation("cms.bulk_update",{projectId:ctx.projectId,env:ctx.env}));let entries2=parseJsonArray(await readContentInputSource(options,message=>new EntriesInputError(message)));if(entries2.length===0){if(options.upsertBy)throw new EntriesInputError("Upsert input must be a non-empty JSON array.");let result2=await api.bulkCreateEntries(ctx.projectId,typeName,entries2);ui.result({command:"entries bulk-create",data:result2,render:__name(()=>renderPrettyJson5(result2),"render")});return}let upsertInputs=options.upsertBy?entries2.map((entry,index2)=>parseEntryInput(entry,index2)):[],identityCounts=new Map;if(options.upsertBy)for(let[index2,input]of upsertInputs.entries()){let key=identityKey(identityValue(input,options.upsertBy,index2),input.locale);identityCounts.set(key,(identityCounts.get(key)??0)+1)}let chunks=chunksOf(options.upsertBy?upsertInputs:entries2,parseChunkSize(options.chunkSize)),receipts=[],data2=[];for(let[index2,chunk]of chunks.entries()){if(options.upsertBy){receipts.push(await upsertChunk(api,ctx.projectId,typeName,options.upsertBy,chunk,index2+1,identityCounts));continue}let result2=await api.bulkCreateEntries(ctx.projectId,typeName,chunk);data2.push(...result2.data),receipts.push({chunk:index2+1,input:chunk.length,created:result2.meta.created,updated:0,conflicts:0,reconciled:0})}let result={data:data2,meta:{created:receipts.reduce((sum,receipt)=>sum+receipt.created,0),updated:receipts.reduce((sum,receipt)=>sum+receipt.updated,0),conflicts:receipts.reduce((sum,receipt)=>sum+receipt.conflicts,0),chunks:receipts}};ui.result({command:"entries bulk-create",data:result,render:__name(()=>renderPrettyJson5(result),"render")})}__name(entriesBulkCreateCommand,"entriesBulkCreateCommand");async function entriesBulkUpdateCommand(typeName,options,cmd){let{ctx,api}=await bootstrapProjectCommand(options,cmd,{refuseReadOnly:!0});await requireOperation("cms.bulk_update",{projectId:ctx.projectId,env:ctx.env});let usesBatchInput=!!(options.file||options.stdin),payload;if(usesBatchInput){if(options.body!==void 0||options.ids||options.where)throw new EntriesInputError("Use --file or --stdin alone for per-entry updates.");payload={updates:parseJsonArray(await readContentInputSource(options,message=>new EntriesInputError(message)))}}else{if((options.ids?1:0)+(options.where?1:0)!=1||options.body===void 0)throw new EntriesInputError("Pass --body with exactly one of --ids or --where.");payload={...options.ids?{ids:parseIds(options.ids)}:{where:parseBulkJsonObject(options.where)},body:parseBulkJsonObject(options.body)}}let result=await api.bulkUpdateEntries(ctx.projectId,typeName,payload);ui.result({command:"entries bulk-update",data:result,warnings:missingIdWarnings(result,"updated"),render:__name(()=>renderPrettyJson5(result),"render")})}__name(entriesBulkUpdateCommand,"entriesBulkUpdateCommand");async function entriesBulkDeleteCommand(typeName,options,cmd){let{ctx,api}=await bootstrapProjectCommand(options,cmd,{refuseReadOnly:!0});if(await requireOperation("cms.bulk_delete",{projectId:ctx.projectId,env:ctx.env}),(options.ids?1:0)+(options.where?1:0)!=1)throw new EntriesInputError("Pass exactly one of --ids or --where.");let payload={...options.ids?{ids:parseIds(options.ids)}:{where:parseBulkJsonObject(options.where)},...options.locale?{locale:options.locale}:{}},result=await api.bulkDeleteEntries(ctx.projectId,typeName,payload);ui.result({command:"entries bulk-delete",data:result,warnings:missingIdWarnings(result,"deleted"),render:__name(()=>renderPrettyJson5(result),"render")})}__name(entriesBulkDeleteCommand,"entriesBulkDeleteCommand");init_dist();init_api();init_config();init_auth_errors();init_project();function collect(value,previous){return[...previous??[],value]}__name(collect,"collect");function addScopeOptions(command){return command.option("--project <id>","Project id (defaults to the locally linked project)").option("-C, --cwd <dir>","Project directory")}__name(addScopeOptions,"addScopeOptions");function registerEnvironmentsCommands(program2){let environments=program2.command("environments").description("Group project Branches into deployment Environments").addHelpText("after",`
|
|
1293
|
+
`)},"render")})}__name(domainsOwnedCommand,"domainsOwnedCommand");init_dist();init_api();init_project_context();init_project();import fs33 from"node:fs";import path32 from"node:path";function selectedInputSources(options,inlineFlag){return[options.body!==void 0?inlineFlag:void 0,options.file?"--file":void 0,options.stdin?"--stdin":void 0].filter(source=>!!source)}__name(selectedInputSources,"selectedInputSources");async function readContentInputSource(options,createError,inlineFlag="--body"){if(selectedInputSources(options,inlineFlag).length!==1)throw createError(`Pass exactly one of ${inlineFlag}, --file, or --stdin.`);if(options.body!==void 0)return options.body;if(options.file){let filePath=path32.resolve(resolveProjectCwd(options.cwd),options.file);try{return fs33.readFileSync(filePath,"utf8")}catch(error){throw createError(error instanceof Error?error.message:`Could not read ${filePath}.`)}}if(process.stdin.isTTY)throw createError("Pipe input to the command when using --stdin.");let chunks=[];for await(let chunk of process.stdin)chunks.push(Buffer.isBuffer(chunk)?chunk:Buffer.from(chunk));return Buffer.concat(chunks).toString("utf8")}__name(readContentInputSource,"readContentInputSource");function renderPrettyJson5(data2){return JSON.stringify(data2,null,2)}__name(renderPrettyJson5,"renderPrettyJson");var EntriesInputError=class extends Error{static{__name(this,"EntriesInputError")}constructor(message){super(message),this.name="EntriesInputError"}},DEFAULT_BULK_CHUNK_SIZE=100,MAX_BULK_CHUNK_SIZE=1e3;function parseJsonObject(value){let parsed=JSON.parse(value);if(!parsed||typeof parsed!="object"||Array.isArray(parsed))throw new Error("Expected a JSON object");return parsed}__name(parseJsonObject,"parseJsonObject");function parseJsonArray(value){let parsed;try{parsed=JSON.parse(value)}catch(error){throw new EntriesInputError(error instanceof Error?`Invalid JSON: ${error.message}`:"Invalid JSON.")}if(!Array.isArray(parsed))throw new EntriesInputError("Expected a JSON array.");return parsed}__name(parseJsonArray,"parseJsonArray");function parseChunkSize(value){if(value===void 0)return DEFAULT_BULK_CHUNK_SIZE;let size=Number(value);if(!Number.isInteger(size)||size<1||size>MAX_BULK_CHUNK_SIZE)throw new EntriesInputError(`--chunk-size must be an integer from 1 to ${MAX_BULK_CHUNK_SIZE}.`);return size}__name(parseChunkSize,"parseChunkSize");function chunksOf(items,size){let chunks=[];for(let offset=0;offset<items.length;offset+=size)chunks.push(items.slice(offset,offset+size));return chunks}__name(chunksOf,"chunksOf");function parseEntryInput(value,index2){if(!value||typeof value!="object"||Array.isArray(value))throw new EntriesInputError(`Entry ${index2+1} must be a JSON object.`);let input=value;if(!input.data||typeof input.data!="object"||Array.isArray(input.data))throw new EntriesInputError(`Entry ${index2+1} must include a data object.`);return input}__name(parseEntryInput,"parseEntryInput");function identityValue(input,field,index2){let value=field==="slug"?input.data.slug??input.data[field]:input.data[field];if(typeof value!="string"||value.length===0)throw new EntriesInputError(`Entry ${index2+1} needs a non-empty data.${field} for --upsert-by ${field}.`);return value}__name(identityValue,"identityValue");function identityKey(value,locale){return`${locale??""}\0${value}`}__name(identityKey,"identityKey");async function listEntriesByIdentity(api,projectId,typeName,field,inputs){let byLocale=new Map;for(let[index2,input]of inputs.entries()){let values=byLocale.get(input.locale)??new Set;values.add(identityValue(input,field,index2)),byLocale.set(input.locale,values)}let found=new Map;for(let[locale,values]of byLocale){let result=await api.listEntries(projectId,typeName,{limit:"100",where:JSON.stringify({[field]:{$in:[...values]}}),fields:`id,documentId,${field},locale`,...locale?{locale}:{}});if(result.meta.hasMore)throw new EntriesInputError(`More than 100 ${typeName} entries matched this ${field} batch; reduce --chunk-size.`);for(let entry of result.data){let value=entry[field];if(typeof value!="string")continue;let key=identityKey(value,locale);found.set(key,[...found.get(key)??[],entry])}}return found}__name(listEntriesByIdentity,"listEntriesByIdentity");async function createWithReconciliation(api,projectId,typeName,field,inputs){let pending=inputs,created=0,reconciled=0;for(let attempt=0;attempt<2&&pending.length>0;attempt+=1)try{let result=await api.bulkCreateEntries(projectId,typeName,pending);created+=result.meta.created,pending=[]}catch(error){if(!(error instanceof ApiRequestError)||error.status!==504)throw error;let existing=await listEntriesByIdentity(api,projectId,typeName,field,pending),absent=pending.filter((input,index2)=>{let key=identityKey(identityValue(input,field,index2),input.locale);return(existing.get(key)?.length??0)===0});reconciled+=pending.length-absent.length,pending=absent}if(pending.length>0)throw new EntriesInputError(`${pending.length} entries remain absent after reconciling an ambiguous 504; rerun the same upsert input safely.`);return{created,reconciled}}__name(createWithReconciliation,"createWithReconciliation");async function upsertChunk(api,projectId,typeName,field,inputs,chunk,identityCounts){let existing=await listEntriesByIdentity(api,projectId,typeName,field,inputs),creates=[],updates=[],conflicts=0;for(let[index2,input]of inputs.entries()){let key=identityKey(identityValue(input,field,index2),input.locale),matches=existing.get(key)??[];if((identityCounts.get(key)??0)>1||matches.length>1){conflicts+=1;continue}matches.length===1?updates.push({id:matches[0].documentId,body:input}):creates.push(input)}let updated=0;if(updates.length>0)try{let result=await api.bulkUpdateEntries(projectId,typeName,{updates});updated=result.meta.updated,conflicts+=result.meta.missing.length}catch(error){throw!(error instanceof ApiRequestError)||error.status!==504?error:(await listEntriesByIdentity(api,projectId,typeName,field,inputs),new EntriesInputError(`${updates.length} updates had an ambiguous 504; identities were reread without replay. Rerun the same upsert input safely.`))}let createResult=await createWithReconciliation(api,projectId,typeName,field,creates);return{chunk,input:inputs.length,created:createResult.created,updated,conflicts,reconciled:createResult.reconciled}}__name(upsertChunk,"upsertChunk");function parseBulkJsonObject(value){try{return parseJsonObject(value)}catch(error){throw new EntriesInputError(error instanceof Error?error.message:"Expected a JSON object.")}}__name(parseBulkJsonObject,"parseBulkJsonObject");function parseIds(value){let ids=[...new Set(value.split(",").map(id=>id.trim()).filter(Boolean))];if(ids.length===0)throw new EntriesInputError("--ids must include at least one ID.");return ids}__name(parseIds,"parseIds");function missingIdWarnings(result,action){let{missing}=result.meta;if(missing.length===0)return[];let changed=action==="updated"?result.meta.updated:result.meta.deleted,ids=missing.join(", ");if(changed===0)return missing.length===1?[`No entries were ${action}; the requested ID was not found: ${ids}.`]:[`No entries were ${action}; all ${missing.length} requested IDs were not found: ${ids}.`];let subject=missing.length===1?"ID was":"IDs were";return[`${missing.length} requested ${subject} not found: ${ids}.`]}__name(missingIdWarnings,"missingIdWarnings");function addDefinedMetadata(body,metadata){for(let[key,value]of Object.entries(metadata))value!==void 0&&(body[key]=value);return body}__name(addDefinedMetadata,"addDefinedMetadata");async function entriesListCommand(typeName,options,cmd){let{ctx,api}=await bootstrapProjectCommand(options,cmd);await requireOperation("cms.list",{projectId:ctx.projectId,env:ctx.env});let params={};options.limit&&(params.limit=options.limit),options.offset&&(params.offset=options.offset),options.search&&(params.search=options.search),options.sort&&(params.sort=options.sort),!options.sort&&options.sortBy&&(params.sortBy=options.sortBy),!options.sort&&options.sortDirection&&(params.sortDirection=options.sortDirection),options.where&&(JSON.parse(options.where),params.where=options.where),options.fields&&(params.fields=options.fields),options.populate&&(params.populate=options.populate),options.locale&&(params.locale=options.locale);let result=await api.listEntries(ctx.projectId,typeName,Object.keys(params).length>0?params:void 0);ui.result({command:"entries list",data:result,render:__name(()=>renderPrettyJson5(result),"render")})}__name(entriesListCommand,"entriesListCommand");async function entriesGetCommand(typeName,id,options,cmd){let{ctx,api}=await bootstrapProjectCommand(options,cmd);await requireOperation("cms.get",{projectId:ctx.projectId,env:ctx.env});let result=await api.getEntry(ctx.projectId,typeName,id,options.locale);ui.result({command:"entries get",data:result,render:__name(()=>renderPrettyJson5(result),"render")})}__name(entriesGetCommand,"entriesGetCommand");async function entriesCreateCommand(typeName,options,cmd){let{ctx,api}=await bootstrapProjectCommand(options,cmd,{refuseReadOnly:!0});await requireOperation("cms.create",{projectId:ctx.projectId,env:ctx.env});let data2=addDefinedMetadata(parseJsonObject(options.body),{locale:options.locale,documentId:options.documentId}),result=await api.createEntry(ctx.projectId,typeName,data2);ui.result({command:"entries create",data:result,render:__name(()=>renderPrettyJson5(result),"render")})}__name(entriesCreateCommand,"entriesCreateCommand");async function entriesUpdateCommand(typeName,id,options,cmd){let{ctx,api}=await bootstrapProjectCommand(options,cmd,{refuseReadOnly:!0});await requireOperation("cms.update",{projectId:ctx.projectId,env:ctx.env});let data2=parseJsonObject(options.body),result=await api.updateEntry(ctx.projectId,typeName,id,options.locale,data2);ui.result({command:"entries update",data:result,render:__name(()=>renderPrettyJson5(result),"render")})}__name(entriesUpdateCommand,"entriesUpdateCommand");async function entriesDeleteCommand(typeName,id,options,cmd){let{ctx,api}=await bootstrapProjectCommand(options,cmd,{refuseReadOnly:!0});await requireOperation("cms.delete",{projectId:ctx.projectId,env:ctx.env});let result=await api.deleteEntry(ctx.projectId,typeName,id,options.locale);ui.result({command:"entries delete",data:result,render:__name(()=>renderPrettyJson5(result),"render")})}__name(entriesDeleteCommand,"entriesDeleteCommand");async function entriesQueryCommand(options,cmd){let{ctx,api}=await bootstrapProjectCommand(options,cmd);await requireOperation("cms.query",{projectId:ctx.projectId,env:ctx.env});let sql=await readContentInputSource({...options,body:options.sql},message=>new EntriesInputError(message),"--sql"),result=await api.queryEntries(ctx.projectId,sql);ui.result({command:"entries query",data:result,render:__name(()=>renderPrettyJson5(result),"render")})}__name(entriesQueryCommand,"entriesQueryCommand");async function entriesBulkCreateCommand(typeName,options,cmd){let{ctx,api}=await bootstrapProjectCommand(options,cmd,{refuseReadOnly:!0});await requireOperation("cms.bulk_create",{projectId:ctx.projectId,env:ctx.env}),options.upsertBy&&(await requireOperation("cms.list",{projectId:ctx.projectId,env:ctx.env}),await requireOperation("cms.bulk_update",{projectId:ctx.projectId,env:ctx.env}));let entries2=parseJsonArray(await readContentInputSource(options,message=>new EntriesInputError(message))),chunkSize=parseChunkSize(options.chunkSize);if(entries2.length===0){if(options.upsertBy)throw new EntriesInputError("Upsert input must be a non-empty JSON array.");let result2=await api.bulkCreateEntries(ctx.projectId,typeName,entries2);ui.result({command:"entries bulk-create",data:result2,render:__name(()=>renderPrettyJson5(result2),"render")});return}let upsertInputs=options.upsertBy?entries2.map((entry,index2)=>parseEntryInput(entry,index2)):[],identityCounts=new Map;if(options.upsertBy)for(let[index2,input]of upsertInputs.entries()){let key=identityKey(identityValue(input,options.upsertBy,index2),input.locale);identityCounts.set(key,(identityCounts.get(key)??0)+1)}let chunks=chunksOf(options.upsertBy?upsertInputs:entries2,chunkSize),receipts=[],data2=[];for(let[index2,chunk]of chunks.entries()){if(options.upsertBy){receipts.push(await upsertChunk(api,ctx.projectId,typeName,options.upsertBy,chunk,index2+1,identityCounts));continue}let result2=await api.bulkCreateEntries(ctx.projectId,typeName,chunk);data2.push(...result2.data),receipts.push({chunk:index2+1,input:chunk.length,created:result2.meta.created,updated:0,conflicts:0,reconciled:0})}let result={data:data2,meta:{created:receipts.reduce((sum,receipt)=>sum+receipt.created,0),updated:receipts.reduce((sum,receipt)=>sum+receipt.updated,0),conflicts:receipts.reduce((sum,receipt)=>sum+receipt.conflicts,0),chunks:receipts}};ui.result({command:"entries bulk-create",data:result,render:__name(()=>renderPrettyJson5(result),"render")})}__name(entriesBulkCreateCommand,"entriesBulkCreateCommand");async function entriesBulkUpdateCommand(typeName,options,cmd){let{ctx,api}=await bootstrapProjectCommand(options,cmd,{refuseReadOnly:!0});await requireOperation("cms.bulk_update",{projectId:ctx.projectId,env:ctx.env});let usesBatchInput=!!(options.file||options.stdin),payload;if(usesBatchInput){if(options.body!==void 0||options.ids||options.where)throw new EntriesInputError("Use --file or --stdin alone for per-entry updates.");payload={updates:parseJsonArray(await readContentInputSource(options,message=>new EntriesInputError(message)))}}else{if((options.ids?1:0)+(options.where?1:0)!=1||options.body===void 0)throw new EntriesInputError("Pass --body with exactly one of --ids or --where.");payload={...options.ids?{ids:parseIds(options.ids)}:{where:parseBulkJsonObject(options.where)},body:parseBulkJsonObject(options.body)}}let result=await api.bulkUpdateEntries(ctx.projectId,typeName,payload);ui.result({command:"entries bulk-update",data:result,warnings:missingIdWarnings(result,"updated"),render:__name(()=>renderPrettyJson5(result),"render")})}__name(entriesBulkUpdateCommand,"entriesBulkUpdateCommand");async function entriesBulkDeleteCommand(typeName,options,cmd){let{ctx,api}=await bootstrapProjectCommand(options,cmd,{refuseReadOnly:!0});if(await requireOperation("cms.bulk_delete",{projectId:ctx.projectId,env:ctx.env}),(options.ids?1:0)+(options.where?1:0)!=1)throw new EntriesInputError("Pass exactly one of --ids or --where.");let payload={...options.ids?{ids:parseIds(options.ids)}:{where:parseBulkJsonObject(options.where)},...options.locale?{locale:options.locale}:{}},result=await api.bulkDeleteEntries(ctx.projectId,typeName,payload);ui.result({command:"entries bulk-delete",data:result,warnings:missingIdWarnings(result,"deleted"),render:__name(()=>renderPrettyJson5(result),"render")})}__name(entriesBulkDeleteCommand,"entriesBulkDeleteCommand");init_dist();init_api();init_config();init_auth_errors();init_project();function collect(value,previous){return[...previous??[],value]}__name(collect,"collect");function addScopeOptions(command){return command.option("--project <id>","Project id (defaults to the locally linked project)").option("-C, --cwd <dir>","Project directory")}__name(addScopeOptions,"addScopeOptions");function registerEnvironmentsCommands(program2){let environments=program2.command("environments").description("Group project Branches into deployment Environments").addHelpText("after",`
|
|
1294
1294
|
Environments group Branches. Production is the deployed snapshot published from main.
|
|
1295
1295
|
Automatic previews receives every unclaimed Branch, including main.
|
|
1296
1296
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fimo",
|
|
3
|
-
"version": "2.1.0-staging.
|
|
3
|
+
"version": "2.1.0-staging.2",
|
|
4
4
|
"description": "Fimo CLI - create, deploy, and manage Fimo projects",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"astro-component"
|
|
@@ -184,12 +184,12 @@
|
|
|
184
184
|
"devDependencies": {
|
|
185
185
|
"@clack/core": "^1.2.0",
|
|
186
186
|
"@clack/prompts": "^1.2.0",
|
|
187
|
-
"@fimo/agents-bundle": "2.1.0-staging.
|
|
188
|
-
"@fimo/api-contracts": "2.1.0-staging.
|
|
189
|
-
"@fimo/cli-kit": "2.1.0-staging.
|
|
190
|
-
"@fimo/framework-detect": "2.1.0-staging.
|
|
191
|
-
"@fimo/routes": "2.1.0-staging.
|
|
192
|
-
"@fimo/tsconfig": "2.1.0-staging.
|
|
187
|
+
"@fimo/agents-bundle": "2.1.0-staging.2",
|
|
188
|
+
"@fimo/api-contracts": "2.1.0-staging.2",
|
|
189
|
+
"@fimo/cli-kit": "2.1.0-staging.2",
|
|
190
|
+
"@fimo/framework-detect": "2.1.0-staging.2",
|
|
191
|
+
"@fimo/routes": "2.1.0-staging.2",
|
|
192
|
+
"@fimo/tsconfig": "2.1.0-staging.2",
|
|
193
193
|
"@types/node": "22.18.6",
|
|
194
194
|
"agent-install": "^0.0.5",
|
|
195
195
|
"astro": "^7.1.6",
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@tanstack/react-query": "^5.80.6",
|
|
15
|
-
"fimo": "2.1.0-staging.
|
|
16
|
-
"fimo-next": "2.1.0-staging.
|
|
17
|
-
"fimo-react": "2.1.0-staging.
|
|
15
|
+
"fimo": "2.1.0-staging.2",
|
|
16
|
+
"fimo-next": "2.1.0-staging.2",
|
|
17
|
+
"fimo-react": "2.1.0-staging.2",
|
|
18
18
|
"next": "^16.3.0",
|
|
19
19
|
"react": "^19.2.7",
|
|
20
20
|
"react-dom": "^19.2.7"
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
"cmdk": "^1.1.1",
|
|
22
22
|
"date-fns": "^4.1.0",
|
|
23
23
|
"embla-carousel-react": "^8.6.0",
|
|
24
|
-
"fimo": "2.1.0-staging.
|
|
25
|
-
"fimo-react": "2.1.0-staging.
|
|
26
|
-
"fimo-react-router": "2.1.0-staging.
|
|
27
|
-
"fimo-vite": "2.1.0-staging.
|
|
24
|
+
"fimo": "2.1.0-staging.2",
|
|
25
|
+
"fimo-react": "2.1.0-staging.2",
|
|
26
|
+
"fimo-react-router": "2.1.0-staging.2",
|
|
27
|
+
"fimo-vite": "2.1.0-staging.2",
|
|
28
28
|
"input-otp": "^1.4.2",
|
|
29
29
|
"isbot": "^5",
|
|
30
30
|
"lucide-react": "^0.577.0",
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"prepare": "svelte-kit sync"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"fimo": "2.1.0-staging.
|
|
15
|
-
"fimo-sveltekit": "2.1.0-staging.
|
|
14
|
+
"fimo": "2.1.0-staging.2",
|
|
15
|
+
"fimo-sveltekit": "2.1.0-staging.2"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
18
|
"@sveltejs/kit": "^2.70.2",
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@tanstack/react-query": "^5.80.6",
|
|
14
|
-
"fimo": "2.1.0-staging.
|
|
15
|
-
"fimo-react": "2.1.0-staging.
|
|
16
|
-
"fimo-react-router": "2.1.0-staging.
|
|
17
|
-
"fimo-vite": "2.1.0-staging.
|
|
14
|
+
"fimo": "2.1.0-staging.2",
|
|
15
|
+
"fimo-react": "2.1.0-staging.2",
|
|
16
|
+
"fimo-react-router": "2.1.0-staging.2",
|
|
17
|
+
"fimo-vite": "2.1.0-staging.2",
|
|
18
18
|
"react": "^19.2.7",
|
|
19
19
|
"react-dom": "^19.2.7",
|
|
20
20
|
"react-router": "^8.3.0"
|