dockito 0.0.1-beta.13 → 0.0.1-beta.14
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/dockito.js +16 -12
- package/package.json +1 -1
package/dockito.js
CHANGED
|
@@ -146,12 +146,15 @@ gives a chart's points instead.
|
|
|
146
146
|
dockito read <doc> --chart 2`},apply:{use:"apply <doc> <changes.json>",about:"Change a sheet at the version you read",page:`Changes a sheet, read at --base: the version (v N) your last get, read or
|
|
147
147
|
changes showed. Addresses, rows and headers mean what they meant then,
|
|
148
148
|
wherever they moved since; so do chart and format numbers (#N, by order in
|
|
149
|
-
the outline
|
|
149
|
+
the outline; a chart an earlier change here makes takes the next number) and
|
|
150
|
+
sheet names (after a rename here, either works). Every change applies, or
|
|
151
|
+
none: a cell someone
|
|
150
152
|
changed since is refused, naming who (exit 1). Read again and apply on the
|
|
151
153
|
new version. Prints each cell old \u2192 new and the new version.
|
|
152
154
|
|
|
153
155
|
The file (or - for stdin) is a list of changes, or {"base": N, "ops": [...],
|
|
154
|
-
"expect": {...}}
|
|
156
|
+
"expect": {...}} (cells that must hold these values before the ops, as at
|
|
157
|
+
base). "sheet" can be left out when there's one. Each change:
|
|
155
158
|
{"set": "Tasks!E17", "value": "Done"}
|
|
156
159
|
{"set": "Tasks!B2:C3", "values": [["Tile grout", "Kitchen"], ["Vent", "Bath"]]}
|
|
157
160
|
{"update": {"sheet": "Tasks", "where": "ID = T-104", "set": {"Status": "Done"}}}
|
|
@@ -159,8 +162,8 @@ The file (or - for stdin) is a list of changes, or {"base": N, "ops": [...],
|
|
|
159
162
|
"set": {"Status": "Done"}, "max": 50}} max is 1 unless set; more
|
|
160
163
|
matches than max are refused
|
|
161
164
|
{"append": {"sheet": "Tasks", "rows": [{"ID": "T-214", "Status": "Open"}]}}
|
|
162
|
-
a column's formula
|
|
163
|
-
into new rows, as in Excel
|
|
165
|
+
a column's formula and the formats of the row
|
|
166
|
+
above carry into new rows, as in Excel
|
|
164
167
|
{"insertRows": {"sheet": "Tasks", "after": 40, "count": 2}}, deleteRows
|
|
165
168
|
{"rows": "41:42"} or a list, "9, 16, 41:42"; moveRows {"rows": "5:6",
|
|
166
169
|
"after": 10}; insertCols, deleteCols, moveCols the same with letters
|
|
@@ -211,8 +214,8 @@ The file (or - for stdin) is a list of changes, or {"base": N, "ops": [...],
|
|
|
211
214
|
what was left and why; over 100,000 cells changes nothing
|
|
212
215
|
{"chart": {"range": "Tasks!A1:C40", "type": "column", "title": "Costs"}}:
|
|
213
216
|
the outline lists charts as chart #N. "header" (first row names the
|
|
214
|
-
series) and "labels" (first column labels the points
|
|
215
|
-
left out. Type: column, bar, line, area, pie, donut, scatter (first
|
|
217
|
+
series) and "labels" (first column labels the points; a scatter's x)
|
|
218
|
+
are guessed when left out. Type: column, bar, line, area, pie, donut, scatter (first
|
|
216
219
|
column: x), or "stacked column", "stacked bar", "stacked area",
|
|
217
220
|
"doughnut", "horizontal bar"; "stacked": true for column, bar, area.
|
|
218
221
|
"at": "E2", "below", "beside", "below chart #2" or "beside chart #2";
|
|
@@ -224,8 +227,8 @@ The file (or - for stdin) is a list of changes, or {"base": N, "ops": [...],
|
|
|
224
227
|
label column, "Kitchen and Bath by Month"), "x title", "y title";
|
|
225
228
|
"legend": right, bottom, top, none; "colors": ["#4285f4", null] per
|
|
226
229
|
series. The answer says what it draws and warns about a total row or
|
|
227
|
-
column, or a column with no numbers. {"chart": 2, ...}
|
|
228
|
-
{"chart": 2, "remove": true} removes it
|
|
230
|
+
column, or a column with no numbers. {"chart": {"chart": 2, ...}}
|
|
231
|
+
changes chart 2; {"chart": {"chart": 2, "remove": true}} removes it
|
|
229
232
|
Values: a number, true, false, null (empty), a string ("=\u2026" is a formula),
|
|
230
233
|
{"text": "=as typed"} or {"date": "2026-10-19"}.
|
|
231
234
|
|
|
@@ -238,8 +241,9 @@ Values: a number, true, false, null (empty), a string ("=\u2026" is a formula),
|
|
|
238
241
|
|
|
239
242
|
dockito apply <doc> changes.json --base 412 -m "close finished tasks"
|
|
240
243
|
echo '[{"set": "E17", "value": "Done"}]' | dockito apply <doc> - --base 412`},check:{use:"check <doc>",about:"Problems in a sheet",page:`Finds problems in a sheet, by rules: formula errors, a formula that breaks
|
|
241
|
-
its column's pattern, a value typed over a column's formulas
|
|
242
|
-
dates typed as text, totals that stop before
|
|
244
|
+
its column's pattern, a value typed over a column's formulas or a cell left
|
|
245
|
+
empty among them, numbers or dates typed as text, totals that stop before
|
|
246
|
+
their column does. Exits 1 when it finds any.
|
|
243
247
|
|
|
244
248
|
--sheet <name> One sheet (default: every sheet)`},changes:{use:"changes <doc> --since <v>",about:"What changed in a sheet",page:`Lists what changed after a version, or since a time in UTC, oldest first:
|
|
245
249
|
who, when, through what, with each cell old \u2192 new, named where it is now.
|
|
@@ -250,9 +254,9 @@ Ends at the current version, to apply changes at.
|
|
|
250
254
|
mcp), saved points with their notes, and the git commit.`},restore:{use:"restore <doc> <entry>",about:"Make a History entry current again",page:"Makes an older entry the current one, as a new entry. Nothing is lost."},save:{use:"save <doc> [entry] -m <note>",about:"Keep an entry as a saved point",page:`Keeps an entry (default: the current one) as a saved point, so History
|
|
251
255
|
never drops it, with an optional note. A doc keeps up to 10.`},login:{use:"login [--update]",about:"Sign in through the browser",page:`Opens the browser, where you check a code and choose this login's access
|
|
252
256
|
in each workspace: View, Publish or Everything. --update changes that access.
|
|
253
|
-
--no-browser prints the link instead.`},logout:{use:"logout",about:"Sign out this machine",page:"Signs this machine out and removes its token."},whoami:{use:"whoami",about:"Who you are and what this login can reach",page:"Your name, the login's expiry, and its access in each workspace."},agent:{use:"agent",about:"What an AI agent needs to know",page:"Prints what Dockito is and how an AI agent should use this CLI."}};var qe="0.0.1-beta.
|
|
257
|
+
--no-browser prints the link instead.`},logout:{use:"logout",about:"Sign out this machine",page:"Signs this machine out and removes its token."},whoami:{use:"whoami",about:"Who you are and what this login can reach",page:"Your name, the login's expiry, and its access in each workspace."},agent:{use:"agent",about:"What an AI agent needs to know",page:"Prints what Dockito is and how an AI agent should use this CLI."}};var qe="0.0.1-beta.14",C=dt(),de=ut(C),Je=`dockito-cli/${qe} (${process.platform})`;function T(){let e=ye(de);return e||p("Not logged in. Run `dockito login`."),fe({url:C,token:e,source:"cli",userAgent:Je})}function St(e){let[t,n]=process.platform==="darwin"?["open",[e]]:process.platform==="win32"?["cmd",["/c","start","",e]]:["xdg-open",[e]];try{let o=an(t,n,{stdio:"ignore",detached:!0});return o.on("error",()=>{}),o.unref(),!0}catch{return!1}}var gn=()=>!process.env.SSH_CONNECTION&&!process.env.CI&&(process.platform!=="linux"||!!process.env.DISPLAY||!!process.env.WAYLAND_DISPLAY),fn=e=>new Promise(t=>setTimeout(t,e)),mn=()=>dn().replace(/\.local$/,"").slice(0,60)||"Unknown device";function M(e){return it(e)??p(`"${e}" isn't a doc link or code. \`dockito ls\` lists docs with their codes.`)}function vt(e){let t=un(Ot(e)),n=bt("git",["rev-parse","HEAD"],{cwd:t,encoding:"utf8"});if(n.error||n.status!==0)return null;let o=bt("git",["status","--porcelain","--",Be(e)],{cwd:t,encoding:"utf8"});return o.status!==0||o.stdout.trim()?null:n.stdout.trim()}var At=e=>cn("sha256").update(e).digest("hex");async function wn(e){let t=ye(de);e.update&&!t&&p("Not logged in. Run `dockito login` first."),process.env.DOCKITO_TOKEN&&$(R("DOCKITO_TOKEN is set, so commands will keep using it instead of this login."));let n=fe({url:C,token:e.update?t:null,userAgent:Je}),o=await n.startLogin("Dockito CLI",mn()),s=!e["no-browser"]&&gn()&&St(o.verification_uri_complete);h(s?`Opening ${o.verification_uri_complete}`:`Open ${S(o.verification_uri)}`),h(`Code: ${S(o.user_code)}`),$(g("Waiting for approval\u2026"));let i=o.interval*1e3,a=Date.now()+o.expires_in*1e3;for(;Date.now()<a;){await fn(i);try{let c=await n.pollLogin(o.device_code);if(!c)continue;let d=ht(de,c.token);h(`${b("\u2713")} Logged in as ${c.user.name}${c.user.username?g(` (${c.user.username})`):""}`);for(let l of c.workspaces)h(` ${l.name} ${g(`${l.slug} \xB7 ${G[l.level]}`)}`);d==="file"&&$(R("No keychain found, so the token is in a file only you can read, in ~/.config/dockito."));return}catch(c){if(c instanceof x&&c.code==="access_denied"&&p("Denied in the browser."),c instanceof x&&c.code==="expired_token"&&p("The code expired. Run `dockito login` again."),c instanceof x&&c.code==="offline"){i=Math.min(i*2,3e4);continue}throw c}}p("The code expired. Run `dockito login` again.")}async function yn(){let e=ye(de);if(!e)return h("Not logged in.");process.env.DOCKITO_TOKEN&&p("DOCKITO_TOKEN is set; unset it or revoke that token in Account \u2192 Tokens.");try{await fe({url:C,token:e,userAgent:Je}).logout()}catch(t){if(!(t instanceof x)||t.code!=="invalid_token"&&t.code!=="not_found")throw t}gt(de),h(`${b("\u2713")} Logged out`)}async function kn(e){let t=await T().whoami();if(e.json)return h(JSON.stringify(t,null,2));h(`${t.user.name} ${g(`${t.user.username} \xB7 ${t.user.email}`)}`),t.token&&h(g(`${t.token.name} \xB7 ${t.token.source==="cli"?"ends after 90 days without use":`expires ${new Date(t.token.expiresAt).toLocaleDateString()}`}`)),h(),se(t.workspaces.map(n=>[n.slug,n.name,g(n.level?G[n.level]:n.role)])),C!=="https://dockito-app.dockito.workers.dev"&&$(g(`
|
|
254
258
|
${C}`))}async function bn(e,t){e.length||p("Name a file: `dockito publish notes.md --to <project/folder>`"),t.doc&&e.length>1&&p("--doc takes one file."),t.title!==void 0&&e.length>1&&p("--title takes one file."),t.title!==void 0&&!t.title.trim()&&p("--title needs a title."),t.public&&t.doc&&p("--public is only for a new doc; an existing one can be made public from Share in the app.");for(let l of e)(!Tt(l)||!ln(l).isFile())&&p(`${l} isn't a file${pn(l)?"":` (looked for ${Ot(l)})`}.`);let n=e.filter(He);n.length&&t.doc&&p("A .csv makes a new sheet; it can't replace a doc. Leave out --doc, or change a sheet with `dockito apply`."),n.length&&t.message&&p("Sheets don't keep saved points yet: publish the .csv without -m.");let o=T(),s=[];if(t.doc){let l=await o.doc(M(t.doc)),m=new Uint8Array(xe(e[0])),f=await o.update(l.doc.id,Be(e[0]),m,{note:t.message,commit:vt(e[0])});return t.json?h(JSON.stringify([{file:e[0],...f,link:o.linkOf(f.slug)}],null,2)):h(f.unchanged?`${g("=")} ${e[0]} ${g("unchanged")} ${o.linkOf(f.slug)}`:`${b("\u2713")} ${e[0]} \u2192 ${o.linkOf(f.slug)}`)}let i=await o.tree(),a=ke(i,t.workspace);I(a)||p(`This login has View access in ${a.slug}. Run \`dockito login --update\`.`);let c=Fe(a,t.to),d=await o.files(a.id,c.project);for(let l of e){let m=new Uint8Array(xe(l)),f=Be(l),w=t.new?[]:oe(d,c.folder,f),O=w.filter(D=>D.kind==="sheet");O.length&&p(`${f} in ${c.label} is ${O.length>1?`${O.length} live sheets`:"a live sheet"} (${O.map(D=>o.linkOf(D.slug)).join(", ")}): change ${O.length>1?"one":"it"} with \`dockito apply\`. --new makes a new sheet from the file instead.`),w.length>1&&p(`${w.length} docs in ${c.label} are named ${f}: ${w.map(D=>o.linkOf(D.slug)).join(", ")}. Pick one with --doc, or publish a new one with --new.`);let k=w[0];if(k&&t.public&&!(await o.doc(k.slug)).doc.public&&p(`${f} is already a private doc in ${c.label} (${o.linkOf(k.slug)}). Only Share in the app can make it public; \`--new --public\` publishes a new public doc.`),k&&k.sha256===At(m)&&!t.message){s.push({file:l,id:k.id,slug:k.slug,version:k.version,unchanged:!0,link:o.linkOf(k.slug)}),t.json||h(`${g("=")} ${l} ${g("unchanged")} ${o.linkOf(k.slug)}`);continue}let v=k?await o.update(k.id,f,m,{note:t.message,commit:vt(l)}):await o.create(a.id,f,m,{project:c.project,folder:c.folder,public:t.public,title:t.title});!k&&t.message&&await o.save(v.id,v.version,t.message);let U="public"in v&&v.public===!0;s.push({file:l,...v,...He(l)?{type:"sheet"}:{},link:o.linkOf(v.slug),new:!k}),t.json||h(`${b("\u2713")} ${l} \u2192 ${o.linkOf(v.slug)} ${g(k?v.unchanged?"unchanged":"updated":`new ${He(l)?"sheet ":""}in ${c.label}`)}${U?` ${b("\xB7 public")}`:""}${t.message?g(` \xB7 saved: ${t.message}`):""}`)}t.json?h(JSON.stringify(s,null,2)):!t.to&&s.some(l=>l.new)&&$(g("In the workspace's Docs. To put docs in a project: --to <project/folder>; `dockito tree` lists them."))}async function $n(e){let t=await T().tree();if(e.json)return h(JSON.stringify(t,null,2));let n=o=>g(`${o} doc${o===1?"":"s"}`);for(let o of t.workspaces){h(`${S(o.slug)} ${o.name} ${g(`\xB7 ${o.level?G[o.level]:o.role}`)}`);let s=[[g("Docs"),"",n(o.docs)]];for(let i of o.projects){s.push([i.slug,i.name,n(i.docs)]);let a=(c,d)=>{for(let l of i.folders.filter(m=>m.parentId===c))s.push([`${d}/${l.name}`,"",n(l.docs)]),a(l.id,`${d}/${l.name}`)};a(null,i.slug)}se(s.map(i=>[" ",...i])),h()}$(g("Publish into a place: dockito publish <file> -w <workspace> --to <project/folder>"))}async function vn(e,t){e&&t.to&&e!==t.to&&p(`Two places: ${e} and --to ${t.to}. Give one.`);let n=e??t.to,o=T(),s=await o.tree(),i=ke(s,t.workspace),a=Fe(i,n),c=await o.docs(i.id,{project:a.project,folder:a.folder}),d=a.project?i.projects.find(w=>w.id===a.project):null,l=n?[]:i.projects,m=d?d.folders.filter(w=>w.parentId===a.folder):[];if(t.json)return h(JSON.stringify({workspace:i.slug,place:n??null,projects:l,folders:m,docs:c},null,2));let f=[];for(let w of l)f.push([S(`${w.slug}/`),w.name,g(`${w.docs} doc${w.docs===1?"":"s"}`),""]);for(let w of m)f.push([S(`${w.name}/`),"",g(`${w.docs} doc${w.docs===1?"":"s"}`),""]);for(let w of c)f.push([w.slug,w.title+g(w.kind==="html"?" .html":w.kind==="sheet"?" sheet":" .md"),g(me(w.updatedAt)),g(w.updatedByName??"")]);if(!f.length)return $(g(`Nothing in ${a.label} yet.`));se(f)}async function jn(e,t){let[n,...o]=(e??"").split("/").filter(Boolean);n||p("`dockito mkdir <project>[/folder[/subfolder]]`"),o.length>2&&p("Folders go at most 2 deep inside a project.");let s=T(),i=ke(await s.tree(),t.workspace),a=H(i,n),c=a?.id??(await s.createProject(i.id,n)).id,d=!a;a||h(`${b("\u2713")} Project ${n}`);let l=q(a),m=null;for(let f=0;f<o.length;f++){let w=l.idOf(o.slice(0,f+1));if(w){m=w;continue}m=(await s.createFolder(c,o[f],m)).id,l.add(o.slice(0,f+1),m),d=!0,h(`${b("\u2713")} Folder ${o.slice(0,f+1).join("/")}`)}d||$(g("Already there."))}async function xn(e){e||p("Name a doc: `dockito open <link or code>`");let t=`${C}/${M(e)}`;St(t)||h(t)}async function Tn(e,t){e||p("Name a doc: `dockito get <link or code> [-o file]`"),t.outline&&(t.lines!==void 0||t.text)&&p("--outline is the headings only; leave out --lines and --text.");let n=T(),o=await n.doc(M(e));if(o.doc.kind==="sheet"){let d=["entry","outline","lines","text"].filter(m=>t[m]!==void 0);d.length&&p(`A sheet has no file to read by ${d.map(m=>`--${m}`).join(" or ")}: \`dockito read\` gives its rows, a range or totals.`);let l=await n.readSheet(o.doc.id,{outline:!0});return t.output?($t(t.output,`${l.text.trimEnd()}
|
|
255
|
-
`),$(`${b("\u2713")} ${t.output} ${g(`\u2190 ${n.linkOf(o.doc.slug)} outline`)}`)):ee(l)}let s=t.entry?Number(t.entry):null;t.entry&&(!Number.isInteger(s)||s<1)&&p("--entry takes an entry number from `dockito history`.");let i=await n.content(o.doc.id,s,{outline:t.outline,lines:t.lines,text:t.text}),a=i.bytes.length&&i.lines!==null&&!t.output&&i.bytes[i.bytes.length-1]!==10?new Uint8Array([...i.bytes,10]):i.bytes;if(!t.output)return void process.stdout.write(a);$t(t.output,a);let c=t.outline?" outline":i.shown?` lines ${i.shown} of ${i.lines}`:t.text?" as text":"";$(`${b("\u2713")} ${t.output} ${g(`\u2190 ${n.linkOf(o.doc.slug)}${s?` entry ${s}`:""}${c}`)}`)}async function On(e,t){e||p("Name a doc: `dockito history <link or code>`");let n=await T().doc(M(e));if(n.doc.kind==="sheet"&&p(Ge),t.json)return h(JSON.stringify(n.versions,null,2));h(`${S(n.doc.title)} ${g(`${C}/${n.doc.slug}`)}`),se(n.versions.map((o,s)=>[String(o.number),s===0?b("current"):g(me(o.createdAt)),s===0?g(me(o.createdAt)):"",o.byName??"",g(o.source),o.savedAt?`${R("saved")}${o.note?` ${o.note}`:""}`:"",o.gitCommit?g(o.gitCommit.slice(0,7)):""]))}async function Sn(e,t){let n=Number(t);(!e||!Number.isInteger(n)||n<1)&&p("`dockito restore <doc> <entry>`; entries are in `dockito history`.");let o=T(),s=await o.doc(M(e));s.doc.kind==="sheet"&&p(`${Ge} \`dockito apply <doc> --undo <version>\` takes back a change of yours.`);let i=await o.restore(s.doc.id,n,s.versions[0]?.number??null);h(`${b("\u2713")} Restored entry ${n} as entry ${i.version} ${g(o.linkOf(i.slug))}`)}async function An(e,t,n){e||p('`dockito save <doc> [entry] -m "note"`');let o=T(),s=await o.doc(M(e));s.doc.kind==="sheet"&&p(Ge);let i=t?Number(t):s.versions[0]?.number;(!Number.isInteger(i)||i<1)&&p("Entries are in `dockito history`."),await o.save(s.doc.id,i,n.message??null),h(`${b("\u2713")} Saved entry ${i}${n.message?g(` \xB7 ${n.message}`):""}`)}async function Dn(e,t){e||p("`dockito share <link or code> [--private]`"),t.public&&p("An existing doc can be made public only from Share in the app. `dockito publish <file> --public` makes a new doc public.");let n=T(),o=await n.doc(M(e)),s=n.linkOf(o.doc.slug);if(t.private)return o.doc.public&&await n.makePrivate(o.doc.id),t.json?h(JSON.stringify({public:!1,link:s},null,2)):h(`${b("\u2713")} Private: only people in ${o.workspace.name} can open it ${g(s)}`);if(t.json)return h(JSON.stringify({public:o.doc.public,link:s},null,2));h(o.doc.public?`${b("Public")}: anyone with the link can open it ${s}`:`Private: only people in ${o.workspace.name} can open it ${g(s)}`)}var He=e=>/\.csv$/i.test(e),Ge="Sheets don't keep History entries yet; `dockito changes <doc> --since <version>` lists what changed.";async function Te(e,t,n){t||p(`Name a sheet: \`dockito ${n}\``);let o=await e.doc(M(t));return o.doc.kind!=="sheet"&&p(`${o.doc.title} is a ${o.doc.kind==="md"?"Markdown":"HTML"} doc, not a sheet: \`dockito get\` reads it.`),o}function ee(e,t){t?h(JSON.stringify(e,null,2)):h(e.text.trimEnd()),e.ok||(process.exitCode=1)}var Z=(e,t,n)=>{if(e===void 0)return;let o=Number(e);return(!/^\d+$/.test(e.trim())||o<n)&&p(`--${t} takes a whole number, ${n} or more.`),o},Ue=e=>e===void 0?void 0:e.split(",").map(t=>t.trim()).filter(Boolean);async function Nn(e,t,n){let o=T(),s=await Te(o,e,"read <doc> [range]"),i=Z(n.chart,"chart",1);if(i!==void 0){let c=Object.entries(n).filter(([d,l])=>d!=="chart"&&d!=="json"&&l!==void 0);return(t||c.length)&&p(`--chart goes alone: it gives the chart's points as drawn, not ${[...t?["a range"]:[],...c.map(([d])=>`--${d}`)].join(", ")}.`),ee(await o.readSheet(s.doc.id,{read:{chart:i}}),n.json)}let a=await o.readSheet(s.doc.id,{read:{range:t,sheet:n.sheet,where:n.where,select:Ue(n.select),orderBy:n["order-by"],group:Ue(n.group),totals:Ue(n.totals),from:Z(n.from,"from",1),limit:Z(n.limit,"limit",1),formulas:n.formulas,styles:n.styles,format:n.csv?"csv":void 0}});ee(a,n.json)}async function Pn(e,t,n){let o=T(),s=await Te(o,e,"apply <doc> <changes.json>"),i=Z(n.undo,"undo",1),a;if(i!==void 0)(t||n.base!==void 0)&&p("--undo goes alone: no changes file and no --base with it."),a={undo:i,note:n.message,dryRun:n["dry-run"]||void 0};else{!t&&process.stdin.isTTY&&p("Give the changes: `dockito apply <doc> changes.json`, or pipe them in with `-`. `dockito apply --help` shows their form.");let d=!t||t==="-"?xe(0,"utf8"):Tt(t)?xe(t,"utf8"):p(`${t} isn't a file.`),l;try{l=JSON.parse(d)}catch{p(`${t&&t!=="-"?t:"The input"} isn't JSON: a list of changes, or {"base": N, "ops": [...]}.`)}let m=Array.isArray(l)?{ops:l}:l;(typeof m!="object"||m===null)&&p('The changes are a list, or {"base": N, "ops": [...]}.');let f=Z(n.base,"base",0)??m.base;f===void 0&&p("--base is the version you read: v N in `dockito get` or `dockito read`."),a={...m,base:f,note:n.message??m.note,dryRun:n["dry-run"]||m.dryRun||void 0}}let c=n.key??Cn(a);ee(await o.changeSheet(s.doc.id,{key:c,...a}),n.json)}var Cn=e=>At(new TextEncoder().encode(JSON.stringify(e))).slice(0,32);async function En(e,t){let n=T(),o=await Te(n,e,"check <doc>")
|
|
259
|
+
`),$(`${b("\u2713")} ${t.output} ${g(`\u2190 ${n.linkOf(o.doc.slug)} outline`)}`)):ee(l)}let s=t.entry?Number(t.entry):null;t.entry&&(!Number.isInteger(s)||s<1)&&p("--entry takes an entry number from `dockito history`.");let i=await n.content(o.doc.id,s,{outline:t.outline,lines:t.lines,text:t.text}),a=i.bytes.length&&i.lines!==null&&!t.output&&i.bytes[i.bytes.length-1]!==10?new Uint8Array([...i.bytes,10]):i.bytes;if(!t.output)return void process.stdout.write(a);$t(t.output,a);let c=t.outline?" outline":i.shown?` lines ${i.shown} of ${i.lines}`:t.text?" as text":"";$(`${b("\u2713")} ${t.output} ${g(`\u2190 ${n.linkOf(o.doc.slug)}${s?` entry ${s}`:""}${c}`)}`)}async function On(e,t){e||p("Name a doc: `dockito history <link or code>`");let n=await T().doc(M(e));if(n.doc.kind==="sheet"&&p(Ge),t.json)return h(JSON.stringify(n.versions,null,2));h(`${S(n.doc.title)} ${g(`${C}/${n.doc.slug}`)}`),se(n.versions.map((o,s)=>[String(o.number),s===0?b("current"):g(me(o.createdAt)),s===0?g(me(o.createdAt)):"",o.byName??"",g(o.source),o.savedAt?`${R("saved")}${o.note?` ${o.note}`:""}`:"",o.gitCommit?g(o.gitCommit.slice(0,7)):""]))}async function Sn(e,t){let n=Number(t);(!e||!Number.isInteger(n)||n<1)&&p("`dockito restore <doc> <entry>`; entries are in `dockito history`.");let o=T(),s=await o.doc(M(e));s.doc.kind==="sheet"&&p(`${Ge} \`dockito apply <doc> --undo <version>\` takes back a change of yours.`);let i=await o.restore(s.doc.id,n,s.versions[0]?.number??null);h(`${b("\u2713")} Restored entry ${n} as entry ${i.version} ${g(o.linkOf(i.slug))}`)}async function An(e,t,n){e||p('`dockito save <doc> [entry] -m "note"`');let o=T(),s=await o.doc(M(e));s.doc.kind==="sheet"&&p(Ge);let i=t?Number(t):s.versions[0]?.number;(!Number.isInteger(i)||i<1)&&p("Entries are in `dockito history`."),await o.save(s.doc.id,i,n.message??null),h(`${b("\u2713")} Saved entry ${i}${n.message?g(` \xB7 ${n.message}`):""}`)}async function Dn(e,t){e||p("`dockito share <link or code> [--private]`"),t.public&&p("An existing doc can be made public only from Share in the app. `dockito publish <file> --public` makes a new doc public.");let n=T(),o=await n.doc(M(e)),s=n.linkOf(o.doc.slug);if(t.private)return o.doc.public&&await n.makePrivate(o.doc.id),t.json?h(JSON.stringify({public:!1,link:s},null,2)):h(`${b("\u2713")} Private: only people in ${o.workspace.name} can open it ${g(s)}`);if(t.json)return h(JSON.stringify({public:o.doc.public,link:s},null,2));h(o.doc.public?`${b("Public")}: anyone with the link can open it ${s}`:`Private: only people in ${o.workspace.name} can open it ${g(s)}`)}var He=e=>/\.csv$/i.test(e),Ge="Sheets don't keep History entries yet; `dockito changes <doc> --since <version>` lists what changed.";async function Te(e,t,n){t||p(`Name a sheet: \`dockito ${n}\``);let o=await e.doc(M(t));return o.doc.kind!=="sheet"&&p(`${o.doc.title} is a ${o.doc.kind==="md"?"Markdown":"HTML"} doc, not a sheet: \`dockito get\` reads it.`),o}function ee(e,t){t?h(JSON.stringify(e,null,2)):h(e.text.trimEnd()),e.ok||(process.exitCode=1)}var Z=(e,t,n)=>{if(e===void 0)return;let o=Number(e);return(!/^\d+$/.test(e.trim())||o<n)&&p(`--${t} takes a whole number, ${n} or more.`),o},Ue=e=>e===void 0?void 0:e.split(",").map(t=>t.trim()).filter(Boolean);async function Nn(e,t,n){let o=T(),s=await Te(o,e,"read <doc> [range]"),i=Z(n.chart,"chart",1);if(i!==void 0){let c=Object.entries(n).filter(([d,l])=>d!=="chart"&&d!=="json"&&l!==void 0);return(t||c.length)&&p(`--chart goes alone: it gives the chart's points as drawn, not ${[...t?["a range"]:[],...c.map(([d])=>`--${d}`)].join(", ")}.`),ee(await o.readSheet(s.doc.id,{read:{chart:i}}),n.json)}let a=await o.readSheet(s.doc.id,{read:{range:t,sheet:n.sheet,where:n.where,select:Ue(n.select),orderBy:n["order-by"],group:Ue(n.group),totals:Ue(n.totals),from:Z(n.from,"from",1),limit:Z(n.limit,"limit",1),formulas:n.formulas,styles:n.styles,format:n.csv?"csv":void 0}});ee(a,n.json)}async function Pn(e,t,n){let o=T(),s=await Te(o,e,"apply <doc> <changes.json>"),i=Z(n.undo,"undo",1),a;if(i!==void 0)(t||n.base!==void 0)&&p("--undo goes alone: no changes file and no --base with it."),a={undo:i,note:n.message,dryRun:n["dry-run"]||void 0};else{!t&&process.stdin.isTTY&&p("Give the changes: `dockito apply <doc> changes.json`, or pipe them in with `-`. `dockito apply --help` shows their form.");let d=!t||t==="-"?xe(0,"utf8"):Tt(t)?xe(t,"utf8"):p(`${t} isn't a file.`),l;try{l=JSON.parse(d)}catch{p(`${t&&t!=="-"?t:"The input"} isn't JSON: a list of changes, or {"base": N, "ops": [...]}.`)}let m=Array.isArray(l)?{ops:l}:l;(typeof m!="object"||m===null)&&p('The changes are a list, or {"base": N, "ops": [...]}.');let f=Z(n.base,"base",0)??m.base;f===void 0&&p("--base is the version you read: v N in `dockito get` or `dockito read`."),a={...m,base:f,note:n.message??m.note,dryRun:n["dry-run"]||m.dryRun||void 0}}let c=n.key??Cn(a);ee(await o.changeSheet(s.doc.id,{key:c,...a}),n.json)}var Cn=e=>At(new TextEncoder().encode(JSON.stringify(e))).slice(0,32);async function En(e,t){let n=T(),o=await Te(n,e,"check <doc>"),s=await n.readSheet(o.doc.id,{check:t.sheet?{sheet:t.sheet}:{}});ee(s,t.json),s.ok&&!s.text.includes("no problems found")&&(process.exitCode=1)}async function In(e,t){let n=T(),o=await Te(n,e,"changes <doc> --since <version>");t.since===void 0&&p('--since is a version (412) or a time in UTC (2026-10-13, "2026-10-13 09:00").');let s=/^\s*\d+\s*$/.test(t.since)?Number(t.since):t.since;ee(await n.readSheet(o.doc.id,{changes:{since:s,max:Z(t.max,"max",1)}}),t.json)}var We=`Dockito CLI ${qe}
|
|
256
260
|
|
|
257
261
|
${Ke}
|
|
258
262
|
|
package/package.json
CHANGED