@uniku/cli 0.0.11 → 0.0.12

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026-current Alberto Schiabel
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1 +1 @@
1
- {"version":3,"file":"bin.d.mts","names":[],"sources":["../src/bin.ts"],"sourcesContent":[],"mappings":";iBAegB,cAAA"}
1
+ {"version":3,"file":"bin.d.mts","names":[],"sources":["../src/bin.ts"],"sourcesContent":[],"mappings":";iBAmBgB,cAAA"}
package/build/bin.mjs CHANGED
@@ -1,4 +1,6 @@
1
- import{BunContext as e,BunRuntime as t}from"@effect/platform-bun";import*as n from"effect/Effect";import*as r from"effect/Layer";import{Args as i,Command as a,Options as o}from"@effect/cli";import*as s from"effect/Option";import{cuid2 as c}from"uniku/cuid2";import{UniqueIdError as l}from"uniku/errors";import{ksuid as u}from"uniku/ksuid";import{nanoid as d}from"uniku/nanoid";import{ulid as f}from"uniku/ulid";import{uuidv4 as p}from"uniku/uuid/v4";import{uuidv7 as m}from"uniku/uuid/v7";import*as h from"effect/Context";const ee={hex:`0123456789abcdef`,numeric:`0123456789`,alpha:`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`};var g=class extends Error{constructor(e,t,n,r=1){super(t),this.code=e,this.hint=n,this.exitCode=r,this.name=`CliError`}},te=class extends g{constructor(e){super(`VALIDATION_FAILED`,e,void 0,2),this.name=`ValidationFailedError`}};function _(e){return new g(e.code,e.message)}function v(e){let t={error:e.message,code:e.code};return e.hint&&(t.hint=e.hint),t}function y(e){return n.try({try:()=>{let t=[];for(let n=0;n<e.count;n++)t.push(c({length:e.length}));return t},catch:e=>e instanceof l?_(e):new g(`GENERATE_FAILED`,String(e))})}function b(e){return n.try({try:()=>{let t=[];for(let n=0;n<e.count;n++){let n=e.timestamp==null?void 0:{secs:e.timestamp};t.push(u(n))}return t},catch:e=>e instanceof l?_(e):new g(`GENERATE_FAILED`,String(e))})}function x(e){if(e)return ee[e]??e}function S(e){return n.try({try:()=>{let t=x(e.alphabet),n=[];for(let r=0;r<e.count;r++)n.push(d({size:e.size,alphabet:t}));return n},catch:e=>e instanceof l?_(e):new g(`GENERATE_FAILED`,String(e))})}function C(e){return e.monotonic&&e.timestamp!=null?n.fail(new g(`INVALID_OPTIONS`,`--monotonic and --timestamp are mutually exclusive`,`Use --monotonic for monotonically increasing ULIDs, or --timestamp to specify a fixed timestamp`)):n.try({try:()=>{let t=[];for(let n=0;n<e.count;n++){let n=f(e.timestamp==null?void 0:{msecs:e.timestamp});e.lowercase&&(n=n.toLowerCase()),t.push(n)}return t},catch:e=>e instanceof l?_(e):new g(`GENERATE_FAILED`,String(e))})}function w(e){return n.try({try:()=>{let t=e.version===7?m:p,n=[];for(let r=0;r<e.count;r++){let r=t();e.lowercase&&(r=r.toLowerCase()),n.push(r)}return n},catch:e=>e instanceof l?_(e):new g(`GENERATE_FAILED`,String(e))})}var T=class extends h.Tag(`OutputService`)(){};function ne(e){if(e.valid){let t=[`valid (${e.type}`];return e.version!=null&&t.push(` v${e.version}`),t.push(`)`),t.join(``)}return`invalid: ${e.error??`malformed identifier`}`}function re(e){let t=[],n=e.version==null?e.type:`${e.type} (v${e.version})`;return t.push(`Type: ${n}`),e.timestamp&&t.push(`Timestamp: ${e.timestamp}`),e.random&&t.push(`Random: ${e.random}`),e.note&&t.push(`Note: ${e.note}`),t.join(`
2
- `)}const ie=T.of({writeIds(e,t){return n.sync(()=>{if(t.json){let t=e.length===1?JSON.stringify(e[0]):JSON.stringify(e);process.stdout.write(`${t}\n`)}else for(let t of e)process.stdout.write(`${t}\n`)})},writeValidation(e,t){return n.sync(()=>{if(!t.quiet)if(t.json){let t=e.length===1?JSON.stringify(e[0]):JSON.stringify(e);process.stdout.write(`${t}\n`)}else for(let t of e)process.stdout.write(`${ne(t)}\n`)})},writeInspect(e,t){return n.sync(()=>{t.json?process.stdout.write(`${JSON.stringify(e)}\n`):process.stdout.write(`${re(e)}\n`)})},writeError(e,t){return n.sync(()=>{if(t.json)process.stderr.write(`${JSON.stringify(v(e))}\n`);else{let t=`Error: ${e.message}`;e.hint&&(t+=`\n ${e.hint}`),process.stderr.write(`${t}\n`)}})}}),E=o.integer(`count`).pipe(o.withAlias(`n`),o.withDescription(`Number of IDs to generate`),o.withDefault(1)),D=o.boolean(`json`).pipe(o.withDescription(`Output as JSON`),o.withDefault(!1)),O=o.choiceWithValue(`version`,[[`4`,4],[`7`,7]]).pipe(o.withAlias(`v`),o.withDescription(`UUID version: 4, 7`),o.withDefault(4)),k=o.boolean(`lowercase`).pipe(o.withAlias(`l`),o.withDescription(`Output in lowercase`),o.withDefault(!1)),A=a.make(`uuid`,{count:E,json:D,version:O,lowercase:k},({count:e,json:t,version:r,lowercase:i})=>n.gen(function*(){let n=yield*T,a=yield*w({count:e,version:r,lowercase:i});yield*n.writeIds(a,{json:t})})).pipe(a.withDescription(`Generate UUIDs (v4 or v7)`)),j=o.boolean(`monotonic`).pipe(o.withDescription(`Generate monotonically increasing ULIDs`),o.withDefault(!1)),M=o.text(`timestamp`).pipe(o.withDescription(`Unix timestamp in milliseconds (or "now")`),o.optional),N=a.make(`ulid`,{count:E,json:D,monotonic:j,timestamp:M,lowercase:k},({count:e,json:t,monotonic:r,timestamp:i,lowercase:a})=>n.gen(function*(){let n=yield*T,o=yield*C({count:e,monotonic:r,timestamp:s.isSome(i)?q(s.getOrThrow(i)):void 0,lowercase:a});yield*n.writeIds(o,{json:t})})).pipe(a.withDescription(`Generate ULIDs`)),P=o.integer(`size`).pipe(o.withAlias(`s`),o.withDescription(`Length of ID (1-256)`),o.withDefault(21)),F=o.text(`alphabet`).pipe(o.withAlias(`a`),o.withDescription(`Custom alphabet or preset: hex, numeric, alpha`),o.optional),I=a.make(`nanoid`,{count:E,json:D,size:P,alphabet:F},({count:e,json:t,size:r,alphabet:i})=>n.gen(function*(){let n=yield*T,a=yield*S({count:e,size:r,alphabet:s.isSome(i)?s.getOrThrow(i):void 0});yield*n.writeIds(a,{json:t})})).pipe(a.withDescription(`Generate Nanoids`)),L=o.integer(`length`).pipe(o.withAlias(`l`),o.withDescription(`Length of ID (2-32)`),o.withDefault(24)),R=a.make(`cuid`,{count:E,json:D,length:L},({count:e,json:t,length:r})=>n.gen(function*(){let n=yield*T,i=yield*y({count:e,length:r});yield*n.writeIds(i,{json:t})})).pipe(a.withDescription(`Generate CUIDs (v2)`)),z=o.text(`timestamp`).pipe(o.withDescription(`Unix timestamp in seconds (or "now")`),o.optional),B=a.make(`ksuid`,{count:E,json:D,timestamp:z},({count:e,json:t,timestamp:r})=>n.gen(function*(){let n=yield*T,i=yield*b({count:e,timestamp:s.isSome(r)?J(s.getOrThrow(r)):void 0});yield*n.writeIds(i,{json:t})})).pipe(a.withDescription(`Generate KSUIDs`)),V=a.make(`generate`).pipe(a.withDescription(`Generate new IDs`),a.withSubcommands([A,N,I,R,B])),H=A,U=N,W=I,G=R,K=B;function q(e){if(e===`now`)return Date.now();let t=Number(e);if(!Number.isFinite(t)||t<0)throw new g(`INVALID_TIMESTAMP`,`Invalid timestamp: "${e}"`,`Provide a Unix timestamp in milliseconds or "now"`);return t}function J(e){if(e===`now`)return Math.floor(Date.now()/1e3);let t=Number(e);if(!Number.isFinite(t)||t<0)throw new g(`INVALID_TIMESTAMP`,`Invalid timestamp: "${e}"`,`Provide a Unix timestamp in seconds or "now"`);return t}function Y(e,t){switch(t){case`uuid`:return ae(e);case`ulid`:return oe(e);case`ksuid`:return se(e);case`cuid`:return ce(e);case`nanoid`:return le(e)}}function X(e){return m.isValid(e)?{id:e,valid:!0,type:`uuid`,version:7}:p.isValid(e)?{id:e,valid:!0,type:`uuid`,version:4}:f.isValid(e)?{id:e,valid:!0,type:`ulid`}:u.isValid(e)?{id:e,valid:!0,type:`ksuid`}:c.isValid(e)?{id:e,valid:!0,type:`cuid`}:d.isValid(e)?{id:e,valid:!0,type:`nanoid`}:{id:e,valid:!1,error:`malformed identifier`}}function ae(e){return m.isValid(e)?{id:e,valid:!0,type:`uuid`,version:7}:p.isValid(e)?{id:e,valid:!0,type:`uuid`,version:4}:{id:e,valid:!1,type:`uuid`,error:`invalid UUID format`}}function oe(e){return f.isValid(e)?{id:e,valid:!0,type:`ulid`}:{id:e,valid:!1,type:`ulid`,error:`invalid ULID format`}}function se(e){return u.isValid(e)?{id:e,valid:!0,type:`ksuid`}:{id:e,valid:!1,type:`ksuid`,error:`invalid KSUID format`}}function ce(e){return c.isValid(e)?{id:e,valid:!0,type:`cuid`}:{id:e,valid:!1,type:`cuid`,error:`invalid CUID format`}}function le(e){return d.isValid(e)?{id:e,valid:!0,type:`nanoid`}:{id:e,valid:!1,type:`nanoid`,error:`invalid Nanoid format`}}function ue(e,t){let n=t??de(e);if(!n)return null;switch(n){case`uuid`:return fe(e);case`ulid`:return pe(e);case`ksuid`:return me(e);case`cuid`:return he(e);case`nanoid`:return ge(e)}}function de(e){let t=X(e);return t.valid?t.type??null:null}function fe(e){if(m.isValid(e)){let t=m.timestamp(e),n=m.toBytes(e),r=Buffer.from(n.slice(10)).toString(`hex`);return{id:e,type:`uuid`,version:7,timestamp:new Date(t).toISOString(),timestamp_ms:t,random:r}}return p.isValid(e)?{id:e,type:`uuid`,version:4,note:`This ID type contains no decodable metadata.`}:{id:e,type:`uuid`,note:`Unrecognized UUID version.`}}function pe(e){let t=f.timestamp(e),n=e.slice(10);return{id:e,type:`ulid`,timestamp:new Date(t).toISOString(),timestamp_ms:t,random:n}}function me(e){let t=u.timestamp(e),n=u.toBytes(e),r=Buffer.from(n.slice(4)).toString(`hex`);return{id:e,type:`ksuid`,timestamp:new Date(t).toISOString(),timestamp_ms:t,random:r}}function he(e){return{id:e,type:`cuid`,note:`This ID type contains no decodable metadata.`}}function ge(e){return{id:e,type:`nanoid`,note:`This ID type contains no decodable metadata.`}}const _e=i.text({name:`id`}).pipe(i.withDescription(`The ID to inspect`)),ve=o.choice(`type`,[`uuid`,`ulid`,`nanoid`,`cuid`,`ksuid`]).pipe(o.withDescription(`ID type (auto-detected if omitted)`),o.optional),ye=o.boolean(`json`).pipe(o.withDescription(`Output as JSON`),o.withDefault(!1)),be=a.make(`inspect`,{id:_e,type:ve,json:ye},({id:e,type:t,json:r})=>n.gen(function*(){let i=yield*T,a=ue(e,s.isSome(t)?s.getOrThrow(t):void 0);if(!a){yield*n.fail(new g(`UNKNOWN_ID_TYPE`,`Could not identify ID type for: "${e}"`,`Use --type to specify the ID type`));return}yield*i.writeInspect(a,{json:r})})).pipe(a.withDescription(`Decode and inspect an ID`));var Z=class extends h.Tag(`StdinService`)(){};const xe=Z.of({readLines(){return n.async(e=>{let t=[];process.stdin.on(`data`,e=>{t.push(e)}),process.stdin.on(`end`,()=>{let r=Buffer.concat(t).toString(`utf-8`).split(`
3
- `).map(e=>e.trim()).filter(e=>e.length>0);e(n.succeed(r))}),process.stdin.on(`error`,t=>{e(n.fail(new g(`STDIN_ERROR`,t.message)))}),process.stdin.resume()})}}),Q=i.text({name:`id`}).pipe(i.withDescription(`The ID to validate`),i.optional),Se=o.choice(`type`,[`uuid`,`ulid`,`nanoid`,`cuid`,`ksuid`]).pipe(o.withDescription(`Expected ID type (auto-detected if omitted)`),o.optional),Ce=o.boolean(`stdin`).pipe(o.withDescription(`Read IDs from stdin (one per line)`),o.withDefault(!1)),we=o.boolean(`json`).pipe(o.withDescription(`Output validation results as JSON`),o.withDefault(!1)),Te=o.boolean(`quiet`).pipe(o.withDescription(`No output, exit code only`),o.withDefault(!1)),Ee=a.make(`validate`,{id:Q,type:Se,stdin:Ce,json:we,quiet:Te},({id:e,type:t,stdin:r,json:i,quiet:a})=>n.gen(function*(){let o=yield*T,c=yield*Z,l=s.isSome(t)?s.getOrThrow(t):void 0,u;if(r){if(u=yield*c.readLines(),u.length===0){yield*n.fail(new g(`NO_INPUT`,`No IDs provided on stdin`));return}}else if(s.isSome(e))u=[s.getOrThrow(e)];else{yield*n.fail(new g(`NO_INPUT`,`No ID provided`,`Pass an ID as argument or use --stdin`));return}let d=u.map(e=>l?Y(e,l):X(e));yield*o.writeValidation(d,{json:i,quiet:a}),d.some(e=>!e.valid)&&(yield*n.fail(new te(`One or more IDs are invalid`)))})).pipe(a.withDescription(`Check if an ID is valid`)),De=a.make(`uniku`).pipe(a.withDescription(`Generate and validate unique identifiers`),a.withSubcommands([V,Ee,be,H,U,W,G,K])),Oe=(e=>a.run(De,{name:`uniku`,version:e}))(`0.0.11`);function $(e){let t=[...e];for(let e=2;e<t.length;e++)t[e]===`-V`&&(t[e]=`--version`);return t.length<=2&&t.push(`--help`),t}const ke=r.mergeAll(r.succeed(T,ie),r.succeed(Z,xe)),Ae=r.mergeAll(ke,e.layer);n.suspend(()=>Oe($(process.argv))).pipe(n.catchAll(e=>n.sync(()=>{e instanceof g?(process.stderr.write(`Error: ${e.message}\n`),e.hint&&process.stderr.write(` ${e.hint}\n`),process.exitCode=e.exitCode):(process.stderr.write(`Error: ${String(e)}\n`),process.exitCode=1)})),n.provide(Ae),t.runMain);export{$ as preprocessArgs};
1
+ import{BunContext as e,BunRuntime as t}from"@effect/platform-bun";import*as n from"effect/Duration";import*as r from"effect/Effect";import*as i from"effect/Fiber";import*as a from"effect/Layer";import*as o from"effect/Option";import{Args as s,Command as c,Options as l}from"@effect/cli";import{cuid2 as u}from"uniku/cuid2";import{UniqueIdError as d}from"uniku/errors";import{ksuid as f}from"uniku/ksuid";import{nanoid as p}from"uniku/nanoid";import{ulid as m}from"uniku/ulid";import{uuidv4 as h}from"uniku/uuid/v4";import{uuidv7 as g}from"uniku/uuid/v7";import*as _ from"effect/Context";import{existsSync as v,mkdirSync as ee,readFileSync as te,renameSync as y,writeFileSync as b}from"node:fs";import{tmpdir as x}from"node:os";import{dirname as S,join as C}from"node:path";const w={hex:`0123456789abcdef`,numeric:`0123456789`,alpha:`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`};var T=class extends Error{constructor(e,t,n,r=1){super(t),this.code=e,this.hint=n,this.exitCode=r,this.name=`CliError`}},ne=class extends T{constructor(e){super(`VALIDATION_FAILED`,e,void 0,2),this.name=`ValidationFailedError`}};function E(e){return new T(e.code,e.message)}function re(e){let t={error:e.message,code:e.code};return e.hint&&(t.hint=e.hint),t}function ie(e){return r.try({try:()=>{let t=[];for(let n=0;n<e.count;n++)t.push(u({length:e.length}));return t},catch:e=>e instanceof d?E(e):new T(`GENERATE_FAILED`,String(e))})}function ae(e){return r.try({try:()=>{let t=[];for(let n=0;n<e.count;n++){let n=e.timestamp==null?void 0:{secs:e.timestamp};t.push(f(n))}return t},catch:e=>e instanceof d?E(e):new T(`GENERATE_FAILED`,String(e))})}function oe(e){if(e)return w[e]??e}function se(e){return r.try({try:()=>{let t=oe(e.alphabet),n=[];for(let r=0;r<e.count;r++)n.push(p({size:e.size,alphabet:t}));return n},catch:e=>e instanceof d?E(e):new T(`GENERATE_FAILED`,String(e))})}function ce(e){return e.monotonic&&e.timestamp!=null?r.fail(new T(`INVALID_OPTIONS`,`--monotonic and --timestamp are mutually exclusive`,`Use --monotonic for monotonically increasing ULIDs, or --timestamp to specify a fixed timestamp`)):r.try({try:()=>{let t=[];for(let n=0;n<e.count;n++){let n=m(e.timestamp==null?void 0:{msecs:e.timestamp});e.lowercase&&(n=n.toLowerCase()),t.push(n)}return t},catch:e=>e instanceof d?E(e):new T(`GENERATE_FAILED`,String(e))})}function le(e){return r.try({try:()=>{let t=e.version===7?g:h,n=[];for(let r=0;r<e.count;r++){let r=t();e.lowercase&&(r=r.toLowerCase()),n.push(r)}return n},catch:e=>e instanceof d?E(e):new T(`GENERATE_FAILED`,String(e))})}var D=class extends _.Tag(`OutputService`)(){};function ue(e){if(e.valid){let t=[`valid (${e.type}`];return e.version!=null&&t.push(` v${e.version}`),t.push(`)`),t.join(``)}return`invalid: ${e.error??`malformed identifier`}`}function de(e){let t=[],n=e.version==null?e.type:`${e.type} (v${e.version})`;return t.push(`Type: ${n}`),e.timestamp&&t.push(`Timestamp: ${e.timestamp}`),e.random&&t.push(`Random: ${e.random}`),e.note&&t.push(`Note: ${e.note}`),t.join(`
2
+ `)}const fe=D.of({writeIds(e,t){return r.sync(()=>{if(t.json){let t=e.length===1?JSON.stringify(e[0]):JSON.stringify(e);process.stdout.write(`${t}\n`)}else for(let t of e)process.stdout.write(`${t}\n`)})},writeValidation(e,t){return r.sync(()=>{if(!t.quiet)if(t.json){let t=e.length===1?JSON.stringify(e[0]):JSON.stringify(e);process.stdout.write(`${t}\n`)}else for(let t of e)process.stdout.write(`${ue(t)}\n`)})},writeInspect(e,t){return r.sync(()=>{t.json?process.stdout.write(`${JSON.stringify(e)}\n`):process.stdout.write(`${de(e)}\n`)})},writeError(e,t){return r.sync(()=>{if(t.json)process.stderr.write(`${JSON.stringify(re(e))}\n`);else{let t=`Error: ${e.message}`;e.hint&&(t+=`\n ${e.hint}`),process.stderr.write(`${t}\n`)}})}}),O=l.integer(`count`).pipe(l.withAlias(`n`),l.withDescription(`Number of IDs to generate`),l.withDefault(1)),k=l.boolean(`json`).pipe(l.withDescription(`Output as JSON`),l.withDefault(!1)),A=l.choiceWithValue(`version`,[[`4`,4],[`7`,7]]).pipe(l.withAlias(`v`),l.withDescription(`UUID version: 4, 7`),l.withDefault(4)),j=l.boolean(`lowercase`).pipe(l.withAlias(`l`),l.withDescription(`Output in lowercase`),l.withDefault(!1)),M=c.make(`uuid`,{count:O,json:k,version:A,lowercase:j},({count:e,json:t,version:n,lowercase:i})=>r.gen(function*(){let r=yield*D,a=yield*le({count:e,version:n,lowercase:i});yield*r.writeIds(a,{json:t})})).pipe(c.withDescription(`Generate UUIDs (v4 or v7)`)),N=l.boolean(`monotonic`).pipe(l.withDescription(`Generate monotonically increasing ULIDs`),l.withDefault(!1)),P=l.text(`timestamp`).pipe(l.withDescription(`Unix timestamp in milliseconds (or "now")`),l.optional),F=c.make(`ulid`,{count:O,json:k,monotonic:N,timestamp:P,lowercase:j},({count:e,json:t,monotonic:n,timestamp:i,lowercase:a})=>r.gen(function*(){let r=yield*D,s=yield*ce({count:e,monotonic:n,timestamp:o.isSome(i)?ye(o.getOrThrow(i)):void 0,lowercase:a});yield*r.writeIds(s,{json:t})})).pipe(c.withDescription(`Generate ULIDs`)),I=l.integer(`size`).pipe(l.withAlias(`s`),l.withDescription(`Length of ID (1-256)`),l.withDefault(21)),L=l.text(`alphabet`).pipe(l.withAlias(`a`),l.withDescription(`Custom alphabet or preset: hex, numeric, alpha`),l.optional),R=c.make(`nanoid`,{count:O,json:k,size:I,alphabet:L},({count:e,json:t,size:n,alphabet:i})=>r.gen(function*(){let r=yield*D,a=yield*se({count:e,size:n,alphabet:o.isSome(i)?o.getOrThrow(i):void 0});yield*r.writeIds(a,{json:t})})).pipe(c.withDescription(`Generate Nanoids`)),z=l.integer(`length`).pipe(l.withAlias(`l`),l.withDescription(`Length of ID (2-32)`),l.withDefault(24)),B=c.make(`cuid`,{count:O,json:k,length:z},({count:e,json:t,length:n})=>r.gen(function*(){let r=yield*D,i=yield*ie({count:e,length:n});yield*r.writeIds(i,{json:t})})).pipe(c.withDescription(`Generate CUIDs (v2)`)),V=l.text(`timestamp`).pipe(l.withDescription(`Unix timestamp in seconds (or "now")`),l.optional),H=c.make(`ksuid`,{count:O,json:k,timestamp:V},({count:e,json:t,timestamp:n})=>r.gen(function*(){let r=yield*D,i=yield*ae({count:e,timestamp:o.isSome(n)?be(o.getOrThrow(n)):void 0});yield*r.writeIds(i,{json:t})})).pipe(c.withDescription(`Generate KSUIDs`)),pe=c.make(`generate`).pipe(c.withDescription(`Generate new IDs`),c.withSubcommands([M,F,R,B,H])),me=M,he=F,ge=R,_e=B,ve=H;function ye(e){if(e===`now`)return Date.now();let t=Number(e);if(!Number.isFinite(t)||t<0)throw new T(`INVALID_TIMESTAMP`,`Invalid timestamp: "${e}"`,`Provide a Unix timestamp in milliseconds or "now"`);return t}function be(e){if(e===`now`)return Math.floor(Date.now()/1e3);let t=Number(e);if(!Number.isFinite(t)||t<0)throw new T(`INVALID_TIMESTAMP`,`Invalid timestamp: "${e}"`,`Provide a Unix timestamp in seconds or "now"`);return t}function xe(e,t){switch(t){case`uuid`:return Se(e);case`ulid`:return Ce(e);case`ksuid`:return we(e);case`cuid`:return Te(e);case`nanoid`:return Ee(e)}}function U(e){return g.isValid(e)?{id:e,valid:!0,type:`uuid`,version:7}:h.isValid(e)?{id:e,valid:!0,type:`uuid`,version:4}:m.isValid(e)?{id:e,valid:!0,type:`ulid`}:f.isValid(e)?{id:e,valid:!0,type:`ksuid`}:u.isValid(e)?{id:e,valid:!0,type:`cuid`}:p.isValid(e)?{id:e,valid:!0,type:`nanoid`}:{id:e,valid:!1,error:`malformed identifier`}}function Se(e){return g.isValid(e)?{id:e,valid:!0,type:`uuid`,version:7}:h.isValid(e)?{id:e,valid:!0,type:`uuid`,version:4}:{id:e,valid:!1,type:`uuid`,error:`invalid UUID format`}}function Ce(e){return m.isValid(e)?{id:e,valid:!0,type:`ulid`}:{id:e,valid:!1,type:`ulid`,error:`invalid ULID format`}}function we(e){return f.isValid(e)?{id:e,valid:!0,type:`ksuid`}:{id:e,valid:!1,type:`ksuid`,error:`invalid KSUID format`}}function Te(e){return u.isValid(e)?{id:e,valid:!0,type:`cuid`}:{id:e,valid:!1,type:`cuid`,error:`invalid CUID format`}}function Ee(e){return p.isValid(e)?{id:e,valid:!0,type:`nanoid`}:{id:e,valid:!1,type:`nanoid`,error:`invalid Nanoid format`}}function De(e,t){let n=t??Oe(e);if(!n)return null;switch(n){case`uuid`:return ke(e);case`ulid`:return Ae(e);case`ksuid`:return je(e);case`cuid`:return Me(e);case`nanoid`:return Ne(e)}}function Oe(e){let t=U(e);return t.valid?t.type??null:null}function ke(e){if(g.isValid(e)){let t=g.timestamp(e),n=g.toBytes(e),r=Buffer.from(n.slice(10)).toString(`hex`);return{id:e,type:`uuid`,version:7,timestamp:new Date(t).toISOString(),timestamp_ms:t,random:r}}return h.isValid(e)?{id:e,type:`uuid`,version:4,note:`This ID type contains no decodable metadata.`}:{id:e,type:`uuid`,note:`Unrecognized UUID version.`}}function Ae(e){let t=m.timestamp(e),n=e.slice(10);return{id:e,type:`ulid`,timestamp:new Date(t).toISOString(),timestamp_ms:t,random:n}}function je(e){let t=f.timestamp(e),n=f.toBytes(e),r=Buffer.from(n.slice(4)).toString(`hex`);return{id:e,type:`ksuid`,timestamp:new Date(t).toISOString(),timestamp_ms:t,random:r}}function Me(e){return{id:e,type:`cuid`,note:`This ID type contains no decodable metadata.`}}function Ne(e){return{id:e,type:`nanoid`,note:`This ID type contains no decodable metadata.`}}const Pe=s.text({name:`id`}).pipe(s.withDescription(`The ID to inspect`)),Fe=l.choice(`type`,[`uuid`,`ulid`,`nanoid`,`cuid`,`ksuid`]).pipe(l.withDescription(`ID type (auto-detected if omitted)`),l.optional),Ie=l.boolean(`json`).pipe(l.withDescription(`Output as JSON`),l.withDefault(!1)),Le=c.make(`inspect`,{id:Pe,type:Fe,json:Ie},({id:e,type:t,json:n})=>r.gen(function*(){let i=yield*D,a=De(e,o.isSome(t)?o.getOrThrow(t):void 0);if(!a){yield*r.fail(new T(`UNKNOWN_ID_TYPE`,`Could not identify ID type for: "${e}"`,`Use --type to specify the ID type`));return}yield*i.writeInspect(a,{json:n})})).pipe(c.withDescription(`Decode and inspect an ID`));var W=class extends _.Tag(`StdinService`)(){};const Re=W.of({readLines(){return r.async(e=>{let t=[];process.stdin.on(`data`,e=>{t.push(e)}),process.stdin.on(`end`,()=>{let n=Buffer.concat(t).toString(`utf-8`).split(`
3
+ `).map(e=>e.trim()).filter(e=>e.length>0);e(r.succeed(n))}),process.stdin.on(`error`,t=>{e(r.fail(new T(`STDIN_ERROR`,t.message)))}),process.stdin.resume()})}}),ze=s.text({name:`id`}).pipe(s.withDescription(`The ID to validate`),s.optional),Be=l.choice(`type`,[`uuid`,`ulid`,`nanoid`,`cuid`,`ksuid`]).pipe(l.withDescription(`Expected ID type (auto-detected if omitted)`),l.optional),Ve=l.boolean(`stdin`).pipe(l.withDescription(`Read IDs from stdin (one per line)`),l.withDefault(!1)),He=l.boolean(`json`).pipe(l.withDescription(`Output validation results as JSON`),l.withDefault(!1)),Ue=l.boolean(`quiet`).pipe(l.withDescription(`No output, exit code only`),l.withDefault(!1)),We=c.make(`validate`,{id:ze,type:Be,stdin:Ve,json:He,quiet:Ue},({id:e,type:t,stdin:n,json:i,quiet:a})=>r.gen(function*(){let s=yield*D,c=yield*W,l=o.isSome(t)?o.getOrThrow(t):void 0,u;if(n){if(u=yield*c.readLines(),u.length===0){yield*r.fail(new T(`NO_INPUT`,`No IDs provided on stdin`));return}}else if(o.isSome(e))u=[o.getOrThrow(e)];else{yield*r.fail(new T(`NO_INPUT`,`No ID provided`,`Pass an ID as argument or use --stdin`));return}let d=u.map(e=>l?xe(e,l):U(e));yield*s.writeValidation(d,{json:i,quiet:a}),d.some(e=>!e.valid)&&(yield*r.fail(new ne(`One or more IDs are invalid`)))})).pipe(c.withDescription(`Check if an ID is valid`)),Ge=c.make(`uniku`).pipe(c.withDescription(`Generate and validate unique identifiers`),c.withSubcommands([pe,We,Le,me,he,ge,_e,ve])),Ke=e=>c.run(Ge,{name:`uniku`,version:e});var G=class extends _.Tag(`UpdateCheckService`)(){};const K=`@uniku/cli`,q=C(x(),`uniku-update-check.json`);function J(e){let t=e.match(/^v?(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/);return t?{major:Number(t[1]),minor:Number(t[2]),patch:Number(t[3]),prerelease:t[4]??null}:null}function Y(e,t){let n=J(e),r=J(t);return!n||!r?!1:n.major===r.major?n.minor===r.minor?n.patch===r.patch?n.prerelease===null&&r.prerelease!==null?!0:(n.prerelease!==null&&r.prerelease,!1):n.patch>r.patch:n.minor>r.minor:n.major>r.major}function qe(){return!!process.env.NO_UPDATE_NOTIFIER||!!process.env.CI||!!process.env.CONTINUOUS_INTEGRATION||process.env.NODE_ENV===`test`||!process.stderr.isTTY}function X(e){if(process.env.NO_COLOR){let t=e.isStandaloneBinary?`Download at https://github.com/jkomyno/uniku/releases`:`Run \`npm install -g ${K}\` to update`;return[``,` Update available: ${e.currentVersion} → ${e.latestVersion}`,` ${t}`,` Set NO_UPDATE_NOTIFIER=1 to disable`,``].join(`
4
+ `)}let t=`\x1B[2m`,n=`\x1B[36m`,r=`\x1B[0m`,i=e.isStandaloneBinary?`Download at ${n}https://github.com/jkomyno/uniku/releases${r}`:`Run ${n}\`npm install -g ${K}\`${r} to update`;return[``,` ${t}Update available:${r} ${t}${e.currentVersion}${r} ${t}→${r} ${e.latestVersion}${r}`,` ${i}`,` ${t}Set NO_UPDATE_NOTIFIER=1 to disable${r}`,``].join(`
5
+ `)}function Je(){try{if(!v(q))return null;let e=te(q,`utf-8`);return JSON.parse(e)}catch{return null}}function Ye(e){try{ee(S(q),{recursive:!0});let t=`${q}.tmp`;b(t,JSON.stringify(e)),y(t,q)}catch{}}function Xe(e){return r.tryPromise({try:t=>fetch(`https://registry.npmjs.org/%40uniku%2Fcli/latest`,{headers:{Accept:`application/json`,"User-Agent":`${K}/${e}`},signal:AbortSignal.any([t,AbortSignal.timeout(5e3)])}).then(async e=>{if(!e.ok)throw Error(`HTTP ${e.status}`);let t=await e.json();if(!t.version)throw Error(`Missing version field`);return t.version}),catch:()=>Error(`fetch failed`)}).pipe(r.catchAll(()=>r.succeed(null)))}function Z(){try{return typeof __STANDALONE_BINARY__<`u`&&__STANDALONE_BINARY__===!0}catch{return!1}}const Ze=G.of({check(e){return r.gen(function*(){if(qe())return o.none();let t=Je(),n=Date.now();if(t&&n-t.checkedAt<864e5)return Y(t.latestVersion,e)?o.some({currentVersion:e,latestVersion:t.latestVersion,isStandaloneBinary:Z()}):o.none();let r=yield*Xe(e);return r===null?o.none():(Ye({latestVersion:r,checkedAt:n}),Y(r,e)?o.some({currentVersion:e,latestVersion:r,isStandaloneBinary:Z()}):o.none())}).pipe(r.catchAll(()=>r.succeed(o.none())))},notify(e){return r.sync(()=>{process.stderr.write(X(e))})}});var Q=`0.0.12`;const Qe=Ke(Q);function $(e){let t=[...e];for(let e=2;e<t.length;e++)t[e]===`-V`&&(t[e]=`--version`);return t.length<=2&&t.push(`--help`),t}const $e=a.mergeAll(a.succeed(D,fe),a.succeed(W,Re),a.succeed(G,Ze)),et=a.mergeAll($e,e.layer);r.gen(function*(){let e=yield*G,t=$(process.argv),a=yield*r.fork(e.check(Q));yield*r.suspend(()=>Qe(t)).pipe(r.catchAll(e=>r.sync(()=>{e instanceof T?(process.stderr.write(`Error: ${e.message}\n`),e.hint&&process.stderr.write(` ${e.hint}\n`),process.exitCode=e.exitCode):(process.stderr.write(`Error: ${String(e)}\n`),process.exitCode=1)})));let s=yield*i.join(a).pipe(r.timeout(n.seconds(5)),r.catchAll(()=>r.succeed(o.none())));o.isSome(s)&&!t.includes(`--json`)&&(yield*e.notify(s.value))}).pipe(r.provide(et),t.runMain);export{$ as preprocessArgs};
4
6
  //# sourceMappingURL=bin.mjs.map
package/build/bin.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.mjs","names":["NANOID_ALPHABET_PRESETS: Record<string, string>","code: string","hint?: string","exitCode: number","obj: { error: string; code: string; hint?: string }","ids: string[]","ids: string[]","ids: string[]","ids: string[]","ids: string[]","lines: string[]","jsonOption","idArg","typeOption","jsonOption","chunks: Buffer[]","type: IdType | undefined","ids: readonly string[]","results: ValidationResult[]","pkg.version"],"sources":["../src/domain/constants.ts","../src/domain/errors.ts","../src/generators/cuid.ts","../src/generators/ksuid.ts","../src/generators/nanoid.ts","../src/generators/ulid.ts","../src/generators/uuid.ts","../src/services/OutputService.ts","../src/commands/generate.cmd.ts","../src/validators/validate.ts","../src/inspectors/inspect.ts","../src/commands/inspect.cmd.ts","../src/services/StdinService.ts","../src/commands/validate.cmd.ts","../src/commands/index.ts","../package.json","../src/bin.ts"],"sourcesContent":["/** Default count for ID generation. */\nexport const COUNT_DEFAULT = 1\n\n/** Valid UUID versions. */\nexport const UUID_VERSIONS = [4, 7] as const\n\n/** Default UUID version. */\nexport const UUID_VERSION_DEFAULT = 4\n\n/** Default nanoid size. */\nexport const NANOID_SIZE_DEFAULT = 21\n\n/** Nanoid size range. */\nexport const NANOID_SIZE_MIN = 1\nexport const NANOID_SIZE_MAX = 256\n\n/** Default CUID2 length. */\nexport const CUID_LENGTH_DEFAULT = 24\n\n/** CUID2 length range. */\nexport const CUID_LENGTH_MIN = 2\nexport const CUID_LENGTH_MAX = 32\n\n/** Nanoid alphabet presets. */\nexport const NANOID_ALPHABET_PRESETS: Record<string, string> = {\n hex: '0123456789abcdef',\n numeric: '0123456789',\n alpha: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',\n}\n\n/** Environment variable for default generate type. */\nexport const ENV_DEFAULT_TYPE = 'UNIKU_DEFAULT_TYPE'\n","import type { UniqueIdError } from 'uniku/errors'\n\n/**\n * Structured CLI error with optional hint and exit code.\n */\nexport class CliError extends Error {\n constructor(\n readonly code: string,\n message: string,\n readonly hint?: string,\n readonly exitCode: number = 1,\n ) {\n super(message)\n this.name = 'CliError'\n }\n}\n\n/**\n * Error indicating validation failure (exit code 2).\n */\nexport class ValidationFailedError extends CliError {\n constructor(message: string) {\n super('VALIDATION_FAILED', message, undefined, 2)\n this.name = 'ValidationFailedError'\n }\n}\n\n/**\n * Maps a uniku library error into a CliError, preserving code and message.\n */\nexport function fromUnikuError(err: UniqueIdError): CliError {\n return new CliError(err.code, err.message)\n}\n\n/**\n * Converts a CliError to a JSON-serializable object for stderr output.\n */\nexport function errorToJson(err: CliError): { error: string; code: string; hint?: string } {\n const obj: { error: string; code: string; hint?: string } = {\n error: err.message,\n code: err.code,\n }\n if (err.hint) {\n obj.hint = err.hint\n }\n return obj\n}\n","import * as Effect from 'effect/Effect'\nimport { cuid2 } from 'uniku/cuid2'\nimport { UniqueIdError } from 'uniku/errors'\nimport { CliError, fromUnikuError } from '@/src/domain/errors'\n\nexport type CuidGenerateOptions = {\n readonly count: number\n readonly length: number\n}\n\nexport function generateCuid(options: CuidGenerateOptions): Effect.Effect<string[], CliError> {\n return Effect.try({\n try: () => {\n const ids: string[] = []\n for (let i = 0; i < options.count; i++) {\n ids.push(cuid2({ length: options.length }))\n }\n return ids\n },\n catch: (err) => {\n if (err instanceof UniqueIdError) return fromUnikuError(err)\n return new CliError('GENERATE_FAILED', String(err))\n },\n })\n}\n","import * as Effect from 'effect/Effect'\nimport { UniqueIdError } from 'uniku/errors'\nimport { ksuid } from 'uniku/ksuid'\nimport { CliError, fromUnikuError } from '@/src/domain/errors'\n\nexport type KsuidGenerateOptions = {\n readonly count: number\n readonly timestamp?: number\n}\n\nexport function generateKsuid(options: KsuidGenerateOptions): Effect.Effect<string[], CliError> {\n return Effect.try({\n try: () => {\n const ids: string[] = []\n for (let i = 0; i < options.count; i++) {\n const ksuidOpts = options.timestamp != null ? { secs: options.timestamp } : undefined\n ids.push(ksuid(ksuidOpts))\n }\n return ids\n },\n catch: (err) => {\n if (err instanceof UniqueIdError) return fromUnikuError(err)\n return new CliError('GENERATE_FAILED', String(err))\n },\n })\n}\n","import * as Effect from 'effect/Effect'\nimport { UniqueIdError } from 'uniku/errors'\nimport { nanoid } from 'uniku/nanoid'\nimport { NANOID_ALPHABET_PRESETS } from '@/src/domain/constants'\nimport { CliError, fromUnikuError } from '@/src/domain/errors'\n\nexport type NanoidGenerateOptions = {\n readonly count: number\n readonly size: number\n readonly alphabet?: string\n}\n\nfunction resolveAlphabet(input?: string): string | undefined {\n if (!input) return undefined\n return NANOID_ALPHABET_PRESETS[input] ?? input\n}\n\nexport function generateNanoid(options: NanoidGenerateOptions): Effect.Effect<string[], CliError> {\n return Effect.try({\n try: () => {\n const alphabet = resolveAlphabet(options.alphabet)\n const ids: string[] = []\n for (let i = 0; i < options.count; i++) {\n ids.push(nanoid({ size: options.size, alphabet }))\n }\n return ids\n },\n catch: (err) => {\n if (err instanceof UniqueIdError) return fromUnikuError(err)\n return new CliError('GENERATE_FAILED', String(err))\n },\n })\n}\n","import * as Effect from 'effect/Effect'\nimport { UniqueIdError } from 'uniku/errors'\nimport { ulid } from 'uniku/ulid'\nimport { CliError, fromUnikuError } from '@/src/domain/errors'\n\nexport type UlidGenerateOptions = {\n readonly count: number\n readonly monotonic: boolean\n readonly timestamp?: number\n readonly lowercase: boolean\n}\n\nexport function generateUlid(options: UlidGenerateOptions): Effect.Effect<string[], CliError> {\n if (options.monotonic && options.timestamp != null) {\n return Effect.fail(\n new CliError(\n 'INVALID_OPTIONS',\n '--monotonic and --timestamp are mutually exclusive',\n 'Use --monotonic for monotonically increasing ULIDs, or --timestamp to specify a fixed timestamp',\n ),\n )\n }\n\n return Effect.try({\n try: () => {\n const ids: string[] = []\n for (let i = 0; i < options.count; i++) {\n const ulidOpts = options.timestamp != null ? { msecs: options.timestamp } : undefined\n let id = ulid(ulidOpts)\n if (options.lowercase) {\n id = id.toLowerCase()\n }\n ids.push(id)\n }\n return ids\n },\n catch: (err) => {\n if (err instanceof UniqueIdError) return fromUnikuError(err)\n return new CliError('GENERATE_FAILED', String(err))\n },\n })\n}\n","import * as Effect from 'effect/Effect'\nimport { UniqueIdError } from 'uniku/errors'\nimport { uuidv4 } from 'uniku/uuid/v4'\nimport { uuidv7 } from 'uniku/uuid/v7'\nimport { CliError, fromUnikuError } from '@/src/domain/errors'\n\nexport type UuidGenerateOptions = {\n readonly count: number\n readonly version: number\n readonly lowercase: boolean\n}\n\nexport function generateUuid(options: UuidGenerateOptions): Effect.Effect<string[], CliError> {\n return Effect.try({\n try: () => {\n const gen = options.version === 7 ? uuidv7 : uuidv4\n const ids: string[] = []\n for (let i = 0; i < options.count; i++) {\n let id = gen()\n if (options.lowercase) {\n id = id.toLowerCase()\n }\n ids.push(id)\n }\n return ids\n },\n catch: (err) => {\n if (err instanceof UniqueIdError) return fromUnikuError(err)\n return new CliError('GENERATE_FAILED', String(err))\n },\n })\n}\n","import * as Context from 'effect/Context'\nimport * as Effect from 'effect/Effect'\nimport { type CliError, errorToJson } from '@/src/domain/errors'\nimport type { InspectResult, ValidationResult } from '@/src/domain/types'\n\nexport type OutputOptions = {\n readonly json?: boolean\n readonly quiet?: boolean\n}\n\nexport class OutputService extends Context.Tag('OutputService')<\n OutputService,\n {\n readonly writeIds: (ids: readonly string[], options: OutputOptions) => Effect.Effect<void>\n readonly writeValidation: (results: readonly ValidationResult[], options: OutputOptions) => Effect.Effect<void>\n readonly writeInspect: (result: InspectResult, options: OutputOptions) => Effect.Effect<void>\n readonly writeError: (error: CliError, options: OutputOptions) => Effect.Effect<void>\n }\n>() {}\n\nfunction formatValidationHuman(result: ValidationResult): string {\n if (result.valid) {\n const parts = [`valid (${result.type}`]\n if (result.version != null) {\n parts.push(` v${result.version}`)\n }\n parts.push(')')\n return parts.join('')\n }\n return `invalid: ${result.error ?? 'malformed identifier'}`\n}\n\nfunction formatInspectHuman(result: InspectResult): string {\n const lines: string[] = []\n const typeLabel = result.version != null ? `${result.type} (v${result.version})` : result.type\n lines.push(`Type: ${typeLabel}`)\n if (result.timestamp) {\n lines.push(`Timestamp: ${result.timestamp}`)\n }\n if (result.random) {\n lines.push(`Random: ${result.random}`)\n }\n if (result.note) {\n lines.push(`Note: ${result.note}`)\n }\n return lines.join('\\n')\n}\n\n/**\n * Default implementation writing to process.stdout / process.stderr.\n */\nexport const OutputServiceLive = OutputService.of({\n writeIds(ids, options) {\n return Effect.sync(() => {\n if (options.json) {\n const out = ids.length === 1 ? JSON.stringify(ids[0]) : JSON.stringify(ids)\n process.stdout.write(`${out}\\n`)\n } else {\n for (const id of ids) {\n process.stdout.write(`${id}\\n`)\n }\n }\n })\n },\n\n writeValidation(results, options) {\n return Effect.sync(() => {\n if (options.quiet) return\n\n if (options.json) {\n const out = results.length === 1 ? JSON.stringify(results[0]) : JSON.stringify(results)\n process.stdout.write(`${out}\\n`)\n } else {\n for (const result of results) {\n process.stdout.write(`${formatValidationHuman(result)}\\n`)\n }\n }\n })\n },\n\n writeInspect(result, options) {\n return Effect.sync(() => {\n if (options.json) {\n process.stdout.write(`${JSON.stringify(result)}\\n`)\n } else {\n process.stdout.write(`${formatInspectHuman(result)}\\n`)\n }\n })\n },\n\n writeError(error, options) {\n return Effect.sync(() => {\n if (options.json) {\n process.stderr.write(`${JSON.stringify(errorToJson(error))}\\n`)\n } else {\n let msg = `Error: ${error.message}`\n if (error.hint) {\n msg += `\\n ${error.hint}`\n }\n process.stderr.write(`${msg}\\n`)\n }\n })\n },\n})\n","import { Command, Options } from '@effect/cli'\nimport * as Effect from 'effect/Effect'\nimport * as Option from 'effect/Option'\nimport { COUNT_DEFAULT, CUID_LENGTH_DEFAULT, NANOID_SIZE_DEFAULT, UUID_VERSION_DEFAULT } from '@/src/domain/constants'\nimport { CliError } from '@/src/domain/errors'\nimport { generateCuid } from '@/src/generators/cuid'\nimport { generateKsuid } from '@/src/generators/ksuid'\nimport { generateNanoid } from '@/src/generators/nanoid'\nimport { generateUlid } from '@/src/generators/ulid'\nimport { generateUuid } from '@/src/generators/uuid'\nimport { OutputService } from '@/src/services/OutputService'\n\n// ── Common options ──────────────────────────────────────────────────\n\nconst countOption = Options.integer('count').pipe(\n Options.withAlias('n'),\n Options.withDescription('Number of IDs to generate'),\n Options.withDefault(COUNT_DEFAULT),\n)\n\nconst jsonOption = Options.boolean('json').pipe(Options.withDescription('Output as JSON'), Options.withDefault(false))\n\n// ── UUID subcommand ─────────────────────────────────────────────────\n\nconst uuidVersionOption = Options.choiceWithValue('version', [\n ['4', 4],\n ['7', 7],\n] as const).pipe(\n Options.withAlias('v'),\n Options.withDescription('UUID version: 4, 7'),\n Options.withDefault(UUID_VERSION_DEFAULT as 4 | 7),\n)\n\nconst lowercaseOption = Options.boolean('lowercase').pipe(\n Options.withAlias('l'),\n Options.withDescription('Output in lowercase'),\n Options.withDefault(false),\n)\n\nconst uuidSubcommand = Command.make(\n 'uuid',\n {\n count: countOption,\n json: jsonOption,\n version: uuidVersionOption,\n lowercase: lowercaseOption,\n },\n ({ count, json, version, lowercase }) =>\n Effect.gen(function* () {\n const output = yield* OutputService\n const ids = yield* generateUuid({ count, version, lowercase })\n yield* output.writeIds(ids, { json })\n }),\n).pipe(Command.withDescription('Generate UUIDs (v4 or v7)'))\n\n// ── ULID subcommand ─────────────────────────────────────────────────\n\nconst monotonicOption = Options.boolean('monotonic').pipe(\n Options.withDescription('Generate monotonically increasing ULIDs'),\n Options.withDefault(false),\n)\n\nconst ulidTimestampOption = Options.text('timestamp').pipe(\n Options.withDescription('Unix timestamp in milliseconds (or \"now\")'),\n Options.optional,\n)\n\nconst ulidSubcommand = Command.make(\n 'ulid',\n {\n count: countOption,\n json: jsonOption,\n monotonic: monotonicOption,\n timestamp: ulidTimestampOption,\n lowercase: lowercaseOption,\n },\n ({ count, json, monotonic, timestamp: timestampOpt, lowercase }) =>\n Effect.gen(function* () {\n const output = yield* OutputService\n const timestamp = Option.isSome(timestampOpt) ? parseTimestampMs(Option.getOrThrow(timestampOpt)) : undefined\n const ids = yield* generateUlid({ count, monotonic, timestamp, lowercase })\n yield* output.writeIds(ids, { json })\n }),\n).pipe(Command.withDescription('Generate ULIDs'))\n\n// ── Nanoid subcommand ───────────────────────────────────────────────\n\nconst sizeOption = Options.integer('size').pipe(\n Options.withAlias('s'),\n Options.withDescription('Length of ID (1-256)'),\n Options.withDefault(NANOID_SIZE_DEFAULT),\n)\n\nconst alphabetOption = Options.text('alphabet').pipe(\n Options.withAlias('a'),\n Options.withDescription('Custom alphabet or preset: hex, numeric, alpha'),\n Options.optional,\n)\n\nconst nanoidSubcommand = Command.make(\n 'nanoid',\n {\n count: countOption,\n json: jsonOption,\n size: sizeOption,\n alphabet: alphabetOption,\n },\n ({ count, json, size, alphabet: alphabetOpt }) =>\n Effect.gen(function* () {\n const output = yield* OutputService\n const alphabet = Option.isSome(alphabetOpt) ? Option.getOrThrow(alphabetOpt) : undefined\n const ids = yield* generateNanoid({ count, size, alphabet })\n yield* output.writeIds(ids, { json })\n }),\n).pipe(Command.withDescription('Generate Nanoids'))\n\n// ── CUID subcommand ─────────────────────────────────────────────────\n\nconst lengthOption = Options.integer('length').pipe(\n Options.withAlias('l'),\n Options.withDescription('Length of ID (2-32)'),\n Options.withDefault(CUID_LENGTH_DEFAULT),\n)\n\nconst cuidSubcommand = Command.make(\n 'cuid',\n {\n count: countOption,\n json: jsonOption,\n length: lengthOption,\n },\n ({ count, json, length }) =>\n Effect.gen(function* () {\n const output = yield* OutputService\n const ids = yield* generateCuid({ count, length })\n yield* output.writeIds(ids, { json })\n }),\n).pipe(Command.withDescription('Generate CUIDs (v2)'))\n\n// ── KSUID subcommand ────────────────────────────────────────────────\n\nconst ksuidTimestampOption = Options.text('timestamp').pipe(\n Options.withDescription('Unix timestamp in seconds (or \"now\")'),\n Options.optional,\n)\n\nconst ksuidSubcommand = Command.make(\n 'ksuid',\n {\n count: countOption,\n json: jsonOption,\n timestamp: ksuidTimestampOption,\n },\n ({ count, json, timestamp: timestampOpt }) =>\n Effect.gen(function* () {\n const output = yield* OutputService\n const timestamp = Option.isSome(timestampOpt) ? parseTimestampSecs(Option.getOrThrow(timestampOpt)) : undefined\n const ids = yield* generateKsuid({ count, timestamp })\n yield* output.writeIds(ids, { json })\n }),\n).pipe(Command.withDescription('Generate KSUIDs'))\n\n// ── Generate parent command ─────────────────────────────────────────\n\nexport const generateCommand = Command.make('generate').pipe(\n Command.withDescription('Generate new IDs'),\n Command.withSubcommands([uuidSubcommand, ulidSubcommand, nanoidSubcommand, cuidSubcommand, ksuidSubcommand]),\n)\n\n// ── Shorthand commands (top-level: `uniku uuid`, `uniku ulid`, etc.) ─\n\nexport const uuidShorthand = uuidSubcommand\nexport const ulidShorthand = ulidSubcommand\nexport const nanoidShorthand = nanoidSubcommand\nexport const cuidShorthand = cuidSubcommand\nexport const ksuidShorthand = ksuidSubcommand\n\n// ── Helpers ─────────────────────────────────────────────────────────\n\nfunction parseTimestampMs(input: string): number {\n if (input === 'now') return Date.now()\n const n = Number(input)\n if (!Number.isFinite(n) || n < 0) {\n throw new CliError(\n 'INVALID_TIMESTAMP',\n `Invalid timestamp: \"${input}\"`,\n 'Provide a Unix timestamp in milliseconds or \"now\"',\n )\n }\n return n\n}\n\nfunction parseTimestampSecs(input: string): number {\n if (input === 'now') return Math.floor(Date.now() / 1000)\n const n = Number(input)\n if (!Number.isFinite(n) || n < 0) {\n throw new CliError(\n 'INVALID_TIMESTAMP',\n `Invalid timestamp: \"${input}\"`,\n 'Provide a Unix timestamp in seconds or \"now\"',\n )\n }\n return n\n}\n","import { cuid2 } from 'uniku/cuid2'\nimport { ksuid } from 'uniku/ksuid'\nimport { nanoid } from 'uniku/nanoid'\nimport { ulid } from 'uniku/ulid'\nimport { uuidv4 } from 'uniku/uuid/v4'\nimport { uuidv7 } from 'uniku/uuid/v7'\nimport type { IdType, ValidationResult } from '@/src/domain/types'\n\n/**\n * Validate a single ID against a specific type.\n */\nexport function validateAs(id: string, type: IdType): ValidationResult {\n switch (type) {\n case 'uuid':\n return validateUuid(id)\n case 'ulid':\n return validateUlid(id)\n case 'ksuid':\n return validateKsuid(id)\n case 'cuid':\n return validateCuid(id)\n case 'nanoid':\n return validateNanoid(id)\n }\n}\n\n/**\n * Auto-detect ID type and validate.\n * Detection order: UUID > ULID > KSUID > CUID > Nanoid.\n */\nexport function validateAutoDetect(id: string): ValidationResult {\n // 1. UUID (36 chars, 8-4-4-4-12 format with hyphens)\n if (uuidv7.isValid(id)) {\n return { id, valid: true, type: 'uuid', version: 7 }\n }\n if (uuidv4.isValid(id)) {\n return { id, valid: true, type: 'uuid', version: 4 }\n }\n\n // 2. ULID (26 chars, Crockford Base32)\n if (ulid.isValid(id)) {\n return { id, valid: true, type: 'ulid' }\n }\n\n // 3. KSUID (27 chars, Base62)\n if (ksuid.isValid(id)) {\n return { id, valid: true, type: 'ksuid' }\n }\n\n // 4. CUID (starts with letter, Base36)\n if (cuid2.isValid(id)) {\n return { id, valid: true, type: 'cuid' }\n }\n\n // 5. Nanoid (fallback: URL-safe A-Za-z0-9_- and length 1-256)\n if (nanoid.isValid(id)) {\n return { id, valid: true, type: 'nanoid' }\n }\n\n return { id, valid: false, error: 'malformed identifier' }\n}\n\nfunction validateUuid(id: string): ValidationResult {\n if (uuidv7.isValid(id)) {\n return { id, valid: true, type: 'uuid', version: 7 }\n }\n if (uuidv4.isValid(id)) {\n return { id, valid: true, type: 'uuid', version: 4 }\n }\n return { id, valid: false, type: 'uuid', error: 'invalid UUID format' }\n}\n\nfunction validateUlid(id: string): ValidationResult {\n if (ulid.isValid(id)) {\n return { id, valid: true, type: 'ulid' }\n }\n return { id, valid: false, type: 'ulid', error: 'invalid ULID format' }\n}\n\nfunction validateKsuid(id: string): ValidationResult {\n if (ksuid.isValid(id)) {\n return { id, valid: true, type: 'ksuid' }\n }\n return { id, valid: false, type: 'ksuid', error: 'invalid KSUID format' }\n}\n\nfunction validateCuid(id: string): ValidationResult {\n if (cuid2.isValid(id)) {\n return { id, valid: true, type: 'cuid' }\n }\n return { id, valid: false, type: 'cuid', error: 'invalid CUID format' }\n}\n\nfunction validateNanoid(id: string): ValidationResult {\n if (nanoid.isValid(id)) {\n return { id, valid: true, type: 'nanoid' }\n }\n return { id, valid: false, type: 'nanoid', error: 'invalid Nanoid format' }\n}\n","import { ksuid } from 'uniku/ksuid'\nimport { ulid } from 'uniku/ulid'\nimport { uuidv4 } from 'uniku/uuid/v4'\nimport { uuidv7 } from 'uniku/uuid/v7'\nimport type { IdType, InspectResult } from '@/src/domain/types'\nimport { validateAutoDetect } from '@/src/validators/validate'\n\n/**\n * Inspect an ID and extract metadata.\n * If type is not provided, auto-detect is used.\n */\nexport function inspectId(id: string, type?: IdType): InspectResult | null {\n const resolvedType = type ?? detectType(id)\n if (!resolvedType) return null\n\n switch (resolvedType) {\n case 'uuid':\n return inspectUuid(id)\n case 'ulid':\n return inspectUlid(id)\n case 'ksuid':\n return inspectKsuid(id)\n case 'cuid':\n return inspectCuid(id)\n case 'nanoid':\n return inspectNanoid(id)\n }\n}\n\nfunction detectType(id: string): IdType | null {\n const result = validateAutoDetect(id)\n return result.valid ? (result.type ?? null) : null\n}\n\nfunction inspectUuid(id: string): InspectResult {\n if (uuidv7.isValid(id)) {\n const ms = uuidv7.timestamp(id)\n const bytes = uuidv7.toBytes(id)\n // Random component: last 6 bytes (bytes 10-15)\n const random = Buffer.from(bytes.slice(10)).toString('hex')\n return {\n id,\n type: 'uuid',\n version: 7,\n timestamp: new Date(ms).toISOString(),\n timestamp_ms: ms,\n random,\n }\n }\n\n if (uuidv4.isValid(id)) {\n return {\n id,\n type: 'uuid',\n version: 4,\n note: 'This ID type contains no decodable metadata.',\n }\n }\n\n return {\n id,\n type: 'uuid',\n note: 'Unrecognized UUID version.',\n }\n}\n\nfunction inspectUlid(id: string): InspectResult {\n const ms = ulid.timestamp(id)\n // Random component: last 16 chars of the 26-char ULID\n const random = id.slice(10)\n return {\n id,\n type: 'ulid',\n timestamp: new Date(ms).toISOString(),\n timestamp_ms: ms,\n random,\n }\n}\n\nfunction inspectKsuid(id: string): InspectResult {\n const ms = ksuid.timestamp(id)\n const bytes = ksuid.toBytes(id)\n // Random payload: last 16 bytes (bytes 4-19)\n const random = Buffer.from(bytes.slice(4)).toString('hex')\n return {\n id,\n type: 'ksuid',\n timestamp: new Date(ms).toISOString(),\n timestamp_ms: ms,\n random,\n }\n}\n\nfunction inspectCuid(id: string): InspectResult {\n return {\n id,\n type: 'cuid',\n note: 'This ID type contains no decodable metadata.',\n }\n}\n\nfunction inspectNanoid(id: string): InspectResult {\n return {\n id,\n type: 'nanoid',\n note: 'This ID type contains no decodable metadata.',\n }\n}\n","import { Args, Command, Options } from '@effect/cli'\nimport * as Effect from 'effect/Effect'\nimport * as Option from 'effect/Option'\nimport { CliError } from '@/src/domain/errors'\nimport type { IdType } from '@/src/domain/types'\nimport { inspectId } from '@/src/inspectors/inspect'\nimport { OutputService } from '@/src/services/OutputService'\n\nconst idArg = Args.text({ name: 'id' }).pipe(Args.withDescription('The ID to inspect'))\n\nconst typeOption = Options.choice('type', ['uuid', 'ulid', 'nanoid', 'cuid', 'ksuid'] as const).pipe(\n Options.withDescription('ID type (auto-detected if omitted)'),\n Options.optional,\n)\n\nconst jsonOption = Options.boolean('json').pipe(Options.withDescription('Output as JSON'), Options.withDefault(false))\n\nexport const inspectCommand = Command.make(\n 'inspect',\n {\n id: idArg,\n type: typeOption,\n json: jsonOption,\n },\n ({ id, type: typeOpt, json }) =>\n Effect.gen(function* () {\n const output = yield* OutputService\n const type: IdType | undefined = Option.isSome(typeOpt) ? Option.getOrThrow(typeOpt) : undefined\n\n const result = inspectId(id, type)\n if (!result) {\n yield* Effect.fail(\n new CliError(\n 'UNKNOWN_ID_TYPE',\n `Could not identify ID type for: \"${id}\"`,\n 'Use --type to specify the ID type',\n ),\n )\n return\n }\n\n yield* output.writeInspect(result, { json })\n }),\n).pipe(Command.withDescription('Decode and inspect an ID'))\n","import * as Context from 'effect/Context'\nimport * as Effect from 'effect/Effect'\nimport { CliError } from '@/src/domain/errors'\n\nexport class StdinService extends Context.Tag('StdinService')<\n StdinService,\n {\n readonly readLines: () => Effect.Effect<readonly string[], CliError>\n }\n>() {}\n\n/**\n * Reads all lines from process.stdin until EOF.\n * Filters out empty lines.\n */\nexport const StdinServiceLive = StdinService.of({\n readLines() {\n return Effect.async<readonly string[], CliError>((resume) => {\n const chunks: Buffer[] = []\n\n process.stdin.on('data', (chunk: Buffer) => {\n chunks.push(chunk)\n })\n\n process.stdin.on('end', () => {\n const text = Buffer.concat(chunks).toString('utf-8')\n const lines = text\n .split('\\n')\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n resume(Effect.succeed(lines))\n })\n\n process.stdin.on('error', (err) => {\n resume(Effect.fail(new CliError('STDIN_ERROR', err.message)))\n })\n\n process.stdin.resume()\n })\n },\n})\n","import { Args, Command, Options } from '@effect/cli'\nimport * as Effect from 'effect/Effect'\nimport * as Option from 'effect/Option'\nimport { CliError, ValidationFailedError } from '@/src/domain/errors'\nimport type { IdType, ValidationResult } from '@/src/domain/types'\nimport { OutputService } from '@/src/services/OutputService'\nimport { StdinService } from '@/src/services/StdinService'\nimport { validateAs, validateAutoDetect } from '@/src/validators/validate'\n\nconst idArg = Args.text({ name: 'id' }).pipe(Args.withDescription('The ID to validate'), Args.optional)\n\nconst typeOption = Options.choice('type', ['uuid', 'ulid', 'nanoid', 'cuid', 'ksuid'] as const).pipe(\n Options.withDescription('Expected ID type (auto-detected if omitted)'),\n Options.optional,\n)\n\nconst stdinOption = Options.boolean('stdin').pipe(\n Options.withDescription('Read IDs from stdin (one per line)'),\n Options.withDefault(false),\n)\n\nconst jsonOption = Options.boolean('json').pipe(\n Options.withDescription('Output validation results as JSON'),\n Options.withDefault(false),\n)\n\nconst quietOption = Options.boolean('quiet').pipe(\n Options.withDescription('No output, exit code only'),\n Options.withDefault(false),\n)\n\nexport const validateCommand = Command.make(\n 'validate',\n {\n id: idArg,\n type: typeOption,\n stdin: stdinOption,\n json: jsonOption,\n quiet: quietOption,\n },\n ({ id: idOpt, type: typeOpt, stdin, json, quiet }) =>\n Effect.gen(function* () {\n const output = yield* OutputService\n const stdinService = yield* StdinService\n const type: IdType | undefined = Option.isSome(typeOpt) ? Option.getOrThrow(typeOpt) : undefined\n\n let ids: readonly string[]\n\n if (stdin) {\n ids = yield* stdinService.readLines()\n if (ids.length === 0) {\n yield* Effect.fail(new CliError('NO_INPUT', 'No IDs provided on stdin'))\n return\n }\n } else if (Option.isSome(idOpt)) {\n ids = [Option.getOrThrow(idOpt)]\n } else {\n yield* Effect.fail(new CliError('NO_INPUT', 'No ID provided', 'Pass an ID as argument or use --stdin'))\n return\n }\n\n const results: ValidationResult[] = ids.map((id) => (type ? validateAs(id, type) : validateAutoDetect(id)))\n\n yield* output.writeValidation(results, { json, quiet })\n\n const hasInvalid = results.some((r) => !r.valid)\n if (hasInvalid) {\n yield* Effect.fail(new ValidationFailedError('One or more IDs are invalid'))\n }\n }),\n).pipe(Command.withDescription('Check if an ID is valid'))\n","import { Command } from '@effect/cli'\nimport {\n cuidShorthand,\n generateCommand,\n ksuidShorthand,\n nanoidShorthand,\n ulidShorthand,\n uuidShorthand,\n} from '@/src/commands/generate.cmd'\nimport { inspectCommand } from '@/src/commands/inspect.cmd'\nimport { validateCommand } from '@/src/commands/validate.cmd'\n\n// ── Root command ────────────────────────────────────────────────────\n\nexport const rootCommand = Command.make('uniku').pipe(\n Command.withDescription('Generate and validate unique identifiers'),\n Command.withSubcommands([\n generateCommand,\n validateCommand,\n inspectCommand,\n // Shorthand commands: `uniku uuid` = `uniku generate uuid`\n uuidShorthand,\n ulidShorthand,\n nanoidShorthand,\n cuidShorthand,\n ksuidShorthand,\n ]),\n)\n\n// ── CLI runner (reusable for testing) ───────────────────────────────\n\nexport const makeCliRunner = (version: string) =>\n Command.run(rootCommand, {\n name: 'uniku',\n version,\n })\n","","import { BunContext, BunRuntime } from '@effect/platform-bun'\nimport * as Effect from 'effect/Effect'\nimport * as Layer from 'effect/Layer'\nimport { makeCliRunner } from '@/src/commands'\nimport { CliError } from '@/src/domain/errors'\nimport { OutputService, OutputServiceLive } from '@/src/services/OutputService'\nimport { StdinService, StdinServiceLive } from '@/src/services/StdinService'\nimport pkg from '../package.json' with { type: 'json' }\n\n// ── CLI runner ──────────────────────────────────────────────────────\n\nconst cli = makeCliRunner(pkg.version)\n\n// ── Arg preprocessing ───────────────────────────────────────────────\n\nexport function preprocessArgs(argv: readonly string[]): string[] {\n const args = [...argv]\n\n // Replace -V with --version (Effect CLI doesn't alias -V by default)\n for (let i = 2; i < args.length; i++) {\n if (args[i] === '-V') {\n args[i] = '--version'\n }\n }\n\n // If no command args beyond the executable path, inject --help\n // argv is typically: [bun, script.ts, ...userArgs]\n if (args.length <= 2) {\n args.push('--help')\n }\n\n return args\n}\n\n// ── Service layers ──────────────────────────────────────────────────\n\nconst ServicesLayer = Layer.mergeAll(\n Layer.succeed(OutputService, OutputServiceLive),\n Layer.succeed(StdinService, StdinServiceLive),\n)\n\nconst MainLayer = Layer.mergeAll(ServicesLayer, BunContext.layer)\n\n// ── Run ─────────────────────────────────────────────────────────────\n\nEffect.suspend(() => cli(preprocessArgs(process.argv))).pipe(\n // Handle our CLI errors (CliError, ValidationFailedError) — these\n // are the only non-ValidationError errors our commands can produce.\n Effect.catchAll((err) =>\n Effect.sync(() => {\n if (err instanceof CliError) {\n process.stderr.write(`Error: ${err.message}\\n`)\n if (err.hint) {\n process.stderr.write(` ${err.hint}\\n`)\n }\n process.exitCode = err.exitCode\n } else {\n // @effect/cli ValidationError variants are already handled\n // by Command.run internally (it prints help/usage).\n // This catches any remaining unexpected errors.\n process.stderr.write(`Error: ${String(err)}\\n`)\n process.exitCode = 1\n }\n }),\n ),\n Effect.provide(MainLayer),\n BunRuntime.runMain,\n)\n"],"mappings":"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"}
1
+ {"version":3,"file":"bin.mjs","names":["NANOID_ALPHABET_PRESETS: Record<string, string>","code: string","hint?: string","exitCode: number","obj: { error: string; code: string; hint?: string }","ids: string[]","ids: string[]","ids: string[]","ids: string[]","ids: string[]","lines: string[]","jsonOption","idArg","typeOption","jsonOption","chunks: Buffer[]","type: IdType | undefined","ids: readonly string[]","results: ValidationResult[]","version","updateCmd","pkg.version"],"sources":["../src/domain/constants.ts","../src/domain/errors.ts","../src/generators/cuid.ts","../src/generators/ksuid.ts","../src/generators/nanoid.ts","../src/generators/ulid.ts","../src/generators/uuid.ts","../src/services/OutputService.ts","../src/commands/generate.cmd.ts","../src/validators/validate.ts","../src/inspectors/inspect.ts","../src/commands/inspect.cmd.ts","../src/services/StdinService.ts","../src/commands/validate.cmd.ts","../src/commands/index.ts","../src/services/UpdateCheckService.ts","../package.json","../src/bin.ts"],"sourcesContent":["/** Default count for ID generation. */\nexport const COUNT_DEFAULT = 1\n\n/** Valid UUID versions. */\nexport const UUID_VERSIONS = [4, 7] as const\n\n/** Default UUID version. */\nexport const UUID_VERSION_DEFAULT = 4\n\n/** Default nanoid size. */\nexport const NANOID_SIZE_DEFAULT = 21\n\n/** Nanoid size range. */\nexport const NANOID_SIZE_MIN = 1\nexport const NANOID_SIZE_MAX = 256\n\n/** Default CUID2 length. */\nexport const CUID_LENGTH_DEFAULT = 24\n\n/** CUID2 length range. */\nexport const CUID_LENGTH_MIN = 2\nexport const CUID_LENGTH_MAX = 32\n\n/** Nanoid alphabet presets. */\nexport const NANOID_ALPHABET_PRESETS: Record<string, string> = {\n hex: '0123456789abcdef',\n numeric: '0123456789',\n alpha: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',\n}\n\n/** Environment variable for default generate type. */\nexport const ENV_DEFAULT_TYPE = 'UNIKU_DEFAULT_TYPE'\n","import type { UniqueIdError } from 'uniku/errors'\n\n/**\n * Structured CLI error with optional hint and exit code.\n */\nexport class CliError extends Error {\n constructor(\n readonly code: string,\n message: string,\n readonly hint?: string,\n readonly exitCode: number = 1,\n ) {\n super(message)\n this.name = 'CliError'\n }\n}\n\n/**\n * Error indicating validation failure (exit code 2).\n */\nexport class ValidationFailedError extends CliError {\n constructor(message: string) {\n super('VALIDATION_FAILED', message, undefined, 2)\n this.name = 'ValidationFailedError'\n }\n}\n\n/**\n * Maps a uniku library error into a CliError, preserving code and message.\n */\nexport function fromUnikuError(err: UniqueIdError): CliError {\n return new CliError(err.code, err.message)\n}\n\n/**\n * Converts a CliError to a JSON-serializable object for stderr output.\n */\nexport function errorToJson(err: CliError): { error: string; code: string; hint?: string } {\n const obj: { error: string; code: string; hint?: string } = {\n error: err.message,\n code: err.code,\n }\n if (err.hint) {\n obj.hint = err.hint\n }\n return obj\n}\n","import * as Effect from 'effect/Effect'\nimport { cuid2 } from 'uniku/cuid2'\nimport { UniqueIdError } from 'uniku/errors'\nimport { CliError, fromUnikuError } from '@/src/domain/errors'\n\nexport type CuidGenerateOptions = {\n readonly count: number\n readonly length: number\n}\n\nexport function generateCuid(options: CuidGenerateOptions): Effect.Effect<string[], CliError> {\n return Effect.try({\n try: () => {\n const ids: string[] = []\n for (let i = 0; i < options.count; i++) {\n ids.push(cuid2({ length: options.length }))\n }\n return ids\n },\n catch: (err) => {\n if (err instanceof UniqueIdError) return fromUnikuError(err)\n return new CliError('GENERATE_FAILED', String(err))\n },\n })\n}\n","import * as Effect from 'effect/Effect'\nimport { UniqueIdError } from 'uniku/errors'\nimport { ksuid } from 'uniku/ksuid'\nimport { CliError, fromUnikuError } from '@/src/domain/errors'\n\nexport type KsuidGenerateOptions = {\n readonly count: number\n readonly timestamp?: number\n}\n\nexport function generateKsuid(options: KsuidGenerateOptions): Effect.Effect<string[], CliError> {\n return Effect.try({\n try: () => {\n const ids: string[] = []\n for (let i = 0; i < options.count; i++) {\n const ksuidOpts = options.timestamp != null ? { secs: options.timestamp } : undefined\n ids.push(ksuid(ksuidOpts))\n }\n return ids\n },\n catch: (err) => {\n if (err instanceof UniqueIdError) return fromUnikuError(err)\n return new CliError('GENERATE_FAILED', String(err))\n },\n })\n}\n","import * as Effect from 'effect/Effect'\nimport { UniqueIdError } from 'uniku/errors'\nimport { nanoid } from 'uniku/nanoid'\nimport { NANOID_ALPHABET_PRESETS } from '@/src/domain/constants'\nimport { CliError, fromUnikuError } from '@/src/domain/errors'\n\nexport type NanoidGenerateOptions = {\n readonly count: number\n readonly size: number\n readonly alphabet?: string\n}\n\nfunction resolveAlphabet(input?: string): string | undefined {\n if (!input) return undefined\n return NANOID_ALPHABET_PRESETS[input] ?? input\n}\n\nexport function generateNanoid(options: NanoidGenerateOptions): Effect.Effect<string[], CliError> {\n return Effect.try({\n try: () => {\n const alphabet = resolveAlphabet(options.alphabet)\n const ids: string[] = []\n for (let i = 0; i < options.count; i++) {\n ids.push(nanoid({ size: options.size, alphabet }))\n }\n return ids\n },\n catch: (err) => {\n if (err instanceof UniqueIdError) return fromUnikuError(err)\n return new CliError('GENERATE_FAILED', String(err))\n },\n })\n}\n","import * as Effect from 'effect/Effect'\nimport { UniqueIdError } from 'uniku/errors'\nimport { ulid } from 'uniku/ulid'\nimport { CliError, fromUnikuError } from '@/src/domain/errors'\n\nexport type UlidGenerateOptions = {\n readonly count: number\n readonly monotonic: boolean\n readonly timestamp?: number\n readonly lowercase: boolean\n}\n\nexport function generateUlid(options: UlidGenerateOptions): Effect.Effect<string[], CliError> {\n if (options.monotonic && options.timestamp != null) {\n return Effect.fail(\n new CliError(\n 'INVALID_OPTIONS',\n '--monotonic and --timestamp are mutually exclusive',\n 'Use --monotonic for monotonically increasing ULIDs, or --timestamp to specify a fixed timestamp',\n ),\n )\n }\n\n return Effect.try({\n try: () => {\n const ids: string[] = []\n for (let i = 0; i < options.count; i++) {\n const ulidOpts = options.timestamp != null ? { msecs: options.timestamp } : undefined\n let id = ulid(ulidOpts)\n if (options.lowercase) {\n id = id.toLowerCase()\n }\n ids.push(id)\n }\n return ids\n },\n catch: (err) => {\n if (err instanceof UniqueIdError) return fromUnikuError(err)\n return new CliError('GENERATE_FAILED', String(err))\n },\n })\n}\n","import * as Effect from 'effect/Effect'\nimport { UniqueIdError } from 'uniku/errors'\nimport { uuidv4 } from 'uniku/uuid/v4'\nimport { uuidv7 } from 'uniku/uuid/v7'\nimport { CliError, fromUnikuError } from '@/src/domain/errors'\n\nexport type UuidGenerateOptions = {\n readonly count: number\n readonly version: number\n readonly lowercase: boolean\n}\n\nexport function generateUuid(options: UuidGenerateOptions): Effect.Effect<string[], CliError> {\n return Effect.try({\n try: () => {\n const gen = options.version === 7 ? uuidv7 : uuidv4\n const ids: string[] = []\n for (let i = 0; i < options.count; i++) {\n let id = gen()\n if (options.lowercase) {\n id = id.toLowerCase()\n }\n ids.push(id)\n }\n return ids\n },\n catch: (err) => {\n if (err instanceof UniqueIdError) return fromUnikuError(err)\n return new CliError('GENERATE_FAILED', String(err))\n },\n })\n}\n","import * as Context from 'effect/Context'\nimport * as Effect from 'effect/Effect'\nimport { type CliError, errorToJson } from '@/src/domain/errors'\nimport type { InspectResult, ValidationResult } from '@/src/domain/types'\n\nexport type OutputOptions = {\n readonly json?: boolean\n readonly quiet?: boolean\n}\n\nexport class OutputService extends Context.Tag('OutputService')<\n OutputService,\n {\n readonly writeIds: (ids: readonly string[], options: OutputOptions) => Effect.Effect<void>\n readonly writeValidation: (results: readonly ValidationResult[], options: OutputOptions) => Effect.Effect<void>\n readonly writeInspect: (result: InspectResult, options: OutputOptions) => Effect.Effect<void>\n readonly writeError: (error: CliError, options: OutputOptions) => Effect.Effect<void>\n }\n>() {}\n\nfunction formatValidationHuman(result: ValidationResult): string {\n if (result.valid) {\n const parts = [`valid (${result.type}`]\n if (result.version != null) {\n parts.push(` v${result.version}`)\n }\n parts.push(')')\n return parts.join('')\n }\n return `invalid: ${result.error ?? 'malformed identifier'}`\n}\n\nfunction formatInspectHuman(result: InspectResult): string {\n const lines: string[] = []\n const typeLabel = result.version != null ? `${result.type} (v${result.version})` : result.type\n lines.push(`Type: ${typeLabel}`)\n if (result.timestamp) {\n lines.push(`Timestamp: ${result.timestamp}`)\n }\n if (result.random) {\n lines.push(`Random: ${result.random}`)\n }\n if (result.note) {\n lines.push(`Note: ${result.note}`)\n }\n return lines.join('\\n')\n}\n\n/**\n * Default implementation writing to process.stdout / process.stderr.\n */\nexport const OutputServiceLive = OutputService.of({\n writeIds(ids, options) {\n return Effect.sync(() => {\n if (options.json) {\n const out = ids.length === 1 ? JSON.stringify(ids[0]) : JSON.stringify(ids)\n process.stdout.write(`${out}\\n`)\n } else {\n for (const id of ids) {\n process.stdout.write(`${id}\\n`)\n }\n }\n })\n },\n\n writeValidation(results, options) {\n return Effect.sync(() => {\n if (options.quiet) return\n\n if (options.json) {\n const out = results.length === 1 ? JSON.stringify(results[0]) : JSON.stringify(results)\n process.stdout.write(`${out}\\n`)\n } else {\n for (const result of results) {\n process.stdout.write(`${formatValidationHuman(result)}\\n`)\n }\n }\n })\n },\n\n writeInspect(result, options) {\n return Effect.sync(() => {\n if (options.json) {\n process.stdout.write(`${JSON.stringify(result)}\\n`)\n } else {\n process.stdout.write(`${formatInspectHuman(result)}\\n`)\n }\n })\n },\n\n writeError(error, options) {\n return Effect.sync(() => {\n if (options.json) {\n process.stderr.write(`${JSON.stringify(errorToJson(error))}\\n`)\n } else {\n let msg = `Error: ${error.message}`\n if (error.hint) {\n msg += `\\n ${error.hint}`\n }\n process.stderr.write(`${msg}\\n`)\n }\n })\n },\n})\n","import { Command, Options } from '@effect/cli'\nimport * as Effect from 'effect/Effect'\nimport * as Option from 'effect/Option'\nimport { COUNT_DEFAULT, CUID_LENGTH_DEFAULT, NANOID_SIZE_DEFAULT, UUID_VERSION_DEFAULT } from '@/src/domain/constants'\nimport { CliError } from '@/src/domain/errors'\nimport { generateCuid } from '@/src/generators/cuid'\nimport { generateKsuid } from '@/src/generators/ksuid'\nimport { generateNanoid } from '@/src/generators/nanoid'\nimport { generateUlid } from '@/src/generators/ulid'\nimport { generateUuid } from '@/src/generators/uuid'\nimport { OutputService } from '@/src/services/OutputService'\n\n// ── Common options ──────────────────────────────────────────────────\n\nconst countOption = Options.integer('count').pipe(\n Options.withAlias('n'),\n Options.withDescription('Number of IDs to generate'),\n Options.withDefault(COUNT_DEFAULT),\n)\n\nconst jsonOption = Options.boolean('json').pipe(Options.withDescription('Output as JSON'), Options.withDefault(false))\n\n// ── UUID subcommand ─────────────────────────────────────────────────\n\nconst uuidVersionOption = Options.choiceWithValue('version', [\n ['4', 4],\n ['7', 7],\n] as const).pipe(\n Options.withAlias('v'),\n Options.withDescription('UUID version: 4, 7'),\n Options.withDefault(UUID_VERSION_DEFAULT as 4 | 7),\n)\n\nconst lowercaseOption = Options.boolean('lowercase').pipe(\n Options.withAlias('l'),\n Options.withDescription('Output in lowercase'),\n Options.withDefault(false),\n)\n\nconst uuidSubcommand = Command.make(\n 'uuid',\n {\n count: countOption,\n json: jsonOption,\n version: uuidVersionOption,\n lowercase: lowercaseOption,\n },\n ({ count, json, version, lowercase }) =>\n Effect.gen(function* () {\n const output = yield* OutputService\n const ids = yield* generateUuid({ count, version, lowercase })\n yield* output.writeIds(ids, { json })\n }),\n).pipe(Command.withDescription('Generate UUIDs (v4 or v7)'))\n\n// ── ULID subcommand ─────────────────────────────────────────────────\n\nconst monotonicOption = Options.boolean('monotonic').pipe(\n Options.withDescription('Generate monotonically increasing ULIDs'),\n Options.withDefault(false),\n)\n\nconst ulidTimestampOption = Options.text('timestamp').pipe(\n Options.withDescription('Unix timestamp in milliseconds (or \"now\")'),\n Options.optional,\n)\n\nconst ulidSubcommand = Command.make(\n 'ulid',\n {\n count: countOption,\n json: jsonOption,\n monotonic: monotonicOption,\n timestamp: ulidTimestampOption,\n lowercase: lowercaseOption,\n },\n ({ count, json, monotonic, timestamp: timestampOpt, lowercase }) =>\n Effect.gen(function* () {\n const output = yield* OutputService\n const timestamp = Option.isSome(timestampOpt) ? parseTimestampMs(Option.getOrThrow(timestampOpt)) : undefined\n const ids = yield* generateUlid({ count, monotonic, timestamp, lowercase })\n yield* output.writeIds(ids, { json })\n }),\n).pipe(Command.withDescription('Generate ULIDs'))\n\n// ── Nanoid subcommand ───────────────────────────────────────────────\n\nconst sizeOption = Options.integer('size').pipe(\n Options.withAlias('s'),\n Options.withDescription('Length of ID (1-256)'),\n Options.withDefault(NANOID_SIZE_DEFAULT),\n)\n\nconst alphabetOption = Options.text('alphabet').pipe(\n Options.withAlias('a'),\n Options.withDescription('Custom alphabet or preset: hex, numeric, alpha'),\n Options.optional,\n)\n\nconst nanoidSubcommand = Command.make(\n 'nanoid',\n {\n count: countOption,\n json: jsonOption,\n size: sizeOption,\n alphabet: alphabetOption,\n },\n ({ count, json, size, alphabet: alphabetOpt }) =>\n Effect.gen(function* () {\n const output = yield* OutputService\n const alphabet = Option.isSome(alphabetOpt) ? Option.getOrThrow(alphabetOpt) : undefined\n const ids = yield* generateNanoid({ count, size, alphabet })\n yield* output.writeIds(ids, { json })\n }),\n).pipe(Command.withDescription('Generate Nanoids'))\n\n// ── CUID subcommand ─────────────────────────────────────────────────\n\nconst lengthOption = Options.integer('length').pipe(\n Options.withAlias('l'),\n Options.withDescription('Length of ID (2-32)'),\n Options.withDefault(CUID_LENGTH_DEFAULT),\n)\n\nconst cuidSubcommand = Command.make(\n 'cuid',\n {\n count: countOption,\n json: jsonOption,\n length: lengthOption,\n },\n ({ count, json, length }) =>\n Effect.gen(function* () {\n const output = yield* OutputService\n const ids = yield* generateCuid({ count, length })\n yield* output.writeIds(ids, { json })\n }),\n).pipe(Command.withDescription('Generate CUIDs (v2)'))\n\n// ── KSUID subcommand ────────────────────────────────────────────────\n\nconst ksuidTimestampOption = Options.text('timestamp').pipe(\n Options.withDescription('Unix timestamp in seconds (or \"now\")'),\n Options.optional,\n)\n\nconst ksuidSubcommand = Command.make(\n 'ksuid',\n {\n count: countOption,\n json: jsonOption,\n timestamp: ksuidTimestampOption,\n },\n ({ count, json, timestamp: timestampOpt }) =>\n Effect.gen(function* () {\n const output = yield* OutputService\n const timestamp = Option.isSome(timestampOpt) ? parseTimestampSecs(Option.getOrThrow(timestampOpt)) : undefined\n const ids = yield* generateKsuid({ count, timestamp })\n yield* output.writeIds(ids, { json })\n }),\n).pipe(Command.withDescription('Generate KSUIDs'))\n\n// ── Generate parent command ─────────────────────────────────────────\n\nexport const generateCommand = Command.make('generate').pipe(\n Command.withDescription('Generate new IDs'),\n Command.withSubcommands([uuidSubcommand, ulidSubcommand, nanoidSubcommand, cuidSubcommand, ksuidSubcommand]),\n)\n\n// ── Shorthand commands (top-level: `uniku uuid`, `uniku ulid`, etc.) ─\n\nexport const uuidShorthand = uuidSubcommand\nexport const ulidShorthand = ulidSubcommand\nexport const nanoidShorthand = nanoidSubcommand\nexport const cuidShorthand = cuidSubcommand\nexport const ksuidShorthand = ksuidSubcommand\n\n// ── Helpers ─────────────────────────────────────────────────────────\n\nfunction parseTimestampMs(input: string): number {\n if (input === 'now') return Date.now()\n const n = Number(input)\n if (!Number.isFinite(n) || n < 0) {\n throw new CliError(\n 'INVALID_TIMESTAMP',\n `Invalid timestamp: \"${input}\"`,\n 'Provide a Unix timestamp in milliseconds or \"now\"',\n )\n }\n return n\n}\n\nfunction parseTimestampSecs(input: string): number {\n if (input === 'now') return Math.floor(Date.now() / 1000)\n const n = Number(input)\n if (!Number.isFinite(n) || n < 0) {\n throw new CliError(\n 'INVALID_TIMESTAMP',\n `Invalid timestamp: \"${input}\"`,\n 'Provide a Unix timestamp in seconds or \"now\"',\n )\n }\n return n\n}\n","import { cuid2 } from 'uniku/cuid2'\nimport { ksuid } from 'uniku/ksuid'\nimport { nanoid } from 'uniku/nanoid'\nimport { ulid } from 'uniku/ulid'\nimport { uuidv4 } from 'uniku/uuid/v4'\nimport { uuidv7 } from 'uniku/uuid/v7'\nimport type { IdType, ValidationResult } from '@/src/domain/types'\n\n/**\n * Validate a single ID against a specific type.\n */\nexport function validateAs(id: string, type: IdType): ValidationResult {\n switch (type) {\n case 'uuid':\n return validateUuid(id)\n case 'ulid':\n return validateUlid(id)\n case 'ksuid':\n return validateKsuid(id)\n case 'cuid':\n return validateCuid(id)\n case 'nanoid':\n return validateNanoid(id)\n }\n}\n\n/**\n * Auto-detect ID type and validate.\n * Detection order: UUID > ULID > KSUID > CUID > Nanoid.\n */\nexport function validateAutoDetect(id: string): ValidationResult {\n // 1. UUID (36 chars, 8-4-4-4-12 format with hyphens)\n if (uuidv7.isValid(id)) {\n return { id, valid: true, type: 'uuid', version: 7 }\n }\n if (uuidv4.isValid(id)) {\n return { id, valid: true, type: 'uuid', version: 4 }\n }\n\n // 2. ULID (26 chars, Crockford Base32)\n if (ulid.isValid(id)) {\n return { id, valid: true, type: 'ulid' }\n }\n\n // 3. KSUID (27 chars, Base62)\n if (ksuid.isValid(id)) {\n return { id, valid: true, type: 'ksuid' }\n }\n\n // 4. CUID (starts with letter, Base36)\n if (cuid2.isValid(id)) {\n return { id, valid: true, type: 'cuid' }\n }\n\n // 5. Nanoid (fallback: URL-safe A-Za-z0-9_- and length 1-256)\n if (nanoid.isValid(id)) {\n return { id, valid: true, type: 'nanoid' }\n }\n\n return { id, valid: false, error: 'malformed identifier' }\n}\n\nfunction validateUuid(id: string): ValidationResult {\n if (uuidv7.isValid(id)) {\n return { id, valid: true, type: 'uuid', version: 7 }\n }\n if (uuidv4.isValid(id)) {\n return { id, valid: true, type: 'uuid', version: 4 }\n }\n return { id, valid: false, type: 'uuid', error: 'invalid UUID format' }\n}\n\nfunction validateUlid(id: string): ValidationResult {\n if (ulid.isValid(id)) {\n return { id, valid: true, type: 'ulid' }\n }\n return { id, valid: false, type: 'ulid', error: 'invalid ULID format' }\n}\n\nfunction validateKsuid(id: string): ValidationResult {\n if (ksuid.isValid(id)) {\n return { id, valid: true, type: 'ksuid' }\n }\n return { id, valid: false, type: 'ksuid', error: 'invalid KSUID format' }\n}\n\nfunction validateCuid(id: string): ValidationResult {\n if (cuid2.isValid(id)) {\n return { id, valid: true, type: 'cuid' }\n }\n return { id, valid: false, type: 'cuid', error: 'invalid CUID format' }\n}\n\nfunction validateNanoid(id: string): ValidationResult {\n if (nanoid.isValid(id)) {\n return { id, valid: true, type: 'nanoid' }\n }\n return { id, valid: false, type: 'nanoid', error: 'invalid Nanoid format' }\n}\n","import { ksuid } from 'uniku/ksuid'\nimport { ulid } from 'uniku/ulid'\nimport { uuidv4 } from 'uniku/uuid/v4'\nimport { uuidv7 } from 'uniku/uuid/v7'\nimport type { IdType, InspectResult } from '@/src/domain/types'\nimport { validateAutoDetect } from '@/src/validators/validate'\n\n/**\n * Inspect an ID and extract metadata.\n * If type is not provided, auto-detect is used.\n */\nexport function inspectId(id: string, type?: IdType): InspectResult | null {\n const resolvedType = type ?? detectType(id)\n if (!resolvedType) return null\n\n switch (resolvedType) {\n case 'uuid':\n return inspectUuid(id)\n case 'ulid':\n return inspectUlid(id)\n case 'ksuid':\n return inspectKsuid(id)\n case 'cuid':\n return inspectCuid(id)\n case 'nanoid':\n return inspectNanoid(id)\n }\n}\n\nfunction detectType(id: string): IdType | null {\n const result = validateAutoDetect(id)\n return result.valid ? (result.type ?? null) : null\n}\n\nfunction inspectUuid(id: string): InspectResult {\n if (uuidv7.isValid(id)) {\n const ms = uuidv7.timestamp(id)\n const bytes = uuidv7.toBytes(id)\n // Random component: last 6 bytes (bytes 10-15)\n const random = Buffer.from(bytes.slice(10)).toString('hex')\n return {\n id,\n type: 'uuid',\n version: 7,\n timestamp: new Date(ms).toISOString(),\n timestamp_ms: ms,\n random,\n }\n }\n\n if (uuidv4.isValid(id)) {\n return {\n id,\n type: 'uuid',\n version: 4,\n note: 'This ID type contains no decodable metadata.',\n }\n }\n\n return {\n id,\n type: 'uuid',\n note: 'Unrecognized UUID version.',\n }\n}\n\nfunction inspectUlid(id: string): InspectResult {\n const ms = ulid.timestamp(id)\n // Random component: last 16 chars of the 26-char ULID\n const random = id.slice(10)\n return {\n id,\n type: 'ulid',\n timestamp: new Date(ms).toISOString(),\n timestamp_ms: ms,\n random,\n }\n}\n\nfunction inspectKsuid(id: string): InspectResult {\n const ms = ksuid.timestamp(id)\n const bytes = ksuid.toBytes(id)\n // Random payload: last 16 bytes (bytes 4-19)\n const random = Buffer.from(bytes.slice(4)).toString('hex')\n return {\n id,\n type: 'ksuid',\n timestamp: new Date(ms).toISOString(),\n timestamp_ms: ms,\n random,\n }\n}\n\nfunction inspectCuid(id: string): InspectResult {\n return {\n id,\n type: 'cuid',\n note: 'This ID type contains no decodable metadata.',\n }\n}\n\nfunction inspectNanoid(id: string): InspectResult {\n return {\n id,\n type: 'nanoid',\n note: 'This ID type contains no decodable metadata.',\n }\n}\n","import { Args, Command, Options } from '@effect/cli'\nimport * as Effect from 'effect/Effect'\nimport * as Option from 'effect/Option'\nimport { CliError } from '@/src/domain/errors'\nimport type { IdType } from '@/src/domain/types'\nimport { inspectId } from '@/src/inspectors/inspect'\nimport { OutputService } from '@/src/services/OutputService'\n\nconst idArg = Args.text({ name: 'id' }).pipe(Args.withDescription('The ID to inspect'))\n\nconst typeOption = Options.choice('type', ['uuid', 'ulid', 'nanoid', 'cuid', 'ksuid'] as const).pipe(\n Options.withDescription('ID type (auto-detected if omitted)'),\n Options.optional,\n)\n\nconst jsonOption = Options.boolean('json').pipe(Options.withDescription('Output as JSON'), Options.withDefault(false))\n\nexport const inspectCommand = Command.make(\n 'inspect',\n {\n id: idArg,\n type: typeOption,\n json: jsonOption,\n },\n ({ id, type: typeOpt, json }) =>\n Effect.gen(function* () {\n const output = yield* OutputService\n const type: IdType | undefined = Option.isSome(typeOpt) ? Option.getOrThrow(typeOpt) : undefined\n\n const result = inspectId(id, type)\n if (!result) {\n yield* Effect.fail(\n new CliError(\n 'UNKNOWN_ID_TYPE',\n `Could not identify ID type for: \"${id}\"`,\n 'Use --type to specify the ID type',\n ),\n )\n return\n }\n\n yield* output.writeInspect(result, { json })\n }),\n).pipe(Command.withDescription('Decode and inspect an ID'))\n","import * as Context from 'effect/Context'\nimport * as Effect from 'effect/Effect'\nimport { CliError } from '@/src/domain/errors'\n\nexport class StdinService extends Context.Tag('StdinService')<\n StdinService,\n {\n readonly readLines: () => Effect.Effect<readonly string[], CliError>\n }\n>() {}\n\n/**\n * Reads all lines from process.stdin until EOF.\n * Filters out empty lines.\n */\nexport const StdinServiceLive = StdinService.of({\n readLines() {\n return Effect.async<readonly string[], CliError>((resume) => {\n const chunks: Buffer[] = []\n\n process.stdin.on('data', (chunk: Buffer) => {\n chunks.push(chunk)\n })\n\n process.stdin.on('end', () => {\n const text = Buffer.concat(chunks).toString('utf-8')\n const lines = text\n .split('\\n')\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n resume(Effect.succeed(lines))\n })\n\n process.stdin.on('error', (err) => {\n resume(Effect.fail(new CliError('STDIN_ERROR', err.message)))\n })\n\n process.stdin.resume()\n })\n },\n})\n","import { Args, Command, Options } from '@effect/cli'\nimport * as Effect from 'effect/Effect'\nimport * as Option from 'effect/Option'\nimport { CliError, ValidationFailedError } from '@/src/domain/errors'\nimport type { IdType, ValidationResult } from '@/src/domain/types'\nimport { OutputService } from '@/src/services/OutputService'\nimport { StdinService } from '@/src/services/StdinService'\nimport { validateAs, validateAutoDetect } from '@/src/validators/validate'\n\nconst idArg = Args.text({ name: 'id' }).pipe(Args.withDescription('The ID to validate'), Args.optional)\n\nconst typeOption = Options.choice('type', ['uuid', 'ulid', 'nanoid', 'cuid', 'ksuid'] as const).pipe(\n Options.withDescription('Expected ID type (auto-detected if omitted)'),\n Options.optional,\n)\n\nconst stdinOption = Options.boolean('stdin').pipe(\n Options.withDescription('Read IDs from stdin (one per line)'),\n Options.withDefault(false),\n)\n\nconst jsonOption = Options.boolean('json').pipe(\n Options.withDescription('Output validation results as JSON'),\n Options.withDefault(false),\n)\n\nconst quietOption = Options.boolean('quiet').pipe(\n Options.withDescription('No output, exit code only'),\n Options.withDefault(false),\n)\n\nexport const validateCommand = Command.make(\n 'validate',\n {\n id: idArg,\n type: typeOption,\n stdin: stdinOption,\n json: jsonOption,\n quiet: quietOption,\n },\n ({ id: idOpt, type: typeOpt, stdin, json, quiet }) =>\n Effect.gen(function* () {\n const output = yield* OutputService\n const stdinService = yield* StdinService\n const type: IdType | undefined = Option.isSome(typeOpt) ? Option.getOrThrow(typeOpt) : undefined\n\n let ids: readonly string[]\n\n if (stdin) {\n ids = yield* stdinService.readLines()\n if (ids.length === 0) {\n yield* Effect.fail(new CliError('NO_INPUT', 'No IDs provided on stdin'))\n return\n }\n } else if (Option.isSome(idOpt)) {\n ids = [Option.getOrThrow(idOpt)]\n } else {\n yield* Effect.fail(new CliError('NO_INPUT', 'No ID provided', 'Pass an ID as argument or use --stdin'))\n return\n }\n\n const results: ValidationResult[] = ids.map((id) => (type ? validateAs(id, type) : validateAutoDetect(id)))\n\n yield* output.writeValidation(results, { json, quiet })\n\n const hasInvalid = results.some((r) => !r.valid)\n if (hasInvalid) {\n yield* Effect.fail(new ValidationFailedError('One or more IDs are invalid'))\n }\n }),\n).pipe(Command.withDescription('Check if an ID is valid'))\n","import { Command } from '@effect/cli'\nimport {\n cuidShorthand,\n generateCommand,\n ksuidShorthand,\n nanoidShorthand,\n ulidShorthand,\n uuidShorthand,\n} from '@/src/commands/generate.cmd'\nimport { inspectCommand } from '@/src/commands/inspect.cmd'\nimport { validateCommand } from '@/src/commands/validate.cmd'\n\n// ── Root command ────────────────────────────────────────────────────\n\nexport const rootCommand = Command.make('uniku').pipe(\n Command.withDescription('Generate and validate unique identifiers'),\n Command.withSubcommands([\n generateCommand,\n validateCommand,\n inspectCommand,\n // Shorthand commands: `uniku uuid` = `uniku generate uuid`\n uuidShorthand,\n ulidShorthand,\n nanoidShorthand,\n cuidShorthand,\n ksuidShorthand,\n ]),\n)\n\n// ── CLI runner (reusable for testing) ───────────────────────────────\n\nexport const makeCliRunner = (version: string) =>\n Command.run(rootCommand, {\n name: 'uniku',\n version,\n })\n","import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs'\nimport { tmpdir } from 'node:os'\nimport { dirname, join } from 'node:path'\nimport * as Context from 'effect/Context'\nimport * as Effect from 'effect/Effect'\nimport * as Option from 'effect/Option'\n\n// ── Types ────────────────────────────────────────────────────────────\n\nexport interface UpdateInfo {\n readonly currentVersion: string\n readonly latestVersion: string\n readonly isStandaloneBinary: boolean\n}\n\ninterface UpdateCache {\n readonly latestVersion: string\n readonly checkedAt: number\n}\n\n// ── Service tag ──────────────────────────────────────────────────────\n\nexport class UpdateCheckService extends Context.Tag('UpdateCheckService')<\n UpdateCheckService,\n {\n /** Check for available updates. Returns Some(info) if update available, None otherwise. */\n readonly check: (currentVersion: string) => Effect.Effect<Option.Option<UpdateInfo>>\n /** Print the update notification to stderr. */\n readonly notify: (info: UpdateInfo) => Effect.Effect<void>\n }\n>() {}\n\n// ── Constants ────────────────────────────────────────────────────────\n\nconst PACKAGE_NAME = '@uniku/cli'\nconst REGISTRY_URL = `https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}/latest`\nconst CACHE_FILE = join(tmpdir(), 'uniku-update-check.json')\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000 // 24 hours\nconst FETCH_TIMEOUT_MS = 5_000\n\n// ── Version comparison ───────────────────────────────────────────────\n\n/**\n * Parse a semver version string into its components.\n * Returns null if the string is not a valid semver.\n */\nexport function parseSemver(version: string) {\n const match = version.match(/^v?(\\d+)\\.(\\d+)\\.(\\d+)(?:-(.+))?$/)\n if (!match) return null\n return {\n major: Number(match[1]),\n minor: Number(match[2]),\n patch: Number(match[3]),\n prerelease: match[4] ?? null,\n }\n}\n\n/**\n * Returns true if `latest` is newer than `current`.\n *\n * Handles pre-release correctly:\n * - 1.0.0 > 1.0.0-beta.1 (stable is newer than pre-release of same version)\n * - 1.0.0-beta.1 > 0.9.0 (pre-release of higher version is newer)\n */\nexport function isNewerVersion(latest: string, current: string): boolean {\n const l = parseSemver(latest)\n const c = parseSemver(current)\n if (!l || !c) return false\n\n if (l.major !== c.major) return l.major > c.major\n if (l.minor !== c.minor) return l.minor > c.minor\n if (l.patch !== c.patch) return l.patch > c.patch\n\n // Same major.minor.patch — stable (no prerelease) beats pre-release\n if (l.prerelease === null && c.prerelease !== null) return true\n if (l.prerelease !== null && c.prerelease === null) return false\n\n return false\n}\n\n// ── Skip conditions ──────────────────────────────────────────────────\n\nexport function shouldSkipUpdateCheck(): boolean {\n return (\n !!process.env.NO_UPDATE_NOTIFIER ||\n !!process.env.CI ||\n !!process.env.CONTINUOUS_INTEGRATION ||\n process.env.NODE_ENV === 'test' ||\n !process.stderr.isTTY\n )\n}\n\n// ── Notification formatting ──────────────────────────────────────────\n\nexport function formatNotification(info: UpdateInfo): string {\n const noColor = !!process.env.NO_COLOR\n\n if (noColor) {\n const updateCmd = info.isStandaloneBinary\n ? `Download at https://github.com/jkomyno/uniku/releases`\n : `Run \\`npm install -g ${PACKAGE_NAME}\\` to update`\n return [\n '',\n ` Update available: ${info.currentVersion} → ${info.latestVersion}`,\n ` ${updateCmd}`,\n ` Set NO_UPDATE_NOTIFIER=1 to disable`,\n '',\n ].join('\\n')\n }\n\n const dim = '\\x1b[2m'\n const cyan = '\\x1b[36m'\n const boldCyan = '\\x1b[1;36m'\n const reset = '\\x1b[0m'\n\n const updateCmd = info.isStandaloneBinary\n ? `Download at ${cyan}https://github.com/jkomyno/uniku/releases${reset}`\n : `Run ${cyan}\\`npm install -g ${PACKAGE_NAME}\\`${reset} to update`\n\n return [\n '',\n ` ${dim}Update available:${reset} ${dim}${info.currentVersion}${reset} ${dim}→${reset} ${boldCyan}${info.latestVersion}${reset}`,\n ` ${updateCmd}`,\n ` ${dim}Set NO_UPDATE_NOTIFIER=1 to disable${reset}`,\n '',\n ].join('\\n')\n}\n\n// ── Cache helpers (plain Node.js — maximally resilient) ──────────────\n\nfunction readCache(): UpdateCache | null {\n try {\n if (!existsSync(CACHE_FILE)) return null\n const content = readFileSync(CACHE_FILE, 'utf-8')\n return JSON.parse(content) as UpdateCache\n } catch {\n return null\n }\n}\n\nfunction writeCache(cache: UpdateCache): void {\n try {\n const dir = dirname(CACHE_FILE)\n mkdirSync(dir, { recursive: true })\n const tmpPath = `${CACHE_FILE}.tmp`\n writeFileSync(tmpPath, JSON.stringify(cache))\n renameSync(tmpPath, CACHE_FILE)\n } catch {\n // Silently ignore write errors\n }\n}\n\n// ── Registry fetch ───────────────────────────────────────────────────\n\nfunction fetchLatestVersion(currentVersion: string): Effect.Effect<string | null> {\n return Effect.tryPromise({\n try: (signal) =>\n fetch(REGISTRY_URL, {\n headers: {\n Accept: 'application/json',\n 'User-Agent': `${PACKAGE_NAME}/${currentVersion}`,\n },\n signal: AbortSignal.any([signal, AbortSignal.timeout(FETCH_TIMEOUT_MS)]),\n }).then(async (res) => {\n if (!res.ok) throw new Error(`HTTP ${res.status}`)\n const data = (await res.json()) as { version?: string }\n if (!data.version) throw new Error('Missing version field')\n return data.version\n }),\n catch: () => new Error('fetch failed'),\n }).pipe(Effect.catchAll(() => Effect.succeed(null)))\n}\n\n// ── Standalone binary detection ──────────────────────────────────────\n\ndeclare const __STANDALONE_BINARY__: boolean | undefined\n\nfunction isStandaloneBinary(): boolean {\n try {\n return typeof __STANDALONE_BINARY__ !== 'undefined' && __STANDALONE_BINARY__ === true\n } catch {\n return false\n }\n}\n\n// ── Live implementation ──────────────────────────────────────────────\n\nexport const UpdateCheckServiceLive = UpdateCheckService.of({\n check(currentVersion) {\n return Effect.gen(function* () {\n if (shouldSkipUpdateCheck()) {\n return Option.none()\n }\n\n const cached = readCache()\n const now = Date.now()\n\n // Cache is fresh — use cached result\n if (cached && now - cached.checkedAt < CACHE_TTL_MS) {\n if (isNewerVersion(cached.latestVersion, currentVersion)) {\n return Option.some<UpdateInfo>({\n currentVersion,\n latestVersion: cached.latestVersion,\n isStandaloneBinary: isStandaloneBinary(),\n })\n }\n return Option.none()\n }\n\n // Cache is stale or missing — fetch from registry\n const latestVersion = yield* fetchLatestVersion(currentVersion)\n\n if (latestVersion === null) {\n return Option.none()\n }\n\n writeCache({ latestVersion, checkedAt: now })\n\n if (isNewerVersion(latestVersion, currentVersion)) {\n return Option.some<UpdateInfo>({\n currentVersion,\n latestVersion,\n isStandaloneBinary: isStandaloneBinary(),\n })\n }\n\n return Option.none()\n }).pipe(Effect.catchAll(() => Effect.succeed(Option.none())))\n },\n\n notify(info) {\n return Effect.sync(() => {\n process.stderr.write(formatNotification(info))\n })\n },\n})\n","","import { BunContext, BunRuntime } from '@effect/platform-bun'\nimport * as Duration from 'effect/Duration'\nimport * as Effect from 'effect/Effect'\nimport * as Fiber from 'effect/Fiber'\nimport * as Layer from 'effect/Layer'\nimport * as Option from 'effect/Option'\nimport { makeCliRunner } from '@/src/commands'\nimport { CliError } from '@/src/domain/errors'\nimport { OutputService, OutputServiceLive } from '@/src/services/OutputService'\nimport { StdinService, StdinServiceLive } from '@/src/services/StdinService'\nimport { UpdateCheckService, UpdateCheckServiceLive } from '@/src/services/UpdateCheckService'\nimport pkg from '../package.json' with { type: 'json' }\n\n// ── CLI runner ──────────────────────────────────────────────────────\n\nconst cli = makeCliRunner(pkg.version)\n\n// ── Arg preprocessing ───────────────────────────────────────────────\n\nexport function preprocessArgs(argv: readonly string[]): string[] {\n const args = [...argv]\n\n // Replace -V with --version (Effect CLI doesn't alias -V by default)\n for (let i = 2; i < args.length; i++) {\n if (args[i] === '-V') {\n args[i] = '--version'\n }\n }\n\n // If no command args beyond the executable path, inject --help\n // argv is typically: [bun, script.ts, ...userArgs]\n if (args.length <= 2) {\n args.push('--help')\n }\n\n return args\n}\n\n// ── Service layers ──────────────────────────────────────────────────\n\nconst ServicesLayer = Layer.mergeAll(\n Layer.succeed(OutputService, OutputServiceLive),\n Layer.succeed(StdinService, StdinServiceLive),\n Layer.succeed(UpdateCheckService, UpdateCheckServiceLive),\n)\n\nconst MainLayer = Layer.mergeAll(ServicesLayer, BunContext.layer)\n\n// ── Run ─────────────────────────────────────────────────────────────\n\nconst program = Effect.gen(function* () {\n const updateCheck = yield* UpdateCheckService\n const args = preprocessArgs(process.argv)\n\n // Fork update check as a background fiber\n const fiber = yield* Effect.fork(updateCheck.check(pkg.version))\n\n // Run the main CLI command\n yield* Effect.suspend(() => cli(args)).pipe(\n Effect.catchAll((err) =>\n Effect.sync(() => {\n if (err instanceof CliError) {\n process.stderr.write(`Error: ${err.message}\\n`)\n if (err.hint) {\n process.stderr.write(` ${err.hint}\\n`)\n }\n process.exitCode = err.exitCode\n } else {\n process.stderr.write(`Error: ${String(err)}\\n`)\n process.exitCode = 1\n }\n }),\n ),\n )\n\n // After main command, join fiber with timeout\n const result = yield* Fiber.join(fiber).pipe(\n Effect.timeout(Duration.seconds(5)),\n Effect.catchAll(() => Effect.succeed(Option.none())),\n )\n\n // Show notification unless --json is active\n if (Option.isSome(result) && !args.includes('--json')) {\n yield* updateCheck.notify(result.value)\n }\n})\n\nprogram.pipe(Effect.provide(MainLayer), BunRuntime.runMain)\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@uniku/cli",
4
- "version": "0.0.11",
4
+ "version": "0.0.12",
5
5
  "description": "CLI tool for generating and validating unique identifiers",
6
6
  "author": {
7
7
  "name": "Alberto Schiabel",
@@ -26,25 +26,25 @@
26
26
  "build",
27
27
  "README.md"
28
28
  ],
29
- "scripts": {
30
- "clean": "rimraf build .turbo",
31
- "build": "tsdown --config-loader unrun",
32
- "build:binary": "bun scripts/build-binary.ts",
33
- "install:binary": "bun scripts/install-binary.ts",
34
- "typecheck": "tsc --noEmit",
35
- "test": "vitest run",
36
- "test:watch": "vitest"
37
- },
38
29
  "dependencies": {
39
30
  "effect": "3.19.16",
40
31
  "@effect/cli": "0.73.2",
41
32
  "@effect/platform": "0.94.3",
42
33
  "@effect/platform-bun": "0.87.1",
43
- "uniku": "workspace:*"
34
+ "uniku": "0.0.12"
44
35
  },
45
36
  "devDependencies": {
46
37
  "@types/bun": "^1.3.8",
47
38
  "@effect/vitest": "0.27.0",
48
39
  "vitest": "~3.2.0"
40
+ },
41
+ "scripts": {
42
+ "clean": "rimraf build .turbo",
43
+ "build": "tsdown --config-loader unrun",
44
+ "build:binary": "bun scripts/build-binary.ts",
45
+ "install:binary": "bun scripts/install-binary.ts",
46
+ "typecheck": "tsc --noEmit",
47
+ "test": "vitest run",
48
+ "test:watch": "vitest"
49
49
  }
50
- }
50
+ }