@farthershore/cli 0.24.3 → 0.24.4
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/README.md +1 -1
- package/dist/index.js +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Create and operate [FartherShore](https://farthershore.com) software businesses
|
|
4
4
|
from the terminal.
|
|
5
5
|
|
|
6
|
-
**Status: `0.24.
|
|
6
|
+
**Status: `0.24.4`.** Pre-1.0 — the command surface is stable but may still
|
|
7
7
|
change between minor versions. Pin an exact version in CI.
|
|
8
8
|
|
|
9
9
|
FartherShore lets you define a software business as code, then sells, meters,
|
package/dist/index.js
CHANGED
|
@@ -2025,7 +2025,7 @@ Examples:
|
|
|
2025
2025
|
Available templates:
|
|
2026
2026
|
${cp().map(e=>` ${e.kind.padEnd(8)} ${e.description}`).join(`
|
|
2027
2027
|
`)}
|
|
2028
|
-
`).action(async e=>{let r,o=e.path;if(e.template)r=E$(e.template);else if(u_.isTTY&&d_.isTTY){let p=S$({input:u_,output:d_});try{let m=await j$({ask:g=>p.question(g),log:g=>{console.log(g)}});if(!m){G("Cancelled.");return}r=m.kind,o=o??m.path}finally{p.close()}}else throw new b(`--template is required when stdin is not a TTY. Choose one of: ${ke.join(", ")}.`,void 0,{code:"INIT_TEMPLATE_REQUIRED"});let n=Pi(r),i=p_(o??fr),s=ur(e);if(kp(i)&&!e.force)throw new b(`${i} already exists. Pass --force to overwrite.`,void 0,{code:"INIT_FILE_EXISTS"});let c=C$(n,i,s),l=c.map(p=>p.path).filter(p=>kp(p));if(l.length>0&&!e.force)throw new b(`${l[0]} already exists. Pass --force to overwrite.`,void 0,{code:"INIT_FILE_EXISTS"});let d=R$(i);if(d)throw new b(`${d} already declares an @Business class. Folder discovery compiles every module under business/, so scaffolding ${i} beside it would leave two @Business classes. Remove or rename ${d} first.`,void 0,{code:"INIT_BUSINESS_EXISTS"});for(let p of c)v$(mr(p.path),{recursive:!0}),k$(p.path,p.content,"utf-8");let u=c.find(p=>p.path===i)?.content??m_(n,s);F({template:r,path:i,surfaces:ip(s),preset:{kind:n.kind,label:n.label},content:u,files:c},`Scaffolded ${i} from preset "${n.label}".`),G(`Next: edit ${o??fr}, then run \`farthershore build\`.`)})}import{existsSync as Ip,lstatSync as Y$,mkdirSync as X$,mkdtempSync as Q$,readFileSync as eT,rmSync as S_,writeFileSync as tT}from"node:fs";import*as I_ from"node:fs";import{randomUUID as nT}from"node:crypto";import{gunzipSync as rT}from"node:zlib";import{join as br,relative as oT,resolve as w_}from"node:path";import{mkdirSync as g_,writeFileSync as L$}from"node:fs";import{dirname as M$,posix as h_,resolve as b_,sep as F$}from"node:path";var hr={maxEntries:2e3,maxFileBytes:20*1024*1024,maxPathBytes:512,maxPathComponentBytes:255},gr=512,B$=new Set(["x","g"]),V$=new Set(["0","","5"]),H$=new Set(["1","2"]);function __(t,e,r=()=>!1){let o=Z$(t).filter(s=>!r(s.path)),n=b_(e),i=[];for(let s of o){let c=b_(n,s.path);if(!J$(n,c))throw new Error(`Tar entry escapes destination: ${s.path}`);if("directory"in s){g_(c,{recursive:!0});continue}g_(M$(c),{recursive:!0}),L$(c,s.content,s.mode?{mode:s.mode}:void 0),i.push(s.path)}return i}function Z$(t){let e=[],r=0,o=null;for(;r+gr<=t.length;){let n=t.subarray(r,r+gr);if(q$(n))break;let i=Ui(n,0,100),s=Ui(n,345,155),c=s?`${s}/${i}`:i,l=v_(n,124,12),d=v_(n,100,8),u=Ui(n,156,1)||"0",p=r+gr,m=p+l;if(m>t.length)throw new Error(`Tar entry "${c}" is truncated.`);if(r=p+Math.ceil(l/gr)*gr,!K$(c,u,l))continue;let g=G$(c,o);if(!g.path){o=g.rootPrefix;continue}o=g.rootPrefix;let x=W$(g.path);if(u==="5"?e.push({path:x,directory:!0}):e.push({path:x,content:Buffer.from(t.subarray(p,m)),mode:Number.isFinite(d)&&d>0?d:void 0}),e.length>hr.maxEntries)throw new Error(`Tar archive exceeds ${hr.maxEntries} entries.`)}return e}function K$(t,e,r){if(B$.has(e))return!1;if(H$.has(e))throw new Error(`Refusing link tar entry: ${t}`);if(!V$.has(e))return!1;if(r>hr.maxFileBytes)throw new Error(`Tar entry exceeds 20 MB file limit: ${t}`);return!0}function G$(t,e){let r=t.replace(/\\/g,"/").replace(/^\.\//,""),[o,...n]=r.split("/"),i=e??o??null;return!i||o!==i?{rootPrefix:i,path:r}:{rootPrefix:i,path:n.join("/")}}function W$(t){let e=h_.normalize(t.replace(/\\/g,"/"));if(e==="."||e.includes("\0")||e.startsWith("../")||e.includes("/../")||h_.isAbsolute(e)||Buffer.byteLength(e,"utf8")>hr.maxPathBytes)throw new Error(`Unsafe tar entry path: ${t}`);if(e.split("/").some(r=>r===""||r==="."||r===".."||Buffer.byteLength(r,"utf8")>hr.maxPathComponentBytes))throw new Error(`Unsafe tar entry path: ${t}`);return e}function Ui(t,e,r){let o=t.subarray(e,e+r),n=o.indexOf(0);return o.subarray(0,n===-1?o.length:n).toString("utf8").trim()}function v_(t,e,r){let o=Ui(t,e,r).replace(/\0/g,"").trim();return o?Number.parseInt(o,8):0}function q$(t){return t.every(e=>e===0)}function J$(t,e){return e===t||e.startsWith(`${t}${F$}`)}var iT="https://github.com",aT=3e4,y_=20*1024*1024,sT=100*1024*1024,zi={renameSync:I_.renameSync},ji={node:{repo:"farther-shore/api-template-node",label:"Node (TypeScript + Express)"}},k_=["Mint a runtime token: farthershore backend tokens create <business> --kind live","Deploy the api/ Docker image anywhere that can serve HTTPS.","Register the origin: farthershore backend create <business> --name api --transport direct --origin-url ... --default"];function E_(t){t.command("create").description("Create local FartherShore project components").command("api").description("Scaffold a starter backend from a public template tarball").option("--node",`${ji.node.label} template (default)`).option("--path <dir>","Managed builder repo root (default: current directory)").option("--force","Overwrite an existing api/ directory if present").option("--ref <branch-or-tag>","Template tag or branch to download instead of main (tags are tried first)").addHelpText("after",`
|
|
2028
|
+
`).action(async e=>{let r,o=e.path;if(e.template)r=E$(e.template);else if(u_.isTTY&&d_.isTTY){let p=S$({input:u_,output:d_});try{let m=await j$({ask:g=>p.question(g),log:g=>{console.log(g)}});if(!m){G("Cancelled.");return}r=m.kind,o=o??m.path}finally{p.close()}}else throw new b(`--template is required when stdin is not a TTY. Choose one of: ${ke.join(", ")}.`,void 0,{code:"INIT_TEMPLATE_REQUIRED"});let n=Pi(r),i=p_(o??fr),s=ur(e);if(kp(i)&&!e.force)throw new b(`${i} already exists. Pass --force to overwrite.`,void 0,{code:"INIT_FILE_EXISTS"});let c=C$(n,i,s),l=c.map(p=>p.path).filter(p=>kp(p));if(l.length>0&&!e.force)throw new b(`${l[0]} already exists. Pass --force to overwrite.`,void 0,{code:"INIT_FILE_EXISTS"});let d=R$(i);if(d)throw new b(`${d} already declares an @Business class. Folder discovery compiles every module under business/, so scaffolding ${i} beside it would leave two @Business classes. Remove or rename ${d} first.`,void 0,{code:"INIT_BUSINESS_EXISTS"});for(let p of c)v$(mr(p.path),{recursive:!0}),k$(p.path,p.content,"utf-8");let u=c.find(p=>p.path===i)?.content??m_(n,s);F({template:r,path:i,surfaces:ip(s),preset:{kind:n.kind,label:n.label},content:u,files:c},`Scaffolded ${i} from preset "${n.label}".`),G(`Next: edit ${o??fr}, then run \`farthershore build\`.`)})}import{existsSync as Ip,lstatSync as Y$,mkdirSync as X$,mkdtempSync as Q$,readFileSync as eT,rmSync as S_,writeFileSync as tT}from"node:fs";import*as I_ from"node:fs";import{randomUUID as nT}from"node:crypto";import{gunzipSync as rT}from"node:zlib";import{join as br,relative as oT,resolve as w_}from"node:path";import{mkdirSync as g_,writeFileSync as L$}from"node:fs";import{dirname as M$,posix as h_,resolve as b_,sep as F$}from"node:path";var hr={maxEntries:2e3,maxFileBytes:20*1024*1024,maxPathBytes:512,maxPathComponentBytes:255},gr=512,B$=new Set(["x","g"]),V$=new Set(["0","","5"]),H$=new Set(["1","2"]);function __(t,e,r=()=>!1){let o=Z$(t).filter(s=>!r(s.path)),n=b_(e),i=[];for(let s of o){let c=b_(n,s.path);if(!J$(n,c))throw new Error(`Tar entry escapes destination: ${s.path}`);if("directory"in s){g_(c,{recursive:!0});continue}g_(M$(c),{recursive:!0}),L$(c,s.content,s.mode?{mode:s.mode}:void 0),i.push(s.path)}return i}function Z$(t){let e=[],r=0,o=null;for(;r+gr<=t.length;){let n=t.subarray(r,r+gr);if(q$(n))break;let i=Ui(n,0,100),s=Ui(n,345,155),c=s?`${s}/${i}`:i,l=v_(n,124,12),d=v_(n,100,8),u=Ui(n,156,1)||"0",p=r+gr,m=p+l;if(m>t.length)throw new Error(`Tar entry "${c}" is truncated.`);if(r=p+Math.ceil(l/gr)*gr,!K$(c,u,l))continue;let g=G$(c,o);if(!g.path||g.path==="/"||/^\/*$/.test(g.path)){o=g.rootPrefix;continue}o=g.rootPrefix;let x=W$(g.path);if(u==="5"?e.push({path:x,directory:!0}):e.push({path:x,content:Buffer.from(t.subarray(p,m)),mode:Number.isFinite(d)&&d>0?d:void 0}),e.length>hr.maxEntries)throw new Error(`Tar archive exceeds ${hr.maxEntries} entries.`)}return e}function K$(t,e,r){if(B$.has(e))return!1;if(H$.has(e))throw new Error(`Refusing link tar entry: ${t}`);if(!V$.has(e))return!1;if(r>hr.maxFileBytes)throw new Error(`Tar entry exceeds 20 MB file limit: ${t}`);return!0}function G$(t,e){let r=t.replace(/\\/g,"/").replace(/^\.\//,""),[o,...n]=r.split("/"),i=e??o??null;return!i||o!==i?{rootPrefix:i,path:r}:{rootPrefix:i,path:n.join("/")}}function W$(t){let e=h_.normalize(t.replace(/\\/g,"/")).replace(/\/+$/,"");if(e==="."||e.includes("\0")||e.startsWith("../")||e.includes("/../")||h_.isAbsolute(e)||Buffer.byteLength(e,"utf8")>hr.maxPathBytes)throw new Error(`Unsafe tar entry path: ${t}`);if(e.split("/").some(r=>r===""||r==="."||r===".."||Buffer.byteLength(r,"utf8")>hr.maxPathComponentBytes))throw new Error(`Unsafe tar entry path: ${t}`);return e}function Ui(t,e,r){let o=t.subarray(e,e+r),n=o.indexOf(0);return o.subarray(0,n===-1?o.length:n).toString("utf8").trim()}function v_(t,e,r){let o=Ui(t,e,r).replace(/\0/g,"").trim();return o?Number.parseInt(o,8):0}function q$(t){return t.every(e=>e===0)}function J$(t,e){return e===t||e.startsWith(`${t}${F$}`)}var iT="https://github.com",aT=3e4,y_=20*1024*1024,sT=100*1024*1024,zi={renameSync:I_.renameSync},ji={node:{repo:"farther-shore/api-template-node",label:"Node (TypeScript + Express)"}},k_=["Mint a runtime token: farthershore backend tokens create <business> --kind live","Deploy the api/ Docker image anywhere that can serve HTTPS.","Register the origin: farthershore backend create <business> --name api --transport direct --origin-url ... --default"];function E_(t){t.command("create").description("Create local FartherShore project components").command("api").description("Scaffold a starter backend from a public template tarball").option("--node",`${ji.node.label} template (default)`).option("--path <dir>","Managed builder repo root (default: current directory)").option("--force","Overwrite an existing api/ directory if present").option("--ref <branch-or-tag>","Template tag or branch to download instead of main (tags are tried first)").addHelpText("after",`
|
|
2029
2029
|
Languages:
|
|
2030
2030
|
--node ${ji.node.label} (default)
|
|
2031
2031
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@farthershore/cli",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.4",
|
|
4
4
|
"description": "FartherShore CLI — bootstrap and operate software businesses",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
"typescript-eslint": "^8.59.0",
|
|
43
43
|
"vitest": "^4.1.6",
|
|
44
44
|
"zod": "^4.3.6",
|
|
45
|
+
"@farthershore/business": "0.11.0",
|
|
45
46
|
"@farthershore/contracts": "0.62.0",
|
|
46
|
-
"@farthershore/farthershore-js": "0.18.2"
|
|
47
|
-
"@farthershore/business": "0.11.0"
|
|
47
|
+
"@farthershore/farthershore-js": "0.18.2"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"dev": "tsx src/index.ts",
|