@visulima/package 5.0.0-alpha.3 → 5.0.0-alpha.5

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,4 +1,620 @@
1
- var K=Object.defineProperty;var f=(e,r)=>K(e,"name",{value:r,configurable:!0});import{createRequire as V}from"node:module";import{installPackage as X}from"@antfu/install-pkg";import{readJsonSync as L,readFileSync as H,findUp as Q,findUpSync as Z,writeJson as ee,writeJsonSync as re,readJson as ne,readFile as te}from"@visulima/fs";import{NotFoundError as I}from"@visulima/fs/error";import{parseJson as T,toPath as A}from"@visulima/fs/utils";import{readYamlSync as oe,readYaml as se}from"@visulima/fs/yaml";import{join as _}from"@visulima/path";import F from"json5";import ae from"normalize-package-data";import{readPnpmCatalogsSync as D,resolveCatalogReferences as E,readPnpmCatalogs as C}from"./pnpm.js";const U=V(import.meta.url),w=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,J=f(e=>{if(typeof w<"u"&&w.versions&&w.versions.node){const[r,t]=w.versions.node.split(".").map(Number);if(r>22||r===22&&t>=3||r===20&&t>=16)return w.getBuiltinModule(e)}return U(e)},"__cjs_getBuiltinModule"),{existsSync:N}=J("node:fs"),{createInterface:ie}=J("node:readline"),{styleText:g}=J("node:util");var ce=Object.defineProperty,l=f((e,r)=>ce(e,"name",{value:r,configurable:!0}),"f");const h=l(e=>{const r=typeof e;return e!==null&&(r==="object"||r==="function")},"isObject"),fe=l(e=>{if(!h(e))return!1;for(const r in e)if(Object.hasOwn(e,r))return!1;return!0},"isEmptyObject"),O=new Set(["__proto__","prototype","constructor"]),W=1e6,pe=l(e=>e>="0"&&e<="9","isDigit");function b(e){if(e==="0")return!0;if(/^[1-9]\d*$/.test(e)){const r=Number.parseInt(e,10);return r<=Number.MAX_SAFE_INTEGER&&r<=W}return!1}f(b,"p$1");l(b,"shouldCoerceToNumber");function k(e,r){return O.has(e)?!1:(e&&b(e)?r.push(Number.parseInt(e,10)):r.push(e),!0)}f(k,"y");l(k,"processSegment");function B(e){if(typeof e!="string")throw new TypeError(`Expected a string, got ${typeof e}`);const r=[];let t="",n="start",o=!1,s=0;for(const a of e){if(s++,o){t+=a,o=!1;continue}if(a==="\\"){if(n==="index")throw new Error(`Invalid character '${a}' in an index at position ${s}`);if(n==="indexEnd")throw new Error(`Invalid character '${a}' after an index at position ${s}`);o=!0,n=n==="start"?"property":n;continue}switch(a){case".":{if(n==="index")throw new Error(`Invalid character '${a}' in an index at position ${s}`);if(n==="indexEnd"){n="property";break}if(!k(t,r))return[];t="",n="property";break}case"[":{if(n==="index")throw new Error(`Invalid character '${a}' in an index at position ${s}`);if(n==="indexEnd"){n="index";break}if(n==="property"||n==="start"){if((t||n==="property")&&!k(t,r))return[];t=""}n="index";break}case"]":{if(n==="index"){if(t==="")t=(r.pop()||"")+"[]",n="property";else{const i=Number.parseInt(t,10);!Number.isNaN(i)&&Number.isFinite(i)&&i>=0&&i<=Number.MAX_SAFE_INTEGER&&i<=W&&t===String(i)?r.push(i):r.push(t),t="",n="indexEnd"}break}if(n==="indexEnd")throw new Error(`Invalid character '${a}' after an index at position ${s}`);t+=a;break}default:{if(n==="index"&&!pe(a))throw new Error(`Invalid character '${a}' in an index at position ${s}`);if(n==="indexEnd")throw new Error(`Invalid character '${a}' after an index at position ${s}`);n==="start"&&(n="property"),t+=a}}}switch(o&&(t+="\\"),n){case"property":{if(!k(t,r))return[];break}case"index":throw new Error("Index was not closed");case"start":{r.push("");break}}return r}f(B,"parsePath");l(B,"parsePath");function $(e){if(typeof e=="string")return B(e);if(Array.isArray(e)){const r=[];for(const[t,n]of e.entries()){if(typeof n!="string"&&typeof n!="number")throw new TypeError(`Expected a string or number for path segment at index ${t}, got ${typeof n}`);if(typeof n=="number"&&!Number.isFinite(n))throw new TypeError(`Path segment at index ${t} must be a finite number, got ${n}`);if(O.has(n))return[];typeof n=="string"&&b(n)?r.push(Number.parseInt(n,10)):r.push(n)}return r}return[]}f($,"d");l($,"normalizePath");function d(e,r,t){if(!h(e)||typeof r!="string"&&!Array.isArray(r))return t===void 0?e:t;const n=$(r);if(n.length===0)return t;for(let o=0;o<n.length;o++){const s=n[o];if(e=e[s],e==null){if(o!==n.length-1)return t;break}}return e===void 0?t:e}f(d,"getProperty");l(d,"getProperty");function M(e,r,t){if(!h(e)||typeof r!="string"&&!Array.isArray(r))return e;const n=e,o=$(r);if(o.length===0)return e;for(let s=0;s<o.length;s++){const a=o[s];if(s===o.length-1)e[a]=t;else if(!h(e[a])){const i=typeof o[s+1]=="number";e[a]=i?[]:{}}e=e[a]}return n}f(M,"setProperty");l(M,"setProperty");function le(e,r){if(!h(e)||typeof r!="string"&&!Array.isArray(r))return!1;const t=$(r);if(t.length===0)return!1;for(let n=0;n<t.length;n++){const o=t[n];if(n===t.length-1)return Object.hasOwn(e,o)?(delete e[o],!0):!1;if(e=e[o],!h(e))return!1}}f(le,"deleteProperty");l(le,"deleteProperty");function y(e,r){if(!h(e)||typeof r!="string"&&!Array.isArray(r))return!1;const t=$(r);if(t.length===0)return!1;for(const n of t){if(!h(e)||!(n in e))return!1;e=e[n]}return!0}f(y,"hasProperty");l(y,"hasProperty");function x(e){if(typeof e!="string")throw new TypeError(`Expected a string, got ${typeof e}`);return e.replaceAll(/[\\.[]/g,String.raw`\$&`)}f(x,"escapePath");l(x,"escapePath");function R(e){const r=Object.entries(e);return Array.isArray(e)?r.map(([t,n])=>[b(t)?Number.parseInt(t,10):t,n]):r}f(R,"m$2");l(R,"normalizeEntries");function Y(e,r={}){if(!Array.isArray(e))throw new TypeError(`Expected an array, got ${typeof e}`);const{preferDotForIndices:t=!1}=r,n=[];for(const[o,s]of e.entries()){if(typeof s!="string"&&typeof s!="number")throw new TypeError(`Expected a string or number for path segment at index ${o}, got ${typeof s}`);if(typeof s=="number")if(!Number.isInteger(s)||s<0){const a=x(String(s));n.push(o===0?a:`.${a}`)}else t&&o>0?n.push(`.${s}`):n.push(`[${s}]`);else if(typeof s=="string")if(s==="")o===0||n.push(".");else if(b(s)){const a=Number.parseInt(s,10);t&&o>0?n.push(`.${a}`):n.push(`[${a}]`)}else{const a=x(s);n.push(o===0?a:`.${a}`)}}return n.join("")}f(Y,"stringifyPath");l(Y,"stringifyPath");function*S(e,r=[],t=new Set){if(!h(e)||fe(e)){r.length>0&&(yield Y(r));return}if(!t.has(e)){t.add(e);for(const[n,o]of R(e))r.push(n),yield*S(o,r,t),r.pop();t.delete(e)}}f(S,"x");l(S,"deepKeysIterator");function ue(e){return[...S(e)]}f(ue,"deepKeys");l(ue,"deepKeys");function ge(e){const r={};if(!h(e))return r;for(const[t,n]of Object.entries(e))M(r,t,n);return r}f(ge,"unflatten");l(ge,"unflatten");var he=Object.defineProperty,j=f((e,r)=>he(e,"name",{value:r,configurable:!0}),"i");const de=j(async e=>{const{default:r=!1,message:t,transformer:n}=e,o=j(a=>{const i=g(["cyan","bold"],"?"),c=g(["bold"],a),u=r?`${g(["greenBright"],"Y")}${g(["gray"],"/n")}`:`y/${g(["yellowBright"],"N")}`;return`${i} ${c} ${g(["gray"],`(${u})`)}`},"formatMessage"),s=j(a=>n?n(a):a?g(["greenBright"],"Yes"):g(["yellowBright"],"No"),"formatAnswer");return new Promise(a=>{const i=ie({input:process.stdin,output:process.stdout}),c=o(t);i.question(c,u=>{i.close();const m=u.trim().toLowerCase();if(m===""){a(r);return}if(m==="y"||m==="yes"){console.log(`${g(["greenBright"],"✓")} ${s(!0)}`),a(!0);return}if(m==="n"||m==="no"){console.log(`${g(["yellowBright"],"✗")} ${s(!1)}`),a(!1);return}console.log(`${g(["gray"],"→")} ${s(r)}`),a(r)}),i.on("SIGINT",()=>{i.close(),console.log(`
2
- ${g(["gray"],"→")} ${s(r)}`),a(r)})})},"confirm"),ye=typeof process.stdout<"u"&&!process.versions.deno&&!globalThis.window;var me=Object.defineProperty,p=f((e,r)=>me(e,"name",{value:r,configurable:!0}),"l");const P=new Map,q=new Map;class we extends Error{static{f(this,"F")}static{p(this,"PackageJsonValidationError")}constructor(r){super(`The following warnings were encountered while normalizing package data:
3
- - ${r.join(`
4
- - `)}`),this.name="PackageJsonValidationError"}}const v=p((e,r,t=[])=>{const n=[];if(ae(e,o=>{n.push(o)},r),r&&n.length>0){const o=n.filter(s=>!t.some(a=>a instanceof RegExp?a.test(s):a===s));if(o.length>0)throw new we(o)}return e},"normalizeInput"),be=p(async e=>await se(e),"parseYamlFile"),$e=p(e=>oe(e),"parseYamlFileSync"),ke=p(async e=>{const r=await te(e);return F.parse(r)},"parseJson5File"),Pe=p(e=>{const r=H(e);return F.parse(r)},"parseJson5FileSync"),z=p(async(e,r)=>r?.yaml!==!1&&(e.endsWith(".yaml")||e.endsWith(".yml"))?be(e):r?.json5!==!1&&e.endsWith(".json5")?ke(e):ne(e),"parsePackageFile"),G=p((e,r)=>r?.yaml!==!1&&(e.endsWith(".yaml")||e.endsWith(".yml"))?$e(e):r?.json5!==!1&&e.endsWith(".json5")?Pe(e):L(e),"parsePackageFileSync"),Fe=p(async(e,r={})=>{const t={type:"file"};e&&(t.cwd=e);const n=["package.json"];r.yaml!==!1&&n.push("package.yaml","package.yml"),r.json5!==!1&&n.push("package.json5");let o;for await(const c of n)if(o=await Q(c,t),o)break;if(!o)throw new I(`No such file or directory, for ${n.join(", ").replace(/, ([^,]*)$/," or $1")} found.`);const s=r.cache&&typeof r.cache!="boolean"?r.cache:q;if(r.cache&&s.has(o))return s.get(o);const a=await z(o,r);if(r.resolveCatalogs){const c=await C(o);c&&E(a,c)}v(a,r.strict??!1,r.ignoreWarnings);const i={packageJson:a,path:o};return r.cache&&s.set(o,i),i},"findPackageJson"),De=p((e,r={})=>{const t={type:"file"};e&&(t.cwd=e);const n=["package.json"];r.yaml!==!1&&n.push("package.yaml","package.yml"),r.json5!==!1&&n.push("package.json5");let o;for(const c of n)if(o=Z(c,t),o)break;if(!o)throw new I(`No such file or directory, for ${n.join(", ").replace(/, ([^,]*)$/," or $1")} found.`);const s=r.cache&&typeof r.cache!="boolean"?r.cache:q;if(r.cache&&s.has(o))return s.get(o);const a=G(o,r);if(r.resolveCatalogs){const c=D(o);c&&E(a,c)}v(a,r.strict??!1,r.ignoreWarnings);const i={packageJson:a,path:o};return r.cache&&s.set(o,i),i},"findPackageJsonSync"),Ce=p(async(e,r={})=>{const{cwd:t,...n}=r,o=A(t??process.cwd());await ee(_(o,"package.json"),e,n)},"writePackageJson"),Oe=p((e,r={})=>{const{cwd:t,...n}=r,o=A(t??process.cwd());re(_(o,"package.json"),e,n)},"writePackageJsonSync"),We=p((e,r)=>{const t=e!==null&&typeof e=="object"&&!Array.isArray(e);if(!t&&typeof e!="string")throw new TypeError("`packageFile` should be either an `object` or a `string`.");let n,o=!1,s;if(t)n=structuredClone(e);else if(N(e)){s=e;const i=r?.cache&&typeof r.cache!="boolean"?r.cache:P;if(r?.cache&&i.has(s))return i.get(s);n=G(s,r),o=!0}else n=T(e);if(r?.resolveCatalogs)if(o){const i=D(e);i&&E(n,i)}else throw new Error("The 'resolveCatalogs' option can only be used on a file path.");v(n,r?.strict??!1,r?.ignoreWarnings);const a=n;return o&&s&&r?.cache&&(r.cache&&typeof r.cache!="boolean"?r.cache:P).set(s,a),a},"parsePackageJsonSync"),Be=p(async(e,r)=>{const t=e!==null&&typeof e=="object"&&!Array.isArray(e);if(!t&&typeof e!="string")throw new TypeError("`packageFile` should be either an `object` or a `string`.");let n,o=!1,s;if(t)n=structuredClone(e);else if(N(e)){s=e;const i=r?.cache&&typeof r.cache!="boolean"?r.cache:P;if(r?.cache&&i.has(s))return i.get(s);n=await z(s,r),o=!0}else n=T(e);if(r?.resolveCatalogs)if(o){const i=await C(e);i&&E(n,i)}else throw new Error("The 'resolveCatalogs' option can only be used on a file path.");v(n,r?.strict??!1,r?.ignoreWarnings);const a=n;return o&&s&&r?.cache&&(r.cache&&typeof r.cache!="boolean"?r.cache:P).set(s,a),a},"parsePackageJson"),Me=p((e,r,t)=>d(e,r,t),"getPackageJsonProperty"),Re=p((e,r)=>y(e,r),"hasPackageJsonProperty"),Ye=p((e,r,t)=>{const n=d(e,"dependencies",{}),o=d(e,"devDependencies",{}),s=d(e,"peerDependencies",{}),a={...n,...o,...t?.peerDeps===!1?{}:s};for(const i of r)if(y(a,i))return!0;return!1},"hasPackageJsonAnyDependency"),qe=p(async(e,r,t="dependencies",n={})=>{const o=d(e,"dependencies",{}),s=d(e,"devDependencies",{}),a=d(e,"peerDependencies",{}),i=[],c={deps:!0,devDeps:!0,peerDeps:!1,...n};for(const u of r)c.deps&&y(o,u)||c.devDeps&&y(s,u)||c.peerDeps&&y(a,u)||i.push(u);if(i.length!==0){if(process.env.CI||ye&&!process.stdout?.isTTY){const u=`Skipping package installation for [${r.join(", ")}] because the process is not interactive.`;if(n.throwOnWarn)throw new Error(u);n.logger?.warn?n.logger.warn(u):console.warn(u);return}if(typeof c.confirm?.message=="function"&&(c.confirm.message=c.confirm.message(i)),c.confirm?.message===void 0){const u=`${i.length===1?"Package is":"Packages are"} required for this config: ${i.join(", ")}. Do you want to install them?`;c.confirm===void 0?c.confirm={message:u}:c.confirm.message=u}await de(c.confirm)&&await X(i,{...c.installPackage,cwd:c.cwd?A(c.cwd):void 0,dev:t==="devDependencies"})}},"ensurePackages");export{qe as ensurePackages,Fe as findPackageJson,De as findPackageJsonSync,Me as getPackageJsonProperty,Ye as hasPackageJsonAnyDependency,Re as hasPackageJsonProperty,Be as parsePackageJson,We as parsePackageJsonSync,Ce as writePackageJson,Oe as writePackageJsonSync};
1
+ import { createRequire as __cjs_createRequire } from "node:module";
2
+
3
+ const __cjs_require = __cjs_createRequire(import.meta.url);
4
+
5
+ const __cjs_getProcess = typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" ? globalThis.process : process;
6
+
7
+ const __cjs_getBuiltinModule = (module) => {
8
+ // Check if we're in Node.js and version supports getBuiltinModule
9
+ if (typeof __cjs_getProcess !== "undefined" && __cjs_getProcess.versions && __cjs_getProcess.versions.node) {
10
+ const [major, minor] = __cjs_getProcess.versions.node.split(".").map(Number);
11
+ // Node.js 20.16.0+ and 22.3.0+
12
+ if (major > 22 || (major === 22 && minor >= 3) || (major === 20 && minor >= 16)) {
13
+ return __cjs_getProcess.getBuiltinModule(module);
14
+ }
15
+ }
16
+ // Fallback to createRequire
17
+ return __cjs_require(module);
18
+ };
19
+
20
+ const {
21
+ existsSync
22
+ } = __cjs_getBuiltinModule("node:fs");
23
+ import { installPackage } from '@antfu/install-pkg';
24
+ import { findUp, findUpSync, writeJson, writeJsonSync, readJson, readJsonSync, readFile, readFileSync } from '@visulima/fs';
25
+ import { NotFoundError } from '@visulima/fs/error';
26
+ import { toPath, parseJson } from '@visulima/fs/utils';
27
+ import { readYaml, readYamlSync } from '@visulima/fs/yaml';
28
+ import { join } from '@visulima/path';
29
+ import JSON5 from 'json5';
30
+ import normalizeData from 'normalize-package-data';
31
+ import { readPnpmCatalogs, resolveCatalogReferences, readPnpmCatalogsSync } from './pnpm.js';
32
+ const {
33
+ createInterface
34
+ } = __cjs_getBuiltinModule("node:readline");
35
+ const {
36
+ styleText
37
+ } = __cjs_getBuiltinModule("node:util");
38
+
39
+ const isObject = (value) => {
40
+ const type = typeof value;
41
+ return value !== null && (type === "object" || type === "function");
42
+ };
43
+ const disallowedKeys = /* @__PURE__ */ new Set([
44
+ "__proto__",
45
+ "prototype",
46
+ "constructor"
47
+ ]);
48
+ const MAX_ARRAY_INDEX = 1e6;
49
+ const isDigit = (character) => character >= "0" && character <= "9";
50
+ function shouldCoerceToNumber(segment) {
51
+ if (segment === "0") {
52
+ return true;
53
+ }
54
+ if (/^[1-9]\d*$/.test(segment)) {
55
+ const parsedNumber = Number.parseInt(segment, 10);
56
+ return parsedNumber <= Number.MAX_SAFE_INTEGER && parsedNumber <= MAX_ARRAY_INDEX;
57
+ }
58
+ return false;
59
+ }
60
+ function processSegment(segment, parts) {
61
+ if (disallowedKeys.has(segment)) {
62
+ return false;
63
+ }
64
+ if (segment && shouldCoerceToNumber(segment)) {
65
+ parts.push(Number.parseInt(segment, 10));
66
+ } else {
67
+ parts.push(segment);
68
+ }
69
+ return true;
70
+ }
71
+ function parsePath(path) {
72
+ if (typeof path !== "string") {
73
+ throw new TypeError(`Expected a string, got ${typeof path}`);
74
+ }
75
+ const parts = [];
76
+ let currentSegment = "";
77
+ let currentPart = "start";
78
+ let isEscaping = false;
79
+ let position = 0;
80
+ for (const character of path) {
81
+ position++;
82
+ if (isEscaping) {
83
+ currentSegment += character;
84
+ isEscaping = false;
85
+ continue;
86
+ }
87
+ if (character === "\\") {
88
+ if (currentPart === "index") {
89
+ throw new Error(`Invalid character '${character}' in an index at position ${position}`);
90
+ }
91
+ if (currentPart === "indexEnd") {
92
+ throw new Error(`Invalid character '${character}' after an index at position ${position}`);
93
+ }
94
+ isEscaping = true;
95
+ currentPart = currentPart === "start" ? "property" : currentPart;
96
+ continue;
97
+ }
98
+ switch (character) {
99
+ case ".": {
100
+ if (currentPart === "index") {
101
+ throw new Error(`Invalid character '${character}' in an index at position ${position}`);
102
+ }
103
+ if (currentPart === "indexEnd") {
104
+ currentPart = "property";
105
+ break;
106
+ }
107
+ if (!processSegment(currentSegment, parts)) {
108
+ return [];
109
+ }
110
+ currentSegment = "";
111
+ currentPart = "property";
112
+ break;
113
+ }
114
+ case "[": {
115
+ if (currentPart === "index") {
116
+ throw new Error(`Invalid character '${character}' in an index at position ${position}`);
117
+ }
118
+ if (currentPart === "indexEnd") {
119
+ currentPart = "index";
120
+ break;
121
+ }
122
+ if (currentPart === "property" || currentPart === "start") {
123
+ if ((currentSegment || currentPart === "property") && !processSegment(currentSegment, parts)) {
124
+ return [];
125
+ }
126
+ currentSegment = "";
127
+ }
128
+ currentPart = "index";
129
+ break;
130
+ }
131
+ case "]": {
132
+ if (currentPart === "index") {
133
+ if (currentSegment === "") {
134
+ const lastSegment = parts.pop() || "";
135
+ currentSegment = lastSegment + "[]";
136
+ currentPart = "property";
137
+ } else {
138
+ const parsedNumber = Number.parseInt(currentSegment, 10);
139
+ const isValidInteger = !Number.isNaN(parsedNumber) && Number.isFinite(parsedNumber) && parsedNumber >= 0 && parsedNumber <= Number.MAX_SAFE_INTEGER && parsedNumber <= MAX_ARRAY_INDEX && currentSegment === String(parsedNumber);
140
+ if (isValidInteger) {
141
+ parts.push(parsedNumber);
142
+ } else {
143
+ parts.push(currentSegment);
144
+ }
145
+ currentSegment = "";
146
+ currentPart = "indexEnd";
147
+ }
148
+ break;
149
+ }
150
+ if (currentPart === "indexEnd") {
151
+ throw new Error(`Invalid character '${character}' after an index at position ${position}`);
152
+ }
153
+ currentSegment += character;
154
+ break;
155
+ }
156
+ default: {
157
+ if (currentPart === "index" && !isDigit(character)) {
158
+ throw new Error(`Invalid character '${character}' in an index at position ${position}`);
159
+ }
160
+ if (currentPart === "indexEnd") {
161
+ throw new Error(`Invalid character '${character}' after an index at position ${position}`);
162
+ }
163
+ if (currentPart === "start") {
164
+ currentPart = "property";
165
+ }
166
+ currentSegment += character;
167
+ }
168
+ }
169
+ }
170
+ if (isEscaping) {
171
+ currentSegment += "\\";
172
+ }
173
+ switch (currentPart) {
174
+ case "property": {
175
+ if (!processSegment(currentSegment, parts)) {
176
+ return [];
177
+ }
178
+ break;
179
+ }
180
+ case "index": {
181
+ throw new Error("Index was not closed");
182
+ }
183
+ case "start": {
184
+ parts.push("");
185
+ break;
186
+ }
187
+ }
188
+ return parts;
189
+ }
190
+ function normalizePath(path) {
191
+ if (typeof path === "string") {
192
+ return parsePath(path);
193
+ }
194
+ if (Array.isArray(path)) {
195
+ const normalized = [];
196
+ for (const [index, segment] of path.entries()) {
197
+ if (typeof segment !== "string" && typeof segment !== "number") {
198
+ throw new TypeError(`Expected a string or number for path segment at index ${index}, got ${typeof segment}`);
199
+ }
200
+ if (typeof segment === "number" && !Number.isFinite(segment)) {
201
+ throw new TypeError(`Path segment at index ${index} must be a finite number, got ${segment}`);
202
+ }
203
+ if (disallowedKeys.has(segment)) {
204
+ return [];
205
+ }
206
+ if (typeof segment === "string" && shouldCoerceToNumber(segment)) {
207
+ normalized.push(Number.parseInt(segment, 10));
208
+ } else {
209
+ normalized.push(segment);
210
+ }
211
+ }
212
+ return normalized;
213
+ }
214
+ return [];
215
+ }
216
+ function getProperty(object, path, value) {
217
+ if (!isObject(object) || typeof path !== "string" && !Array.isArray(path)) {
218
+ return value === void 0 ? object : value;
219
+ }
220
+ const pathArray = normalizePath(path);
221
+ if (pathArray.length === 0) {
222
+ return value;
223
+ }
224
+ for (let index = 0; index < pathArray.length; index++) {
225
+ const key = pathArray[index];
226
+ object = object[key];
227
+ if (object === void 0 || object === null) {
228
+ if (index !== pathArray.length - 1) {
229
+ return value;
230
+ }
231
+ break;
232
+ }
233
+ }
234
+ return object === void 0 ? value : object;
235
+ }
236
+ function hasProperty(object, path) {
237
+ if (!isObject(object) || typeof path !== "string" && !Array.isArray(path)) {
238
+ return false;
239
+ }
240
+ const pathArray = normalizePath(path);
241
+ if (pathArray.length === 0) {
242
+ return false;
243
+ }
244
+ for (const key of pathArray) {
245
+ if (!isObject(object) || !(key in object)) {
246
+ return false;
247
+ }
248
+ object = object[key];
249
+ }
250
+ return true;
251
+ }
252
+
253
+ const confirm = async (options) => {
254
+ const { default: defaultValue = false, message, transformer } = options;
255
+ const formatMessage = (message_) => {
256
+ const questionMark = styleText(["cyan", "bold"], "?");
257
+ const boldMessage = styleText(["bold"], message_);
258
+ const defaultHint = defaultValue ? `${styleText(["greenBright"], "Y")}${styleText(["gray"], "/n")}` : `y/${styleText(["yellowBright"], "N")}`;
259
+ return `${questionMark} ${boldMessage} ${styleText(["gray"], `(${defaultHint})`)}`;
260
+ };
261
+ const formatAnswer = (answer) => {
262
+ if (transformer) {
263
+ return transformer(answer);
264
+ }
265
+ return answer ? styleText(["greenBright"], "Yes") : styleText(["yellowBright"], "No");
266
+ };
267
+ return new Promise((resolve) => {
268
+ const rl = createInterface({
269
+ input: process.stdin,
270
+ output: process.stdout
271
+ });
272
+ const formattedMessage = formatMessage(message);
273
+ rl.question(formattedMessage, (answer) => {
274
+ rl.close();
275
+ const normalizedAnswer = answer.trim().toLowerCase();
276
+ if (normalizedAnswer === "") {
277
+ resolve(defaultValue);
278
+ return;
279
+ }
280
+ if (normalizedAnswer === "y" || normalizedAnswer === "yes") {
281
+ console.log(`${styleText(["greenBright"], "✓")} ${formatAnswer(true)}`);
282
+ resolve(true);
283
+ return;
284
+ }
285
+ if (normalizedAnswer === "n" || normalizedAnswer === "no") {
286
+ console.log(`${styleText(["yellowBright"], "✗")} ${formatAnswer(false)}`);
287
+ resolve(false);
288
+ return;
289
+ }
290
+ console.log(`${styleText(["gray"], "→")} ${formatAnswer(defaultValue)}`);
291
+ resolve(defaultValue);
292
+ });
293
+ rl.on("SIGINT", () => {
294
+ rl.close();
295
+ console.log(`
296
+ ${styleText(["gray"], "→")} ${formatAnswer(defaultValue)}`);
297
+ resolve(defaultValue);
298
+ });
299
+ });
300
+ };
301
+
302
+ const isNode = typeof process.stdout < "u" && !process.versions.deno && !globalThis.window;
303
+
304
+ const PackageJsonParseCache = /* @__PURE__ */ new Map();
305
+ const PackageJsonFileCache = /* @__PURE__ */ new Map();
306
+ class PackageJsonValidationError extends Error {
307
+ constructor(warnings) {
308
+ super(`The following warnings were encountered while normalizing package data:
309
+ - ${warnings.join("\n- ")}`);
310
+ this.name = "PackageJsonValidationError";
311
+ }
312
+ }
313
+ const normalizeInput = (input, strict, ignoreWarnings = []) => {
314
+ const warnings = [];
315
+ normalizeData(
316
+ input,
317
+ (message) => {
318
+ warnings.push(message);
319
+ },
320
+ strict
321
+ );
322
+ if (strict && warnings.length > 0) {
323
+ const filteredWarnings = warnings.filter(
324
+ (warning) => !ignoreWarnings.some((pattern) => {
325
+ if (pattern instanceof RegExp) {
326
+ return pattern.test(warning);
327
+ }
328
+ return pattern === warning;
329
+ })
330
+ );
331
+ if (filteredWarnings.length > 0) {
332
+ throw new PackageJsonValidationError(filteredWarnings);
333
+ }
334
+ }
335
+ return input;
336
+ };
337
+ const parseYamlFile = async (filePath) => {
338
+ const yamlData = await readYaml(filePath);
339
+ return yamlData;
340
+ };
341
+ const parseYamlFileSync = (filePath) => {
342
+ const yamlData = readYamlSync(filePath);
343
+ return yamlData;
344
+ };
345
+ const parseJson5File = async (filePath) => {
346
+ const text = await readFile(filePath);
347
+ return JSON5.parse(text);
348
+ };
349
+ const parseJson5FileSync = (filePath) => {
350
+ const text = readFileSync(filePath);
351
+ return JSON5.parse(text);
352
+ };
353
+ const parsePackageFile = async (filePath, options) => {
354
+ if (options?.yaml !== false && (filePath.endsWith(".yaml") || filePath.endsWith(".yml"))) {
355
+ return parseYamlFile(filePath);
356
+ }
357
+ if (options?.json5 !== false && filePath.endsWith(".json5")) {
358
+ return parseJson5File(filePath);
359
+ }
360
+ return readJson(filePath);
361
+ };
362
+ const parsePackageFileSync = (filePath, options) => {
363
+ if (options?.yaml !== false && (filePath.endsWith(".yaml") || filePath.endsWith(".yml"))) {
364
+ return parseYamlFileSync(filePath);
365
+ }
366
+ if (options?.json5 !== false && filePath.endsWith(".json5")) {
367
+ return parseJson5FileSync(filePath);
368
+ }
369
+ return readJsonSync(filePath);
370
+ };
371
+ const findPackageJson = async (cwd, options = {}) => {
372
+ const findUpConfig = {
373
+ type: "file"
374
+ };
375
+ if (cwd) {
376
+ findUpConfig.cwd = cwd;
377
+ }
378
+ const searchPatterns = ["package.json"];
379
+ if (options.yaml !== false) {
380
+ searchPatterns.push("package.yaml", "package.yml");
381
+ }
382
+ if (options.json5 !== false) {
383
+ searchPatterns.push("package.json5");
384
+ }
385
+ let filePath;
386
+ for await (const pattern of searchPatterns) {
387
+ filePath = await findUp(pattern, findUpConfig);
388
+ if (filePath) {
389
+ break;
390
+ }
391
+ }
392
+ if (!filePath) {
393
+ throw new NotFoundError(`No such file or directory, for ${searchPatterns.join(", ").replace(/, ([^,]*)$/, " or $1")} found.`);
394
+ }
395
+ const cache = options.cache && typeof options.cache !== "boolean" ? options.cache : PackageJsonFileCache;
396
+ if (options.cache && cache.has(filePath)) {
397
+ return cache.get(filePath);
398
+ }
399
+ const packageJson = await parsePackageFile(filePath, options);
400
+ if (options.resolveCatalogs) {
401
+ const catalogs = await readPnpmCatalogs(filePath);
402
+ if (catalogs) {
403
+ resolveCatalogReferences(packageJson, catalogs);
404
+ }
405
+ }
406
+ normalizeInput(packageJson, options.strict ?? false, options.ignoreWarnings);
407
+ const output = {
408
+ packageJson,
409
+ path: filePath
410
+ };
411
+ if (options.cache) {
412
+ cache.set(filePath, output);
413
+ }
414
+ return output;
415
+ };
416
+ const findPackageJsonSync = (cwd, options = {}) => {
417
+ const findUpConfig = {
418
+ type: "file"
419
+ };
420
+ if (cwd) {
421
+ findUpConfig.cwd = cwd;
422
+ }
423
+ const searchPatterns = ["package.json"];
424
+ if (options.yaml !== false) {
425
+ searchPatterns.push("package.yaml", "package.yml");
426
+ }
427
+ if (options.json5 !== false) {
428
+ searchPatterns.push("package.json5");
429
+ }
430
+ let filePath;
431
+ for (const pattern of searchPatterns) {
432
+ filePath = findUpSync(pattern, findUpConfig);
433
+ if (filePath) {
434
+ break;
435
+ }
436
+ }
437
+ if (!filePath) {
438
+ throw new NotFoundError(`No such file or directory, for ${searchPatterns.join(", ").replace(/, ([^,]*)$/, " or $1")} found.`);
439
+ }
440
+ const cache = options.cache && typeof options.cache !== "boolean" ? options.cache : PackageJsonFileCache;
441
+ if (options.cache && cache.has(filePath)) {
442
+ return cache.get(filePath);
443
+ }
444
+ const packageJson = parsePackageFileSync(filePath, options);
445
+ if (options.resolveCatalogs) {
446
+ const catalogs = readPnpmCatalogsSync(filePath);
447
+ if (catalogs) {
448
+ resolveCatalogReferences(packageJson, catalogs);
449
+ }
450
+ }
451
+ normalizeInput(packageJson, options.strict ?? false, options.ignoreWarnings);
452
+ const output = {
453
+ packageJson,
454
+ path: filePath
455
+ };
456
+ if (options.cache) {
457
+ cache.set(filePath, output);
458
+ }
459
+ return output;
460
+ };
461
+ const writePackageJson = async (data, options = {}) => {
462
+ const { cwd, ...writeOptions } = options;
463
+ const directory = toPath(cwd ?? process.cwd());
464
+ await writeJson(join(directory, "package.json"), data, writeOptions);
465
+ };
466
+ const writePackageJsonSync = (data, options = {}) => {
467
+ const { cwd, ...writeOptions } = options;
468
+ const directory = toPath(cwd ?? process.cwd());
469
+ writeJsonSync(join(directory, "package.json"), data, writeOptions);
470
+ };
471
+ const parsePackageJsonSync = (packageFile, options) => {
472
+ const isObject = packageFile !== null && typeof packageFile === "object" && !Array.isArray(packageFile);
473
+ const isString = typeof packageFile === "string";
474
+ if (!isObject && !isString) {
475
+ throw new TypeError("`packageFile` should be either an `object` or a `string`.");
476
+ }
477
+ let json;
478
+ let isFile = false;
479
+ let filePath;
480
+ if (isObject) {
481
+ json = structuredClone(packageFile);
482
+ } else if (existsSync(packageFile)) {
483
+ filePath = packageFile;
484
+ const cache = options?.cache && typeof options.cache !== "boolean" ? options.cache : PackageJsonParseCache;
485
+ if (options?.cache && cache.has(filePath)) {
486
+ return cache.get(filePath);
487
+ }
488
+ json = parsePackageFileSync(filePath, options);
489
+ isFile = true;
490
+ } else {
491
+ json = parseJson(packageFile);
492
+ }
493
+ if (options?.resolveCatalogs) {
494
+ if (isFile) {
495
+ const catalogs = readPnpmCatalogsSync(packageFile);
496
+ if (catalogs) {
497
+ resolveCatalogReferences(json, catalogs);
498
+ }
499
+ } else {
500
+ throw new Error("The 'resolveCatalogs' option can only be used on a file path.");
501
+ }
502
+ }
503
+ normalizeInput(json, options?.strict ?? false, options?.ignoreWarnings);
504
+ const result = json;
505
+ if (isFile && filePath && options?.cache) {
506
+ const cache = options.cache && typeof options.cache !== "boolean" ? options.cache : PackageJsonParseCache;
507
+ cache.set(filePath, result);
508
+ }
509
+ return result;
510
+ };
511
+ const parsePackageJson = async (packageFile, options) => {
512
+ const isObject = packageFile !== null && typeof packageFile === "object" && !Array.isArray(packageFile);
513
+ const isString = typeof packageFile === "string";
514
+ if (!isObject && !isString) {
515
+ throw new TypeError("`packageFile` should be either an `object` or a `string`.");
516
+ }
517
+ let json;
518
+ let isFile = false;
519
+ let filePath;
520
+ if (isObject) {
521
+ json = structuredClone(packageFile);
522
+ } else if (existsSync(packageFile)) {
523
+ filePath = packageFile;
524
+ const cache = options?.cache && typeof options.cache !== "boolean" ? options.cache : PackageJsonParseCache;
525
+ if (options?.cache && cache.has(filePath)) {
526
+ return cache.get(filePath);
527
+ }
528
+ json = await parsePackageFile(filePath, options);
529
+ isFile = true;
530
+ } else {
531
+ json = parseJson(packageFile);
532
+ }
533
+ if (options?.resolveCatalogs) {
534
+ if (isFile) {
535
+ const catalogs = await readPnpmCatalogs(packageFile);
536
+ if (catalogs) {
537
+ resolveCatalogReferences(json, catalogs);
538
+ }
539
+ } else {
540
+ throw new Error("The 'resolveCatalogs' option can only be used on a file path.");
541
+ }
542
+ }
543
+ normalizeInput(json, options?.strict ?? false, options?.ignoreWarnings);
544
+ const result = json;
545
+ if (isFile && filePath && options?.cache) {
546
+ const cache = options.cache && typeof options.cache !== "boolean" ? options.cache : PackageJsonParseCache;
547
+ cache.set(filePath, result);
548
+ }
549
+ return result;
550
+ };
551
+ const getPackageJsonProperty = (packageJson, property, defaultValue) => getProperty(packageJson, property, defaultValue);
552
+ const hasPackageJsonProperty = (packageJson, property) => hasProperty(packageJson, property);
553
+ const hasPackageJsonAnyDependency = (packageJson, arguments_, options) => {
554
+ const dependencies = getProperty(packageJson, "dependencies", {});
555
+ const devDependencies = getProperty(packageJson, "devDependencies", {});
556
+ const peerDependencies = getProperty(packageJson, "peerDependencies", {});
557
+ const allDependencies = { ...dependencies, ...devDependencies, ...options?.peerDeps === false ? {} : peerDependencies };
558
+ for (const argument of arguments_) {
559
+ if (hasProperty(allDependencies, argument)) {
560
+ return true;
561
+ }
562
+ }
563
+ return false;
564
+ };
565
+ const ensurePackages = async (packageJson, packages, installKey = "dependencies", options = {}) => {
566
+ const dependencies = getProperty(packageJson, "dependencies", {});
567
+ const devDependencies = getProperty(packageJson, "devDependencies", {});
568
+ const peerDependencies = getProperty(packageJson, "peerDependencies", {});
569
+ const nonExistingPackages = [];
570
+ const config = {
571
+ deps: true,
572
+ devDeps: true,
573
+ peerDeps: false,
574
+ ...options
575
+ };
576
+ for (const packageName of packages) {
577
+ if (config.deps && hasProperty(dependencies, packageName) || config.devDeps && hasProperty(devDependencies, packageName) || config.peerDeps && hasProperty(peerDependencies, packageName)) {
578
+ continue;
579
+ }
580
+ nonExistingPackages.push(packageName);
581
+ }
582
+ if (nonExistingPackages.length === 0) {
583
+ return;
584
+ }
585
+ if (process.env.CI || isNode && !process.stdout?.isTTY) {
586
+ const message = `Skipping package installation for [${packages.join(", ")}] because the process is not interactive.`;
587
+ if (options.throwOnWarn) {
588
+ throw new Error(message);
589
+ } else if (options.logger?.warn) {
590
+ options.logger.warn(message);
591
+ } else {
592
+ console.warn(message);
593
+ }
594
+ return;
595
+ }
596
+ if (typeof config.confirm?.message === "function") {
597
+ config.confirm.message = config.confirm.message(nonExistingPackages);
598
+ }
599
+ if (config.confirm?.message === void 0) {
600
+ const message = `${nonExistingPackages.length === 1 ? "Package is" : "Packages are"} required for this config: ${nonExistingPackages.join(", ")}. Do you want to install them?`;
601
+ if (config.confirm === void 0) {
602
+ config.confirm = {
603
+ message
604
+ };
605
+ } else {
606
+ config.confirm.message = message;
607
+ }
608
+ }
609
+ const answer = await confirm(config.confirm);
610
+ if (!answer) {
611
+ return;
612
+ }
613
+ await installPackage(nonExistingPackages, {
614
+ ...config.installPackage,
615
+ cwd: config.cwd ? toPath(config.cwd) : void 0,
616
+ dev: installKey === "devDependencies"
617
+ });
618
+ };
619
+
620
+ export { ensurePackages, findPackageJson, findPackageJsonSync, getPackageJsonProperty, hasPackageJsonAnyDependency, hasPackageJsonProperty, parsePackageJson, parsePackageJsonSync, writePackageJson, writePackageJsonSync };