@yunarch/config-web 0.5.1 → 0.5.2
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.
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
import{c as
|
|
3
|
-
`))}function
|
|
2
|
+
import{c as d}from"../chunk-3QWYGBKZ.js";import{styleText as p}from"util";import{styleText as l}from"util";var m=["blue","green","yellow","grey","white","cyan"],b=o=>`${(Number(Bun.nanoseconds()-o)/1e6/1e3).toFixed(2)}s`;function g({start:o,tasks:e,failedTasks:n}){let c=e-n,a=b(o),t=n>0?l("red",`${n} failed`):"",i=c>0?l("green",`${c} successful`):"";console.log(""),console.log(l(["white","bold"],"Tasks: "),`${t}${t&&i?"|":""}${i}`,l("gray",`-- ${e} total`)),console.log(l(["white","bold"],"Time: "),l("gray",`${a}
|
|
3
|
+
`))}function f({index:o,script:e,continueOnError:n,reportTime:c}){let a=m[o%m.length],t=Bun.nanoseconds(),i=Bun.spawn(["bun","run",e],{stdout:"pipe",stderr:"pipe",env:{...Bun.env,FORCE_COLOR:"1"},onExit(r,s){s===1&&!n&&process.exit(1)}});return i.stdout.pipeTo(new WritableStream({write(r){let s=new TextDecoder().decode(r).split(`
|
|
4
4
|
`);for(let u of s)console.log(l([a,"bold"],`${e}:`),u)}})),i.stderr.pipeTo(new WritableStream({write(r){let s=new TextDecoder().decode(r).split(`
|
|
5
|
-
`);for(let u of s)console.log(l([a,"bold"],`${e}:`),u)}})),i.exited.then(r=>{r===0&&c&&console.log(l([a,"bold"],`${e}:`),l(["gray"],"Finished in"),l(["white","bold"],
|
|
5
|
+
`);for(let u of s)console.log(l([a,"bold"],`${e}:`),u)}})),i.exited.then(r=>{r===0&&c&&console.log(l([a,"bold"],`${e}:`),l(["gray"],"Finished in"),l(["white","bold"],b(t)))}),i}async function x(o,e){let{continueOnError:n,reportTime:c}=e,a=Bun.nanoseconds(),t=o.map((s,u)=>f({index:u,script:s,continueOnError:n,reportTime:c})),r=(await Promise.allSettled(t.map(s=>s.exited))).filter(s=>s.status==="rejected"||s.value!==0).length;return g({start:a,tasks:o.length,failedTasks:r}),r>0?1:0}async function T(o,e){let{continueOnError:n,reportTime:c}=e,a=Bun.nanoseconds(),t=0;for(let[i,r]of o.entries())await f({index:i,script:r,continueOnError:n,reportTime:c}).exited!==0&&t++;return g({start:a,tasks:o.length,failedTasks:t}),t>0?1:0}d().name("bun-run-all").description("Run given package scripts in parallel or sequential by using bun.").argument("<scripts...>","A list of package scripts' names.").option("-c, --continue-on-error","Continue executing other/subsequent tasks even if a task threw an error").option("-p, --parallel","Run a group of tasks in parallel.").option("-s, --sequential","Run a group of tasks sequentially.").option("-t, --time","Report execution time for each task.").addHelpText("after",`
|
|
6
6
|
Example usage:
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
${p("dim","$")} ${p("cyan","bun-run-all")} ${p("yellow","script1")} ${p("yellow","script2")}
|
|
8
|
+
`).action(async(o,e)=>{try{console.log(p("magenta",`
|
|
9
9
|
\u{1F680} bun-run-all
|
|
10
|
-
`));let n=e.sequential??!1,c=e.parallel??!n,a=e.continueOnError??!1,t=e.time??!1;if(c===n&&(console.error("You cannot use both --parallel and --sequential options at the same time."),process.exit(1)),n){let r=await
|
|
10
|
+
`));let n=e.sequential??!1,c=e.parallel??!n,a=e.continueOnError??!1,t=e.time??!1;if(c===n&&(console.error("You cannot use both --parallel and --sequential options at the same time."),process.exit(1)),n){let r=await T(o,{continueOnError:a,reportTime:t});process.exit(r)}let i=await x(o,{continueOnError:a,reportTime:t});process.exit(i)}catch(n){console.error(n),process.exit(1)}}).parseAsync(process.argv);
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{c as M}from"../chunk-3QWYGBKZ.js";import{existsSync as
|
|
2
|
+
import{c as M}from"../chunk-3QWYGBKZ.js";import{existsSync as N,statSync as T}from"fs";import v from"path";import{styleText as e}from"util";import{styleText as m}from"util";function H(f){let c=new Map;for(let o of f)c.has(o.service.name)||c.set(o.service.name,{service:o.service,handlers:[]}),c.get(o.service.name)?.handlers.push(o);if(c.size===0){console.log(m("green","\u2714 No missing handlers found"));return}for(let{service:o,handlers:i}of c.values()){console.log(`${m("underline",o.name)}${m("gray",` (${o.path})`)}`);for(let[a,s]of i.entries()){let t=a===i.length-1;console.log(` ${t?"\u2514\u2500":"\u251C\u2500"} ${m("cyan",s.service.toHandleHttpMethod)} ${m("yellow",s.service.toHandleUrl)}`),console.log(` ${t?" ":"\u2502"} \u251C\u2500 ${m("gray","Used in:")}`);for(let[p,l]of s.usedIn.entries()){let r=p===s.usedIn.length-1;console.log(` ${t?" ":"\u2502"} ${r?"\u2502 \u2514\u2500":"\u2502 \u251C\u2500"} ${l}`)}console.log(` ${t?" ":"\u2502"} \u2514\u2500 ${m("green","Suggested handler:")}`),console.log(` ${t?" ":"\u2502"} ${m("dim","\u2192")} ${s.suggestedPath}`),a<i.length-1&&console.log(` ${t?" ":"\u2502"}`)}console.log("")}console.log(m("red",`\u2718 ${f.length} missing ${f.length===1?"handler":"handlers"}`))}import{pathToFileURL as F}from"url";async function E({mswSetupFilePath:f,mswSetupConst:c}){let o=new Map,i=await import(F(f).href);if(!Object.hasOwn(i,c))throw new TypeError("MSW setup constant not found in the setup file");let a=i[c];if(!a||typeof a.listHandlers!="function")throw new TypeError("MSW setup constant does not have a listHandlers() method");let s=a.listHandlers();for(let t of s){if(!("info"in t)||!t.info?.path||!t.info.method)continue;let p=String(t.info.path),l=String(t.info.method).toUpperCase(),r=p.replaceAll(/:(?<temp1>[^/]+)/g,"{$1}"),d=`${l}:${r}`;o.set(d,{path:p,httpMethod:l,url:r})}return o}import{existsSync as C,readFileSync as U}from"fs";import I from"path";import _ from"fast-glob";import n from"typescript";async function W(f){let c=[],o=I.join(f,"services");if(!C(o))throw new Error(`Services directory not found: ${o}`);let i=await _("**/*Service.ts",{cwd:o,absolute:!0,ignore:["**/node_modules/**"]});for(let a of i){let s=I.basename(a,".ts"),t=U(a,"utf8"),p=n.createSourceFile(a,t,n.ScriptTarget.Latest,!0);n.forEachChild(p,l=>{if(n.isClassDeclaration(l)&&l.name?.text===s){for(let r of l.members)if(n.isMethodDeclaration(r)&&n.isIdentifier(r.name)&&r.modifiers&&r.modifiers.some(d=>d.kind===n.SyntaxKind.PublicKeyword)&&r.modifiers.some(d=>d.kind===n.SyntaxKind.StaticKeyword)){let d=r.name.text,y,h,x=u=>{if(n.isReturnStatement(u)&&u.expression&&n.isCallExpression(u.expression)&&n.isIdentifier(u.expression.expression)&&u.expression.expression.text==="__request"){let S=u.expression.arguments[1];if(n.isObjectLiteralExpression(S))for(let g of S.properties)n.isPropertyAssignment(g)&&n.isIdentifier(g.name)&&g.name.text==="url"&&n.isStringLiteral(g.initializer)?y=g.initializer.text:n.isPropertyAssignment(g)&&n.isIdentifier(g.name)&&g.name.text==="method"&&n.isStringLiteral(g.initializer)&&(h=g.initializer.text.toUpperCase())}n.forEachChild(u,x)};r.body&&n.forEachChild(r.body,x),y&&h?c.push({path:a,name:s,methodName:d,toHandleUrl:y,toHandleHttpMethod:h}):(y||console.warn(`No URL found for ${d} request in service ${s} (${a})`),h||console.warn(`No HTTP method found for ${d} request in service ${s} (${a})`))}}})}return c}async function P({genPath:f,srcPath:c}){let o=await W(f),i=new Map;for(let s of o)i.has(s.name)||i.set(s.name,new Map),i.get(s.name)?.set(s.methodName,{serviceInfo:s,files:new Set});let a=await _("**/*.{ts,tsx}",{cwd:c,absolute:!0,ignore:["**/node_modules/**","**/__tests__/**"]});for(let s of a)try{let t=U(s,"utf8"),p=n.createSourceFile(s,t,n.ScriptTarget.Latest,!0),l=r=>{if(n.isCallExpression(r)&&n.isPropertyAccessExpression(r.expression)&&n.isIdentifier(r.expression.expression)&&r.expression.expression.text.endsWith("Service")){let d=r.expression.expression.text,y=r.expression.name.text,h=i.get(d)?.get(y);if(!h)return;h.files.add(s)}n.forEachChild(r,l)};l(p)}catch(t){throw t instanceof Error?new TypeError(`Error parsing ${s}: ${t.message}`):new TypeError(`Error parsing ${s}: Unknown error`)}for(let[s,t]of i.entries()){for(let[p,l]of t.entries())l.files.size===0&&t.delete(p);t.size===0&&i.delete(s)}return i}import L from"path";function b(f,c,o){let i=[];for(let[a,s]of f.entries())for(let[t,p]of s.entries()){let{serviceInfo:l}=p,r=l.toHandleHttpMethod,d=l.toHandleUrl;!c.has(`${r}:${d}`)&&!c.has(`${r}:*${d}`)&&i.push({type:"missing_handler",service:l,usedIn:[...p.files],suggestedPath:L.join(o,`handlers/services/${a}/${t}.ts`)})}return i}M().name("openapi-sync-lint-msw-handlers").description("Lint MSW handlers against OpenAPI generated services from `openapi-sync`.\nIt checks for missing handlers based on generated services and your MSW setup.").requiredOption("--gen <path>","The output folder from `openapi-sync` script. Where the generated models and openapi schema and type definitions are saved.").requiredOption("--msw-setup-file <path>","Path to the MSW setup file (file that configures MSW setupServer or setupWorker).").requiredOption("--msw-setup-const <const>","Name of the constant that holds the MSW setup (e.g., server or worker).").addHelpText("after",`
|
|
3
3
|
Example usage:
|
|
4
|
+
${e("dim","$")} ${e("cyan","openapi-sync-lint-msw-handlers")} ${e("green","--gen")} ${e("yellow","./src/api/gen")} ${e("green","--msw-setup-file")} ${e("yellow","./src/api/__tests__/node.js")} ${e("green","--msw-setup-const")} ${e("yellow","server")}
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
Note: If the MSW setup file (passed via ${e("green","--msw-setup-file")}) is a TypeScript file,
|
|
7
|
+
you must run the script with a runtime that supports TypeScript (e.g. ${e("yellow","tsx")}, ${e("yellow","ts-node")}, or ${e("yellow","bun")}).
|
|
8
|
+
|
|
9
|
+
Examples:
|
|
10
|
+
${e("dim","$")} ${e("yellow","tsx")} ${e("cyan","openapi-sync-lint-msw-handlers")} ${e("green","--gen")} ${e("yellow","./src/api/gen")} ${e("green","--msw-setup-file")} ${e("yellow","./src/api/__tests__/node.ts")} ${e("green","--msw-setup-const")} ${e("yellow","server")}
|
|
11
|
+
|
|
12
|
+
${e("dim","$")} ${e("yellow","bun")} ${e("yellow","--bun")} ${e("cyan","openapi-sync-lint-msw-handlers")} ${e("green","--gen")} ${e("yellow","./src/api/gen")} ${e("green","--msw-setup-file")} ${e("yellow","./src/api/__tests__/node.ts")} ${e("green","--msw-setup-const")} ${e("yellow","server")}
|
|
13
|
+
`).action(async({gen:f,mswSetupFile:c,mswSetupConst:o})=>{try{let i=process.cwd(),a=v.resolve(i,f),s=v.resolve(i,"."),t=v.resolve(i,c);if(!N(a)||!T(a).isDirectory())throw new Error("Generated API folder does not exist or is not a directory");if(!N(t)||!T(t).isFile())throw new Error("MSW setup file does not exist or is not a file");let p=await P({genPath:a,srcPath:s}),l=await E({mswSetupFilePath:t,mswSetupConst:o}),r=b(p,l,v.dirname(t));H(r),process.exit(r.length>0?1:0)}catch(i){console.error(i),process.exit(1)}}).parseAsync(process.argv);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as f,b as o,c as
|
|
2
|
+
import{a as f,b as o,c as u}from"../chunk-3QWYGBKZ.js";import{existsSync as y}from"fs";import{mkdir as H,readFile as T,writeFile as M}from"fs/promises";import c from"path";import{styleText as n}from"util";import E from"@inquirer/confirm";async function g(e,t){await o({name:"Generating models",command:`npx openapi-typescript-codegen --input ${e} --output ${t} --client fetch`})}import{writeFile as O}from"fs/promises";var w=`
|
|
3
3
|
import {
|
|
4
4
|
http as mswHttp,
|
|
5
5
|
type DefaultBodyType,
|
|
@@ -116,18 +116,18 @@ export function http<P extends keyof Paths, M extends Methods<P>>(
|
|
|
116
116
|
}
|
|
117
117
|
return handlers[method as keyof typeof handlers](uri, resolver, options);
|
|
118
118
|
}
|
|
119
|
-
`;async function P(e){await o({name:"Generating openapi MSW utils",command:async()=>{await O(`${e}/openapi-msw-http.ts`,w)}})}import{readFile as
|
|
120
|
-
${
|
|
119
|
+
`;async function P(e){await o({name:"Generating openapi MSW utils",command:async()=>{await O(`${e}/openapi-msw-http.ts`,w)}})}import{readFile as $,writeFile as R}from"fs/promises";async function x(e,t){await o({name:"Generating schema types",command:async()=>{await f(`npx openapi-typescript ${e} -o ${t}`);let a=await $(t,"utf8");await R(t,`/* eslint-disable -- Autogenerated file */
|
|
120
|
+
${a}`)}})}async function v(e){if(c.extname(e)!=="")throw new Error("Output must be a directory.");let t=process.cwd(),a=c.resolve(e),s=a.startsWith(t)?a:c.resolve(t,c.relative(c.parse(e).root,e));return y(s)||await o({name:"Generating output directory",command:async()=>{await H(s,{recursive:!0})}}),s}async function B(e,t){let[a,p]=await Promise.all([o({name:"Reading input openapi schema",command:async()=>{if(!e.endsWith(".json"))throw new Error(`Input file must be a JSON file: ${e}`);if(e.startsWith("http"))try{let{stdout:s}=await f(`curl -s ${e} --fail`);return s}catch{throw new Error(`Failed to fetch remote OpenAPI file: ${e}`)}if(!y(e))throw new Error(`Input file does not exist: ${e}`);return await T(e,"utf8")}}),o({name:"Reading output openapi schema",command:async()=>{if(!t.endsWith(".json"))throw new Error(`Output file must be a JSON file: ${t}`);return y(t)?await T(t,"utf8"):!1}})]);return[JSON.stringify(JSON.parse(a)),p?JSON.stringify(JSON.parse(p)):!1]}u().name("openapi-sync").description("A CLI tool to convert OpenAPI 3.0/3.1 schemas to TypeScript types and create type-safe fetching based on a openapi file and keep them in sync.").requiredOption("-i, --input <path>","The input (local or remote) openapi schema (JSON).").requiredOption("-o, --output <folder>","The output folder to save the generated models and openapi schema and type definitions.").option("-f, --force-gen","Force generation of typescript schemas and fetching code even if the input and output schemas are identical.").option("--include-msw-utils","Include MSW mocking utilities based on the generated typescript types.").option("--post-script <script>","A package.json script to run after the code generation.").addHelpText("after",`
|
|
121
121
|
Example usage:
|
|
122
|
-
|
|
123
|
-
|
|
122
|
+
${n("dim","$")} ${n("cyan","openapi-sync")} ${n("green","-i")} ${n("yellow","./openapi.json")} ${n("green","-o")} ${n("yellow","./src/api/gen")} ${n("green","--include-msw-utils")}
|
|
123
|
+
`).action(async({input:e,output:t,forceGen:a,includeMswUtils:p,postScript:s})=>{try{console.log(n("magenta",`
|
|
124
124
|
\u{1F680} openapi-sync
|
|
125
|
-
`));let
|
|
125
|
+
`));let r=await v(t),i=`${r}/openapi.json`,k=`${r}/schema.d.ts`,[m,d]=await B(e,i);d&&m===d&&!a?(console.log(n("blue",`
|
|
126
126
|
No updates required.
|
|
127
|
-
`)),process.exit(0)):
|
|
127
|
+
`)),process.exit(0)):d?d&&m!==d&&(console.log(n("yellow",`
|
|
128
128
|
\u26A0\uFE0F Local and remote schemas does not match!
|
|
129
|
-
`)),await
|
|
129
|
+
`)),await E({message:"Do you want to use the remote schema? (y/n)?"})?await o({name:"Replacing local schema with input schema",command:M(i,m)}):(console.log(n("yellow",`
|
|
130
130
|
\u26A0\uFE0F Sync remote schemas skipped.
|
|
131
|
-
`)),
|
|
131
|
+
`)),a||process.exit(0))):await o({name:"Creating local schema",command:M(i,m)}),await Promise.all([x(i,k),g(i,r)]),p&&await P(r),s&&await o({name:"Running post script",command:`node --run ${s}`}),console.log(n("green",`
|
|
132
132
|
\u2705 openapi-sync process completed!
|
|
133
|
-
`))}catch(
|
|
133
|
+
`))}catch(r){console.error(r),process.exit(1)}}).parseAsync(process.argv);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{c as
|
|
3
|
-
`).slice(1).map(e=>e.trim()).filter(Boolean).map(e=>e.split(" ")[0]);return await
|
|
2
|
+
import{c as a}from"../chunk-3QWYGBKZ.js";import{execSync as u}from"child_process";import{styleText as t}from"util";import{execSync as p}from"child_process";import i from"@inquirer/select";async function c(){let n=p("npx turbo ls",{encoding:"utf8",stdio:"pipe"}).split(`
|
|
3
|
+
`).slice(1).map(e=>e.trim()).filter(Boolean).map(e=>e.split(" ")[0]);return await i({message:"Select a package to run the script:",choices:n.map(e=>({name:e,value:e}))})}async function s(){return await i({message:"Select a mode to load different env files:",choices:[{name:"development",value:"development"},{name:"staging",value:"staging"},{name:"production",value:"production"}]})}a().name("turbo-select").description(`A CLI tool to filter and select a single package from the Turborepo package list and run a script command.
|
|
4
4
|
Additionally, allow to prompt environment mode (development, staging, production), for example, when using Vite.`).requiredOption("--run <script>","The package script command to execute (e.g., --run=dev).").option("--select-env","An environment mode (development, staging, production) If using for example vite.").addHelpText("after",`
|
|
5
5
|
Example usage:
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
${t("dim","$")} ${t("cyan","turbo-select")} ${t("green","--run")} ${t("yellow","dev")} ${t("green","--select-env")}
|
|
7
|
+
`).action(async({run:o,selectEnv:n})=>{try{console.log(t("magenta",`
|
|
8
8
|
\u{1F680} Turbo-Select
|
|
9
|
-
`));let e=await
|
|
9
|
+
`));let e=await c(),r=n?await s():void 0;u(`turbo run ${o} --ui stream ${e?`--filter=${e}`:""} ${r?`-- --mode ${r}`:""}`,{encoding:"utf8",stdio:"inherit"})}catch(e){console.error(e),process.exit(1)}}).parseAsync(process.argv);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"name": "@yunarch/config-web",
|
|
5
5
|
"description": "Shared configurations for web projects.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
"eslint-plugin-react-hooks": "5.2.0",
|
|
124
124
|
"eslint-plugin-react-refresh": "0.4.20",
|
|
125
125
|
"@tanstack/eslint-plugin-query": "5.83.1",
|
|
126
|
-
"@tanstack/eslint-plugin-router": "1.
|
|
126
|
+
"@tanstack/eslint-plugin-router": "1.130.12",
|
|
127
127
|
"@vitest/eslint-plugin": "1.3.4"
|
|
128
128
|
},
|
|
129
129
|
"devDependencies": {
|
|
@@ -135,7 +135,7 @@
|
|
|
135
135
|
"eslint-typegen": "2.3.0",
|
|
136
136
|
"oxlint": "1.9.0",
|
|
137
137
|
"husky": "9.1.7",
|
|
138
|
-
"lint-staged": "16.1.
|
|
138
|
+
"lint-staged": "16.1.4",
|
|
139
139
|
"rimraf": "6.0.1",
|
|
140
140
|
"tsup": "8.5.0",
|
|
141
141
|
"typescript": "5.9.2",
|