@hraness/lifecharts 1.0.0 → 1.0.1
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
CHANGED
|
@@ -6,19 +6,21 @@ Use Node.js 22.14 or newer, or Bun 1.3.14 or newer. The package has no runtime d
|
|
|
6
6
|
|
|
7
7
|
## Run the CLI
|
|
8
8
|
|
|
9
|
-
The immutable GitHub Release archive is the canonical distribution. Run version 1.0.
|
|
9
|
+
The immutable GitHub Release archive is the canonical distribution. Run version 1.0.1 directly:
|
|
10
10
|
|
|
11
11
|
```sh
|
|
12
|
-
npx --yes --package=https://github.com/hraness/lifecharts/releases/download/v1.0.
|
|
12
|
+
npx --yes --package=https://github.com/hraness/lifecharts/releases/download/v1.0.1/hraness-lifecharts-1.0.1.tgz lifecharts --help
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
When this version is available on npm, its archive is an exact-byte mirror:
|
|
16
16
|
|
|
17
17
|
```sh
|
|
18
|
-
npx --yes @hraness/lifecharts@1.0.
|
|
19
|
-
npm install --global @hraness/lifecharts@1.0.
|
|
18
|
+
npx --yes @hraness/lifecharts@1.0.1 --help
|
|
19
|
+
npm install --global @hraness/lifecharts@1.0.1
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
+
Run `lifecharts` without arguments for a brief introduction and command help. Piped output stays plain.
|
|
23
|
+
|
|
22
24
|
Write your chapters into `timeline.json`:
|
|
23
25
|
|
|
24
26
|
```json
|
|
@@ -46,7 +48,7 @@ lifecharts compile chart.json > updated.url
|
|
|
46
48
|
Without a global installation, use this pinned command prefix before the command and arguments:
|
|
47
49
|
|
|
48
50
|
```sh
|
|
49
|
-
npx --yes --package=https://github.com/hraness/lifecharts/releases/download/v1.0.
|
|
51
|
+
npx --yes --package=https://github.com/hraness/lifecharts/releases/download/v1.0.1/hraness-lifecharts-1.0.1.tgz lifecharts create timeline.json --json
|
|
50
52
|
```
|
|
51
53
|
|
|
52
54
|
`create --json` returns the complete document, share link, edit link, and embed link. Use `-` for stdin. Quote complete URLs in shell commands.
|
package/bin/lifecharts.mjs
CHANGED
|
@@ -25,6 +25,11 @@ Birthday is optional. Supply start or a dated chapter when birthDate is unknown.
|
|
|
25
25
|
For an edit: inspect the URL > chart.json; edit JSON; compile chart.json; verify URL.
|
|
26
26
|
`,BJ=new Set(["create","compile","edit","inspect","validate","verify","templates"]),N=(Q,J=1)=>({ok:!1,stderr:`${Q}
|
|
27
27
|
`,exitCode:J}),F=(Q)=>({ok:!0,stdout:`${typeof Q==="string"?Q:JSON.stringify(Q,null,2)}
|
|
28
|
-
`,exitCode:0});
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
`,exitCode:0});function YJ(Q){if(Q.isTTY!==!0||Q.term==="dumb"||(Q.columns??80)<48)return"";return` | # lifecharts
|
|
29
|
+
| # # Create and share a life chart.
|
|
30
|
+
| # # #
|
|
31
|
+
+-------
|
|
32
|
+
|
|
33
|
+
`}async function qJ(Q,J){let V=Q==="-"?await J.readStdin():Q.startsWith("https://")||Q.startsWith("#")?Q:await J.readFile(Q);if(new TextEncoder().encode(V).byteLength>65536)throw TypeError("Input must be under 64 KB.");return V}async function WJ(Q,J){try{if(!Array.isArray(Q)||Q.some((q)=>typeof q!=="string"))return N("Arguments must be text.",2);if(Q.length===0||Q.length===1&&["--help","help","-h"].includes(Q[0]??""))return F(c.trimEnd());if(Q.length===1&&Q[0]==="--version")return F("Lifecharts CLI 1.0.1 · timeline format 1");let V=Q[0]??"";if(!BJ.has(V))return N("Unknown command. Run --help for available commands.",2);let Z=[],$=!1,Y,K=!1;for(let q=1;q<Q.length;q++){let D=Q[q]??"";if(D==="--json"&&!$)$=!0;else if(D==="--help"&&!K)K=!0;else if(D==="--today"&&Y===void 0){if(Y=Q[++q],!Y||!/^\d{4}-\d{2}-\d{2}$/u.test(Y))return N("--today needs a YYYY-MM-DD date.",2)}else if(D.startsWith("-")&&D!=="-")return N("Unknown or repeated option. Run --help for available options.",2);else Z.push(D)}if(K)return Z.length===0&&!$&&Y===void 0?F(c.trimEnd()):N("Use <command> --help by itself.",2);if(V==="templates"){if(Z.length>1||Y!==void 0)return N("Use templates [list|life|career].",2);let q=Z[0]??"list";if(q==="list")return F($?[{name:"life",description:"Illustrative life with overlapping chapters"},{name:"career",description:"Illustrative career without an inferred birthday"}]:`life Illustrative life with overlapping chapters
|
|
34
|
+
career Illustrative career without an inferred birthday`);if(q==="life")return F(h);if(q==="career")return F({version:1,title:"An example career",start:"2016-06",startKind:"timeline",asOf:"2026-09-01",horizonAge:40,scale:"lived",theme:"system",view:"bars",chapters:[{id:"first-role",label:"First role",start:"2016-06",end:"2020-03",color:"#3478a1"},{id:"next-role",label:"A new direction",start:"2020-03",end:"present",color:"#bd684d"},{id:"side-project",label:"Side project",start:"2023-01",end:"present",color:"#52866b"}]});return N("Unknown template. Run templates list.",2)}if(Z.length!==1)return N("Supply one input file, URL, or '-' for stdin. Run --help for command details.",2);if(Y!==void 0&&!["inspect","verify"].includes(V))return N("--today is supported by inspect and verify only.",2);let j=await qJ(Z[0]??"",J),G;if(["create","compile","edit","validate"].includes(V)){let q;try{q=JSON.parse(j)}catch{return N("The input must be one complete JSON object.")}G=V==="compile"||V==="edit"?U(q):l(q)}else G=d(j);if(!G.ok)return N(G.message);let B=["create","compile","edit"].includes(V)?{...G.value,view:G.value.view??"timeline"}:G.value;if(V==="inspect"&&!$&&Y===void 0)return F(B);if(V==="validate")return F($?{valid:!0,document:B}:`Valid chart: ${B.title} (${B.chapters.length} chapters).`);if(V==="inspect"||V==="verify"){let q=u(B,Y??J.today());return F($?{verified:!0,...q}:V==="inspect"?q:`Verified chart: ${B.title}
|
|
35
|
+
${q.url}`)}let X=C(B);return F($?{verified:!0,document:B,...X}:X.url)}catch(V){return N(V instanceof TypeError?V.message:"The input could not be read. Check the file path, permissions, and JSON.")}}async function o(Q){let J=[],V=0;for await(let Y of Q){if(V+=Y.byteLength,V>65536)throw TypeError("Input must be under 64 KB.");J.push(Y)}let Z=new Uint8Array(V),$=0;for(let Y of J)Z.set(Y,$),$+=Y.byteLength;try{return new TextDecoder("utf-8",{fatal:!0}).decode(Z)}catch{throw TypeError("Input must be valid UTF-8 text.")}}function KJ(){try{return process.argv[1]!==void 0&&p(process.argv[1])===p($J(import.meta.url))}catch{return!1}}if(KJ()){let Q=process.argv.slice(2),J=await WJ(Q,{readFile:(V)=>o(ZJ(V,{highWaterMark:65537})),readStdin:()=>o(process.stdin),today:()=>new Date().toISOString().slice(0,10)});if(J.ok){if(Q.length===0||Q.length===1&&["--help","help","-h"].includes(Q[0]??""))process.stdout.write(YJ({isTTY:process.stdout.isTTY,columns:process.stdout.columns,term:process.env.TERM}));process.stdout.write(J.stdout)}else process.stderr.write(J.stderr);process.exitCode=J.exitCode}export{WJ as runLifechartsCli,YJ as lifechartsTerminalIntro,c as LIFECHARTS_HELP};
|
package/package.json
CHANGED
|
@@ -25,6 +25,11 @@ Birthday is optional. Supply start or a dated chapter when birthDate is unknown.
|
|
|
25
25
|
For an edit: inspect the URL > chart.json; edit JSON; compile chart.json; verify URL.
|
|
26
26
|
`,BJ=new Set(["create","compile","edit","inspect","validate","verify","templates"]),N=(Q,J=1)=>({ok:!1,stderr:`${Q}
|
|
27
27
|
`,exitCode:J}),F=(Q)=>({ok:!0,stdout:`${typeof Q==="string"?Q:JSON.stringify(Q,null,2)}
|
|
28
|
-
`,exitCode:0});
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
`,exitCode:0});function YJ(Q){if(Q.isTTY!==!0||Q.term==="dumb"||(Q.columns??80)<48)return"";return` | # lifecharts
|
|
29
|
+
| # # Create and share a life chart.
|
|
30
|
+
| # # #
|
|
31
|
+
+-------
|
|
32
|
+
|
|
33
|
+
`}async function qJ(Q,J){let V=Q==="-"?await J.readStdin():Q.startsWith("https://")||Q.startsWith("#")?Q:await J.readFile(Q);if(new TextEncoder().encode(V).byteLength>65536)throw TypeError("Input must be under 64 KB.");return V}async function WJ(Q,J){try{if(!Array.isArray(Q)||Q.some((q)=>typeof q!=="string"))return N("Arguments must be text.",2);if(Q.length===0||Q.length===1&&["--help","help","-h"].includes(Q[0]??""))return F(c.trimEnd());if(Q.length===1&&Q[0]==="--version")return F("Lifecharts CLI 1.0.1 · timeline format 1");let V=Q[0]??"";if(!BJ.has(V))return N("Unknown command. Run --help for available commands.",2);let Z=[],$=!1,Y,K=!1;for(let q=1;q<Q.length;q++){let D=Q[q]??"";if(D==="--json"&&!$)$=!0;else if(D==="--help"&&!K)K=!0;else if(D==="--today"&&Y===void 0){if(Y=Q[++q],!Y||!/^\d{4}-\d{2}-\d{2}$/u.test(Y))return N("--today needs a YYYY-MM-DD date.",2)}else if(D.startsWith("-")&&D!=="-")return N("Unknown or repeated option. Run --help for available options.",2);else Z.push(D)}if(K)return Z.length===0&&!$&&Y===void 0?F(c.trimEnd()):N("Use <command> --help by itself.",2);if(V==="templates"){if(Z.length>1||Y!==void 0)return N("Use templates [list|life|career].",2);let q=Z[0]??"list";if(q==="list")return F($?[{name:"life",description:"Illustrative life with overlapping chapters"},{name:"career",description:"Illustrative career without an inferred birthday"}]:`life Illustrative life with overlapping chapters
|
|
34
|
+
career Illustrative career without an inferred birthday`);if(q==="life")return F(h);if(q==="career")return F({version:1,title:"An example career",start:"2016-06",startKind:"timeline",asOf:"2026-09-01",horizonAge:40,scale:"lived",theme:"system",view:"bars",chapters:[{id:"first-role",label:"First role",start:"2016-06",end:"2020-03",color:"#3478a1"},{id:"next-role",label:"A new direction",start:"2020-03",end:"present",color:"#bd684d"},{id:"side-project",label:"Side project",start:"2023-01",end:"present",color:"#52866b"}]});return N("Unknown template. Run templates list.",2)}if(Z.length!==1)return N("Supply one input file, URL, or '-' for stdin. Run --help for command details.",2);if(Y!==void 0&&!["inspect","verify"].includes(V))return N("--today is supported by inspect and verify only.",2);let j=await qJ(Z[0]??"",J),G;if(["create","compile","edit","validate"].includes(V)){let q;try{q=JSON.parse(j)}catch{return N("The input must be one complete JSON object.")}G=V==="compile"||V==="edit"?U(q):l(q)}else G=d(j);if(!G.ok)return N(G.message);let B=["create","compile","edit"].includes(V)?{...G.value,view:G.value.view??"timeline"}:G.value;if(V==="inspect"&&!$&&Y===void 0)return F(B);if(V==="validate")return F($?{valid:!0,document:B}:`Valid chart: ${B.title} (${B.chapters.length} chapters).`);if(V==="inspect"||V==="verify"){let q=u(B,Y??J.today());return F($?{verified:!0,...q}:V==="inspect"?q:`Verified chart: ${B.title}
|
|
35
|
+
${q.url}`)}let X=C(B);return F($?{verified:!0,document:B,...X}:X.url)}catch(V){return N(V instanceof TypeError?V.message:"The input could not be read. Check the file path, permissions, and JSON.")}}async function o(Q){let J=[],V=0;for await(let Y of Q){if(V+=Y.byteLength,V>65536)throw TypeError("Input must be under 64 KB.");J.push(Y)}let Z=new Uint8Array(V),$=0;for(let Y of J)Z.set(Y,$),$+=Y.byteLength;try{return new TextDecoder("utf-8",{fatal:!0}).decode(Z)}catch{throw TypeError("Input must be valid UTF-8 text.")}}function KJ(){try{return process.argv[1]!==void 0&&p(process.argv[1])===p($J(import.meta.url))}catch{return!1}}if(KJ()){let Q=process.argv.slice(2),J=await WJ(Q,{readFile:(V)=>o(ZJ(V,{highWaterMark:65537})),readStdin:()=>o(process.stdin),today:()=>new Date().toISOString().slice(0,10)});if(J.ok){if(Q.length===0||Q.length===1&&["--help","help","-h"].includes(Q[0]??""))process.stdout.write(YJ({isTTY:process.stdout.isTTY,columns:process.stdout.columns,term:process.env.TERM}));process.stdout.write(J.stdout)}else process.stderr.write(J.stderr);process.exitCode=J.exitCode}export{WJ as runLifechartsCli,YJ as lifechartsTerminalIntro,c as LIFECHARTS_HELP};
|