amoosedweb-cli 0.20.0 → 0.21.0

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/LICENSE.txt ADDED
@@ -0,0 +1,18 @@
1
+ AmoosedWeb CLI Package License
2
+
3
+ Copyright (c) 2026 Juhapekka Piiroinen <jp@1337.fi>
4
+ https://amoosed.com
5
+
6
+ Permission is granted, free of charge, to download, install, and use the
7
+ unmodified amoosedweb-cli package to build AmoosedWeb websites and read
8
+ AmoosedWeb content in personal or commercial projects.
9
+
10
+ This permission applies only to the unmodified amoosedweb-cli package. It
11
+ does not grant rights to the AmoosedWeb source code, browser extension,
12
+ website, artwork, hosted content, or access keys. Modification,
13
+ sublicensing, or redistribution of this package requires written permission
14
+ from the copyright owner. All other rights are reserved.
15
+
16
+ THE PACKAGE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED. TO THE EXTENT PERMITTED BY LAW, THE COPYRIGHT OWNER IS NOT LIABLE FOR
18
+ ANY CLAIM OR DAMAGES ARISING FROM USE OF THE PACKAGE.
package/README.md CHANGED
@@ -1,3 +1,3 @@
1
1
  # AmoosedWeb CLI
2
2
 
3
- Install from the local release tarball with `npm install -g amoosedweb-cli-0.20.0.tgz`. Run `amw init my-site`, then `amw --help`. Registry publication is separate and requires package ownership.
3
+ Install with `npm install -g amoosedweb-cli`, or from the matching website tarball with `npm install -g amoosedweb-cli-0.21.0.tgz`. Run `amw init my-site`, then `amw --help`. See [the compiler guide](https://www.amoosed.com/compiler.html) and `LICENSE.txt` for package use terms.
package/amw.cjs CHANGED
@@ -377,7 +377,7 @@ streaming downloads are implemented.
377
377
  `,{flag:"wx",mode:384}),R=!0,await(0,b.writeFile)(d,pr(hr(h,P)),{flag:"wx",mode:384}),$=!0),f&&(await(0,b.mkdir)((0,x.dirname)(g),{recursive:!0}),await(0,b.writeFile)(g,_,{flag:"wx",mode:384}),await(0,b.writeFile)(E,(0,mt.randomBytes)(32).toString("hex")+`
378
378
  `,{flag:"wx",mode:384})),await(0,b.writeFile)(m,JSON.stringify(i,null,2)+`
379
379
  `,{flag:"wx"}),f&&(await(0,b.rename)(E,f),S=!0),await(0,b.rename)(m,n),v=!0}catch(j){throw S&&await(0,b.writeFile)(f,_),v&&await(0,b.writeFile)(n,o),$&&await(0,b.rm)(d),R&&await(0,b.rm)(p),j}finally{for(let j of[m,E])j&&await q(j)&&await(0,b.rm)(j)}return{scope:e,keyId:h,memberPath:p,memberFilePath:d,archivePath:g,siteKeyKind:s?f?"private index":"public encoding":null}}var re=require("node:fs/promises"),X=require("node:path");var rs=require("node:crypto"),ns=require("node:fs"),Ze=require("node:fs/promises"),Ce=require("node:path"),os="MANAGED-FILES.json";async function is(t){let e={};async function r(n){for(let o of(await(0,Ze.readdir)(n,{withFileTypes:!0})).sort((i,a)=>i.name.localeCompare(a.name))){let i=(0,Ce.join)(n,o.name),a=await(0,Ze.lstat)(i);if(a.isSymbolicLink())throw new Error(`Managed release contains a symlink: ${i}`);if(a.isDirectory())await r(i);else if(a.isFile()){let s=(0,rs.createHash)("sha256");for await(let l of(0,ns.createReadStream)(i))s.update(l);e[(0,Ce.relative)(t,i).replaceAll("\\","/")]=s.digest("hex")}else throw new Error(`Managed release contains unsupported file: ${i}`)}}return await r(t),e}async function as(t,e){let r=(0,Ce.resolve)(t),n=(0,Ce.join)(r,"pages"),o={schema:1,managedDirectory:"pages",description:e,notice:"GENERATED. Do not edit, delete, rename, optimize, or append to these files. Edit the project source and build a new distribution.",files:await is(n)},i=(0,Ce.join)(r,os);return await(0,Ze.writeFile)(i,JSON.stringify(o,null,2)+`
380
- `),i}async function jt(t){let e=(0,Ce.resolve)(t),r=JSON.parse(await(0,Ze.readFile)((0,Ce.join)(e,os),"utf8"));if(r.schema!==1||r.managedDirectory!=="pages"||!r.files||typeof r.files!="object"||Array.isArray(r.files))throw new Error("Invalid managed release manifest");let n=r.files;if(Object.keys(n).some(a=>a.startsWith("/")||a.includes("\\")||a.split("/").some(s=>!s||s==="."||s==="..")||!/^[0-9a-f]{64}$/.test(n[a])))throw new Error("Invalid managed release file entry");let o=await is((0,Ce.join)(e,"pages")),i=new Set([...Object.keys(n),...Object.keys(o)]);for(let a of[...i].sort()){if(!n[a])throw new Error(`Unlisted managed file: ${a}`);if(!o[a])throw new Error(`Missing managed file: ${a}`);if(n[a]!==o[a])throw new Error(`Modified managed file: ${a}`)}return{files:i.size,root:e}}var gr=require("node:crypto"),cs=require("node:fs"),O=require("node:fs/promises"),L=require("node:path"),co=require("node:child_process");var gt="0.20.0";var fs="BACKUP-RECEIPT.json",ss={project:["site","app","document.json","bundle.json","README.txt",".gitignore",".amw-template.json"],repository:["src","tools","web","webapp","extension","demo","test","package.json","package-lock.json","AGENTS.md","README.md","FORMAT.md","WEBAPP.md","SITE-INTEGRATION.md","PORTFOLIO-RELEASE.md","COPYRIGHT.txt"]},Dt=(t,e)=>{let r=(0,L.relative)(t,e);return!r||!r.startsWith("..")&&!r.includes(":")};async function Qr(t){try{return await(0,O.lstat)(t),!0}catch(e){if(e.code==="ENOENT")return!1;throw e}}async function wt(t){let e=(0,gr.createHash)("sha256");for await(let r of(0,cs.createReadStream)(t))e.update(r);return e.digest("hex")}async function ls(t){if(process.platform!=="win32"){await(0,O.chmod)(t,448);return}let e=(0,co.spawnSync)("whoami.exe",["/user","/fo","csv","/nh"],{encoding:"utf8"}),r=e.stdout?.match(/,"(S-1(?:-\d+)+)"\s*$/)?.[1];if(e.error||e.status!==0||!r)throw new Error("Cannot identify the local user for release backup ACL");let n=(0,co.spawnSync)("icacls.exe",[t,"/grant:r",`*${r}:(OI)(CI)F`,"/inheritance:r"],{encoding:"utf8"});if(n.error||n.status!==0)throw new Error(`Cannot secure local release backup ACL: ${n.error?.message||n.stderr?.trim()}`)}async function fo(t,e,r,n=""){let o=await(0,O.lstat)(t);if(o.isSymbolicLink())throw new Error(`Release snapshot refuses a symlink: ${t}`);if(o.isDirectory()){await(0,O.mkdir)(e,{recursive:!0,mode:448});for(let i of(await(0,O.readdir)(t,{withFileTypes:!0})).sort((a,s)=>a.name.localeCompare(s.name)))i.name===".git"||i.name===".amw"||await fo((0,L.join)(t,i.name),(0,L.join)(e,i.name),r,n?`${n}/${i.name}`:i.name)}else if(o.isFile())await(0,O.copyFile)(t,e),r[n]=await wt(e);else throw new Error(`Release snapshot refuses an unsupported file: ${t}`)}async function us(t,e,r="project"){if(!ss[r])throw new Error("Invalid release snapshot kind");let n=(0,L.resolve)(t),o=(0,L.resolve)(e);if(process.env.AMW_RELEASE_BACKUP_DIR&&!(0,L.isAbsolute)(process.env.AMW_RELEASE_BACKUP_DIR))throw new Error("AMW_RELEASE_BACKUP_DIR must be an absolute local path");let i=(0,L.resolve)(process.env.AMW_RELEASE_BACKUP_DIR||(0,L.join)(n,".amw","release-snapshots"));if(Dt(o,i)||Dt(i,o)||Dt((0,L.join)(n,"site"),i)||Dt((0,L.join)(n,"app"),i))throw new Error("Release backup must be outside the distribution and source input directories");await jt(o);let a=await wt((0,L.join)(o,"MANAGED-FILES.json"));if(await(0,O.mkdir)(i,{recursive:!0,mode:448}),(await(0,O.lstat)(i)).isSymbolicLink())throw new Error("Release backup directory must not be a symlink");await ls(i);let s=await(0,O.mkdtemp)((0,L.join)(i,".snapshot-")),l=`${new Date().toISOString().replace(/[-:.TZ]/g,"")}-${a.slice(0,12)}-${(0,gr.randomBytes)(4).toString("hex")}`,c=(0,L.join)(i,l);try{await ls(s);let f={},u={};for(let _ of ss[r]){let P=(0,L.join)(n,_);if(await Qr(P))await fo(P,(0,L.join)(s,"source",_),f,_);else if(["site","app","document.json","bundle.json","package.json"].includes(_))throw new Error(`Release snapshot is missing required source: ${_}`)}let h=(0,L.join)(n,".amw");for(let _ of["keys","indexes","rotations"]){let P=(0,L.join)(h,_);await Qr(P)&&await fo(P,(0,L.join)(s,"private",_),u,_)}for(let[_,P]of[["AMW_CONTENT_KEY_HEX","environment-content.hex"],["AMW_INDEX_KEY_HEX","environment-index.hex"]]){let S=process.env[_];if(S===void 0)continue;if(!/^[0-9a-fA-F]{64}$/.test(S))throw new Error(`Invalid ${_} for release backup`);let v=(0,L.join)(s,"private",P);await(0,O.mkdir)((0,L.dirname)(v),{recursive:!0,mode:448}),await(0,O.writeFile)(v,S.toLowerCase()+`
380
+ `),i}async function jt(t){let e=(0,Ce.resolve)(t),r=JSON.parse(await(0,Ze.readFile)((0,Ce.join)(e,os),"utf8"));if(r.schema!==1||r.managedDirectory!=="pages"||!r.files||typeof r.files!="object"||Array.isArray(r.files))throw new Error("Invalid managed release manifest");let n=r.files;if(Object.keys(n).some(a=>a.startsWith("/")||a.includes("\\")||a.split("/").some(s=>!s||s==="."||s==="..")||!/^[0-9a-f]{64}$/.test(n[a])))throw new Error("Invalid managed release file entry");let o=await is((0,Ce.join)(e,"pages")),i=new Set([...Object.keys(n),...Object.keys(o)]);for(let a of[...i].sort()){if(!n[a])throw new Error(`Unlisted managed file: ${a}`);if(!o[a])throw new Error(`Missing managed file: ${a}`);if(n[a]!==o[a])throw new Error(`Modified managed file: ${a}`)}return{files:i.size,root:e}}var gr=require("node:crypto"),cs=require("node:fs"),O=require("node:fs/promises"),L=require("node:path"),co=require("node:child_process");var gt="0.21.0";var fs="BACKUP-RECEIPT.json",ss={project:["site","app","document.json","bundle.json","README.txt",".gitignore",".amw-template.json"],repository:["src","tools","web","webapp","extension","demo","test","package.json","package-lock.json","AGENTS.md","README.md","FORMAT.md","WEBAPP.md","SITE-INTEGRATION.md","PORTFOLIO-RELEASE.md","COPYRIGHT.txt"]},Dt=(t,e)=>{let r=(0,L.relative)(t,e);return!r||!r.startsWith("..")&&!r.includes(":")};async function Qr(t){try{return await(0,O.lstat)(t),!0}catch(e){if(e.code==="ENOENT")return!1;throw e}}async function wt(t){let e=(0,gr.createHash)("sha256");for await(let r of(0,cs.createReadStream)(t))e.update(r);return e.digest("hex")}async function ls(t){if(process.platform!=="win32"){await(0,O.chmod)(t,448);return}let e=(0,co.spawnSync)("whoami.exe",["/user","/fo","csv","/nh"],{encoding:"utf8"}),r=e.stdout?.match(/,"(S-1(?:-\d+)+)"\s*$/)?.[1];if(e.error||e.status!==0||!r)throw new Error("Cannot identify the local user for release backup ACL");let n=(0,co.spawnSync)("icacls.exe",[t,"/grant:r",`*${r}:(OI)(CI)F`,"/inheritance:r"],{encoding:"utf8"});if(n.error||n.status!==0)throw new Error(`Cannot secure local release backup ACL: ${n.error?.message||n.stderr?.trim()}`)}async function fo(t,e,r,n=""){let o=await(0,O.lstat)(t);if(o.isSymbolicLink())throw new Error(`Release snapshot refuses a symlink: ${t}`);if(o.isDirectory()){await(0,O.mkdir)(e,{recursive:!0,mode:448});for(let i of(await(0,O.readdir)(t,{withFileTypes:!0})).sort((a,s)=>a.name.localeCompare(s.name)))i.name===".git"||i.name===".amw"||await fo((0,L.join)(t,i.name),(0,L.join)(e,i.name),r,n?`${n}/${i.name}`:i.name)}else if(o.isFile())await(0,O.copyFile)(t,e),r[n]=await wt(e);else throw new Error(`Release snapshot refuses an unsupported file: ${t}`)}async function us(t,e,r="project"){if(!ss[r])throw new Error("Invalid release snapshot kind");let n=(0,L.resolve)(t),o=(0,L.resolve)(e);if(process.env.AMW_RELEASE_BACKUP_DIR&&!(0,L.isAbsolute)(process.env.AMW_RELEASE_BACKUP_DIR))throw new Error("AMW_RELEASE_BACKUP_DIR must be an absolute local path");let i=(0,L.resolve)(process.env.AMW_RELEASE_BACKUP_DIR||(0,L.join)(n,".amw","release-snapshots"));if(Dt(o,i)||Dt(i,o)||Dt((0,L.join)(n,"site"),i)||Dt((0,L.join)(n,"app"),i))throw new Error("Release backup must be outside the distribution and source input directories");await jt(o);let a=await wt((0,L.join)(o,"MANAGED-FILES.json"));if(await(0,O.mkdir)(i,{recursive:!0,mode:448}),(await(0,O.lstat)(i)).isSymbolicLink())throw new Error("Release backup directory must not be a symlink");await ls(i);let s=await(0,O.mkdtemp)((0,L.join)(i,".snapshot-")),l=`${new Date().toISOString().replace(/[-:.TZ]/g,"")}-${a.slice(0,12)}-${(0,gr.randomBytes)(4).toString("hex")}`,c=(0,L.join)(i,l);try{await ls(s);let f={},u={};for(let _ of ss[r]){let P=(0,L.join)(n,_);if(await Qr(P))await fo(P,(0,L.join)(s,"source",_),f,_);else if(["site","app","document.json","bundle.json","package.json"].includes(_))throw new Error(`Release snapshot is missing required source: ${_}`)}let h=(0,L.join)(n,".amw");for(let _ of["keys","indexes","rotations"]){let P=(0,L.join)(h,_);await Qr(P)&&await fo(P,(0,L.join)(s,"private",_),u,_)}for(let[_,P]of[["AMW_CONTENT_KEY_HEX","environment-content.hex"],["AMW_INDEX_KEY_HEX","environment-index.hex"]]){let S=process.env[_];if(S===void 0)continue;if(!/^[0-9a-fA-F]{64}$/.test(S))throw new Error(`Invalid ${_} for release backup`);let v=(0,L.join)(s,"private",P);await(0,O.mkdir)((0,L.dirname)(v),{recursive:!0,mode:448}),await(0,O.writeFile)(v,S.toLowerCase()+`
381
381
  `,{flag:"wx",mode:384}),u[P]=await wt(v)}let p={schema:1,id:l,kind:r,compilerVersion:gt,createdAt:new Date().toISOString(),releaseManifestSha256:a,sourceFiles:f,privateFiles:u,notice:"PRIVATE LOCAL BACKUP. Contains source and may contain bearer keys. Never publish or commit."},d=(0,L.join)(s,"SNAPSHOT.json");await(0,O.writeFile)(d,JSON.stringify(p,null,2)+`
382
382
  `,{flag:"wx",mode:384});let g=await wt(d);await(0,O.rename)(s,c);let m={schema:1,backup:c,releaseManifestSha256:a,snapshotSha256:g},E=(0,L.join)(o,`.backup-receipt-${(0,gr.randomBytes)(8).toString("hex")}.tmp`);try{await(0,O.writeFile)(E,JSON.stringify(m,null,2)+`
383
383
  `,{flag:"wx",mode:384}),await(0,O.rename)(E,(0,L.join)(o,fs))}finally{await Qr(E)&&await(0,O.rm)(E)}return{backup:c,sourceCount:Object.keys(f).length,privateCount:Object.keys(u).length}}finally{Dt(i,s)&&s!==i&&await Qr(s)&&await(0,O.rm)(s,{recursive:!0,force:!0})}}async function Zr(t){let e=(0,L.resolve)(t),r=JSON.parse(await(0,O.readFile)((0,L.join)(e,fs),"utf8"));if(r.schema!==1||!(0,L.isAbsolute)(r.backup)||!/^[0-9a-f]{64}$/.test(r.releaseManifestSha256)||!/^[0-9a-f]{64}$/.test(r.snapshotSha256)||Dt(e,r.backup))throw new Error("Invalid release backup receipt");let n=await wt((0,L.join)(e,"MANAGED-FILES.json"));if(n!==r.releaseManifestSha256)throw new Error("Release backup does not match this distribution");let o=(0,L.join)(r.backup,"SNAPSHOT.json");if(await wt(o)!==r.snapshotSha256)throw new Error("Release backup record was modified");let i=JSON.parse(await(0,O.readFile)(o,"utf8"));if(i.schema!==1||i.releaseManifestSha256!==n||!i.sourceFiles||!i.privateFiles)throw new Error("Invalid release backup record");for(let[a,s]of[["source",i.sourceFiles],["private",i.privateFiles]])for(let[l,c]of Object.entries(s)){if(l.startsWith("/")||l.includes("\\")||l.split("/").some(u=>!u||u==="."||u==="..")||!/^[0-9a-f]{64}$/.test(c))throw new Error("Invalid release backup file record");let f=(0,L.join)(r.backup,a,l);if((await(0,O.lstat)(f)).isSymbolicLink()||await wt(f)!==c)throw new Error(`Release backup file was modified: ${a}/${l}`)}return{backup:r.backup,sourceCount:Object.keys(i.sourceFiles).length,privateCount:Object.keys(i.privateFiles).length}}var Ff=2e4,Hf=25*1024*1024;async function en(t){try{return await(0,re.stat)(t),!0}catch(e){if(e.code==="ENOENT")return!1;throw e}}async function uo(t){let e=0;async function r(n){for(let o of await(0,re.readdir)(n,{withFileTypes:!0})){let i=(0,X.join)(n,o.name),a=await(0,re.lstat)(i);if(a.isSymbolicLink())throw new Error(`Pages distribution contains a symlink: ${i}`);if(a.isDirectory())await r(i);else if(a.isFile()){if(e++,e>Ff)throw new Error("Pages distribution exceeds 20,000 files");if(a.size>Hf)throw new Error(`Pages asset exceeds 25 MiB: ${(0,X.relative)(t,i)}`);if(o.name.toLowerCase().endsWith(".map"))throw new Error(`Pages distribution contains a source map: ${i}`)}else throw new Error(`Pages distribution contains an unsupported file: ${i}`)}}if(await r(t),!await en((0,X.join)(t,"index.html"))||!(await(0,re.stat)((0,X.join)(t,"index.html"))).isFile())throw new Error("Pages distribution needs an index.html file");return e}function Wf(t,e,r){let n=t??"YOUR_PAGES_PROJECT";return`AMOOSEDWEB CLOUDFLARE PAGES DISTRIBUTION
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "amoosedweb-cli",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "description": "AmoosedWeb project compiler and Cloudflare Pages packaging CLI",
5
5
  "homepage": "https://www.amoosed.com/",
6
6
  "bin": {
@@ -16,7 +16,8 @@
16
16
  "amw.cjs",
17
17
  "reader.mjs",
18
18
  "runtime/",
19
- "COPYRIGHT.txt"
19
+ "COPYRIGHT.txt",
20
+ "LICENSE.txt"
20
21
  ],
21
- "license": "UNLICENSED"
22
+ "license": "SEE LICENSE IN LICENSE.txt"
22
23
  }