@kubb/agent 5.0.0-alpha.33 → 5.0.0-alpha.35

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.
Files changed (30) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/server/chunks/nitro/nitro.mjs +2173 -1924
  3. package/.output/server/chunks/nitro/nitro.mjs.map +1 -1
  4. package/.output/server/chunks/routes/api/health.get.mjs +1 -1
  5. package/.output/server/index.mjs +1 -1
  6. package/.output/server/node_modules/@redocly/config/lib/root-config-schema.js +11 -1
  7. package/.output/server/node_modules/@redocly/config/package.json +1 -1
  8. package/.output/server/node_modules/@redocly/openapi-core/lib/bundle/bundle-document.js +25 -10
  9. package/.output/server/node_modules/@redocly/openapi-core/lib/bundle/bundle-visitor.js +32 -29
  10. package/.output/server/node_modules/@redocly/openapi-core/lib/config/config.js +5 -0
  11. package/.output/server/node_modules/@redocly/openapi-core/lib/decorators/oas2/index.js +1 -1
  12. package/.output/server/node_modules/@redocly/openapi-core/lib/decorators/oas2/remove-unused-components.js +47 -38
  13. package/.output/server/node_modules/@redocly/openapi-core/lib/decorators/oas3/index.js +1 -1
  14. package/.output/server/node_modules/@redocly/openapi-core/lib/decorators/oas3/remove-unused-components.js +45 -41
  15. package/.output/server/node_modules/@redocly/openapi-core/lib/rules/common/no-http-verbs-in-paths.js +3 -1
  16. package/.output/server/node_modules/@redocly/openapi-core/lib/rules/common/no-required-schema-properties-undefined.js +41 -55
  17. package/.output/server/node_modules/@redocly/openapi-core/lib/walk.js +28 -16
  18. package/.output/server/node_modules/@redocly/openapi-core/package.json +2 -2
  19. package/.output/server/package.json +3 -4
  20. package/package.json +20 -20
  21. package/.output/server/node_modules/empathic/access.js +0 -39
  22. package/.output/server/node_modules/empathic/access.mjs +0 -34
  23. package/.output/server/node_modules/empathic/find.js +0 -81
  24. package/.output/server/node_modules/empathic/find.mjs +0 -76
  25. package/.output/server/node_modules/empathic/package.json +0 -49
  26. package/.output/server/node_modules/empathic/package.mjs +0 -52
  27. package/.output/server/node_modules/empathic/resolve.js +0 -31
  28. package/.output/server/node_modules/empathic/resolve.mjs +0 -27
  29. package/.output/server/node_modules/empathic/walk.js +0 -22
  30. package/.output/server/node_modules/empathic/walk.mjs +0 -20
@@ -1,5 +1,6 @@
1
- import { isRef } from '../../ref-utils.js';
2
1
  import { getOwn } from '../../utils/get-own.js';
2
+ import { isNotEmptyArray } from '../../utils/is-not-empty-array.js';
3
+ import { resolveSchema } from '../utils.js';
3
4
  export const NoRequiredSchemaPropertiesUndefined = () => {
4
5
  const parents = [];
5
6
  return {
@@ -7,67 +8,52 @@ export const NoRequiredSchemaPropertiesUndefined = () => {
7
8
  leave(_) {
8
9
  parents.pop();
9
10
  },
10
- enter(schema, { location, report, resolve }) {
11
- parents.push(schema);
12
- if (!schema.required)
11
+ enter(currentSchema, ctx) {
12
+ parents.push(currentSchema);
13
+ if (!currentSchema.required)
13
14
  return;
14
- const visitedSchemas = new Set();
15
- const elevateProperties = (schema, from, includeFirstLevelExclusiveSchemas = true) => {
16
- // Check if the schema has been visited before processing it
17
- if (visitedSchemas.has(schema)) {
18
- return {};
15
+ const hasProperty = (schemaOrRef, propertyName, visited, resolveFrom) => {
16
+ const { schema, location } = resolveSchema(schemaOrRef, ctx, resolveFrom);
17
+ if (!schema || visited.has(schema))
18
+ return false;
19
+ visited.add(schema);
20
+ if (schema.properties && getOwn(schema.properties, propertyName) !== undefined) {
21
+ return true;
19
22
  }
20
- visitedSchemas.add(schema);
21
- if (isRef(schema)) {
22
- const resolved = resolve(schema, from);
23
- if (!resolved.node) {
24
- return {};
25
- }
26
- return elevateProperties(resolved.node, resolved.location?.source.absoluteRef);
23
+ if (schema.allOf?.some((s) => hasProperty(s, propertyName, visited, location))) {
24
+ return true;
27
25
  }
28
- return Object.assign({}, schema.properties, ...(schema.allOf?.map((s) => elevateProperties(s, from)) ?? []), ...(('anyOf' in schema && includeFirstLevelExclusiveSchemas
29
- ? schema.anyOf?.map((s) => elevateProperties(s, from))
30
- : undefined) ?? []), ...(('oneOf' in schema && includeFirstLevelExclusiveSchemas
31
- ? schema.oneOf?.map((s) => elevateProperties(s, from))
32
- : undefined) ?? []));
26
+ if (isNotEmptyArray(schema.anyOf) &&
27
+ schema.anyOf.every((s) => hasProperty(s, propertyName, new Set(visited), location))) {
28
+ return true;
29
+ }
30
+ if (isNotEmptyArray(schema.oneOf) &&
31
+ schema.oneOf.every((s) => hasProperty(s, propertyName, new Set(visited), location))) {
32
+ return true;
33
+ }
34
+ return false;
33
35
  };
34
- /**
35
- * The index to use to lookup grand parent schemas when dealing with composed schemas.
36
- * @summary The current schema should always end up with under ../anyOf/1, if we get multiple ancestors, they should always be a multiple.
37
- */
38
- const locationLookupIndex = 2;
39
- const getParentSchema = (lookupIndex) => {
40
- lookupIndex++;
41
- if (!parents || parents.length < lookupIndex)
42
- return undefined;
43
- const parent = parents[parents.length - lookupIndex];
44
- return parent;
36
+ const isCompositionChild = (parent, child) => {
37
+ const matchesChild = (s) => resolveSchema(s, ctx).schema === child;
38
+ return !!(parent.allOf?.some(matchesChild) ||
39
+ parent.anyOf?.some(matchesChild) ||
40
+ parent.oneOf?.some(matchesChild));
45
41
  };
46
- const recursivelyGetParentProperties = (splitLocation, parentLookupIndex = 0) => {
47
- const isMemberOfComposedType = splitLocation.length > locationLookupIndex &&
48
- !isNaN(parseInt(splitLocation[splitLocation.length - 1])) &&
49
- !!/(allOf|oneOf|anyOf)/.exec(splitLocation[splitLocation.length - locationLookupIndex]);
50
- const parentSchema = isMemberOfComposedType
51
- ? getParentSchema(++parentLookupIndex)
52
- : undefined;
53
- const grandParentProperties = splitLocation.length >= locationLookupIndex + locationLookupIndex
54
- ? recursivelyGetParentProperties(splitLocation.slice(0, -locationLookupIndex), parentLookupIndex)
55
- : {};
56
- return parentSchema
57
- ? {
58
- ...elevateProperties(parentSchema, undefined, false),
59
- ...grandParentProperties,
60
- }
42
+ const findCompositionRoot = (i, child) => {
43
+ if (i < 0)
44
+ return undefined;
45
+ const parent = parents[i];
46
+ return isCompositionChild(parent, child)
47
+ ? (findCompositionRoot(i - 1, parent) ?? parent)
61
48
  : undefined;
62
49
  };
63
- const allProperties = elevateProperties(schema);
64
- const parentProperties = recursivelyGetParentProperties(location.pointer.split('/'));
65
- for (const [i, requiredProperty] of schema.required.entries()) {
66
- if ((!allProperties || getOwn(allProperties, requiredProperty) === undefined) &&
67
- (!parentProperties || getOwn(parentProperties, requiredProperty) === undefined)) {
68
- report({
69
- message: `Required property '${requiredProperty}' is undefined.`,
70
- location: location.child(['required', i]),
50
+ const compositionRoot = findCompositionRoot(parents.length - 2, currentSchema);
51
+ for (const [i, requiredProperty] of currentSchema.required.entries()) {
52
+ if (!hasProperty(currentSchema, requiredProperty, new Set()) &&
53
+ !hasProperty(compositionRoot, requiredProperty, new Set())) {
54
+ ctx.report({
55
+ message: `Required property '${requiredProperty}' is not defined.`,
56
+ location: ctx.location.child(['required', i]),
71
57
  });
72
58
  }
73
59
  }
@@ -27,6 +27,17 @@ export function walkDocument(opts) {
27
27
  const { document, rootType, normalizedVisitors, resolvedRefMap, ctx } = opts;
28
28
  const seenNodesPerType = {};
29
29
  const ignoredNodes = new Set();
30
+ // Pre-compute combined enter/leave arrays per type to avoid per-node array allocations
31
+ const anyEnter = normalizedVisitors.any.enter;
32
+ const anyLeave = normalizedVisitors.any.leave;
33
+ const combinedEnter = {};
34
+ const combinedLeave = {};
35
+ for (const typeName of Object.keys(normalizedVisitors)) {
36
+ if (typeName === 'any' || typeName === 'ref')
37
+ continue;
38
+ combinedEnter[typeName] = anyEnter.concat(normalizedVisitors[typeName]?.enter || []);
39
+ combinedLeave[typeName] = (normalizedVisitors[typeName]?.leave || []).concat(anyLeave);
40
+ }
30
41
  walkNode(document.parsed, rootType, new Location(document.source, '#/'), undefined, '');
31
42
  function walkNode(node, type, location, parent, key) {
32
43
  const resolve = (ref, from = currentLocation.source.absoluteRef) => {
@@ -50,13 +61,14 @@ export function walkDocument(opts) {
50
61
  };
51
62
  const rawLocation = location;
52
63
  let currentLocation = location;
64
+ const nodeIsRef = isRef(node);
53
65
  const { node: resolvedNode, location: resolvedLocation, error } = resolve(node);
54
66
  const enteredContexts = new Set();
55
- if (isRef(node)) {
67
+ if (nodeIsRef) {
56
68
  const refEnterVisitors = normalizedVisitors.ref.enter;
57
69
  for (const { visit: visitor, ruleId, severity, message, context } of refEnterVisitors) {
58
70
  enteredContexts.add(context);
59
- const report = reportFn.bind(undefined, ruleId, severity, message);
71
+ const report = (opts) => reportFn(ruleId, severity, message, opts);
60
72
  visitor(node, {
61
73
  report,
62
74
  resolve,
@@ -69,7 +81,7 @@ export function walkDocument(opts) {
69
81
  parentLocations: {},
70
82
  specVersion: ctx.specVersion,
71
83
  config: ctx.config,
72
- getVisitorData: getVisitorDataFn.bind(undefined, ruleId),
84
+ getVisitorData: () => getVisitorDataFn(ruleId),
73
85
  }, { node: resolvedNode, location: resolvedLocation, error });
74
86
  if (resolvedLocation?.source.absoluteRef && ctx.refTypes) {
75
87
  ctx.refTypes.set(resolvedLocation?.source.absoluteRef, type);
@@ -80,11 +92,11 @@ export function walkDocument(opts) {
80
92
  currentLocation = resolvedLocation;
81
93
  const isNodeSeen = seenNodesPerType[type.name]?.has?.(resolvedNode);
82
94
  let visitedBySome = false;
83
- const anyEnterVisitors = normalizedVisitors.any.enter;
84
- const currentEnterVisitors = anyEnterVisitors.concat(normalizedVisitors[type.name]?.enter || []);
95
+ const currentEnterVisitors = combinedEnter[type.name] || anyEnter.concat(normalizedVisitors[type.name]?.enter || []);
85
96
  const activatedContexts = [];
97
+ const ignoreKey = `${currentLocation.absolutePointer}${currentLocation.pointer}`;
86
98
  for (const { context, visit, skip, ruleId, severity, message } of currentEnterVisitors) {
87
- if (ignoredNodes.has(`${currentLocation.absolutePointer}${currentLocation.pointer}`))
99
+ if (ignoredNodes.has(ignoreKey))
88
100
  break;
89
101
  if (context.isSkippedLevel) {
90
102
  if (context.parent.activatedOn &&
@@ -141,8 +153,9 @@ export function walkDocument(opts) {
141
153
  if (itemsType !== undefined) {
142
154
  const isTypeAFunction = typeof itemsType === 'function';
143
155
  for (let i = 0; i < resolvedNode.length; i++) {
156
+ const itemLocation = resolvedLocation.child([i]);
144
157
  let itemType = isTypeAFunction
145
- ? itemsType(resolvedNode[i], resolvedLocation.child([i]).absolutePointer)
158
+ ? itemsType(resolvedNode[i], itemLocation.absolutePointer)
146
159
  : itemsType;
147
160
  let itemValue = resolvedNode[i];
148
161
  if (itemType?.directResolveAs) {
@@ -150,7 +163,7 @@ export function walkDocument(opts) {
150
163
  itemValue = { $ref: itemValue };
151
164
  }
152
165
  if (isNamedType(itemType)) {
153
- walkNode(itemValue, itemType, resolvedLocation.child([i]), resolvedNode, i);
166
+ walkNode(itemValue, itemType, itemLocation, resolvedNode, i);
154
167
  }
155
168
  }
156
169
  }
@@ -164,7 +177,7 @@ export function walkDocument(opts) {
164
177
  else if (type.extensionsPrefix) {
165
178
  props.push(...Object.keys(resolvedNode).filter((k) => k.startsWith(type.extensionsPrefix)));
166
179
  }
167
- if (isRef(node)) {
180
+ if (nodeIsRef) {
168
181
  props.push(...Object.keys(node).filter((k) => k !== '$ref' && !props.includes(k))); // properties on the same level as $ref
169
182
  }
170
183
  for (const propName of props) {
@@ -202,8 +215,7 @@ export function walkDocument(opts) {
202
215
  }
203
216
  }
204
217
  }
205
- const anyLeaveVisitors = normalizedVisitors.any.leave;
206
- const currentLeaveVisitors = (normalizedVisitors[type.name]?.leave || []).concat(anyLeaveVisitors);
218
+ const currentLeaveVisitors = combinedLeave[type.name] || (normalizedVisitors[type.name]?.leave || []).concat(anyLeave);
207
219
  for (const context of activatedContexts.reverse()) {
208
220
  if (context.isSkippedLevel) {
209
221
  context.seen.delete(resolvedNode);
@@ -226,11 +238,11 @@ export function walkDocument(opts) {
226
238
  }
227
239
  }
228
240
  currentLocation = location;
229
- if (isRef(node)) {
241
+ if (nodeIsRef) {
230
242
  const refLeaveVisitors = normalizedVisitors.ref.leave;
231
243
  for (const { visit: visitor, ruleId, severity, context, message } of refLeaveVisitors) {
232
244
  if (enteredContexts.has(context)) {
233
- const report = reportFn.bind(undefined, ruleId, severity, message);
245
+ const report = (opts) => reportFn(ruleId, severity, message, opts);
234
246
  visitor(node, {
235
247
  report,
236
248
  resolve,
@@ -243,14 +255,14 @@ export function walkDocument(opts) {
243
255
  parentLocations: {},
244
256
  specVersion: ctx.specVersion,
245
257
  config: ctx.config,
246
- getVisitorData: getVisitorDataFn.bind(undefined, ruleId),
258
+ getVisitorData: () => getVisitorDataFn(ruleId),
247
259
  }, { node: resolvedNode, location: resolvedLocation, error });
248
260
  }
249
261
  }
250
262
  }
251
263
  // returns true ignores all the next visitors on the specific node
252
264
  function visitWithContext(visit, resolvedNode, node, context, ruleId, severity, customMessage) {
253
- const report = reportFn.bind(undefined, ruleId, severity, customMessage);
265
+ const report = (opts) => reportFn(ruleId, severity, customMessage, opts);
254
266
  visit(resolvedNode, {
255
267
  report,
256
268
  resolve,
@@ -266,7 +278,7 @@ export function walkDocument(opts) {
266
278
  ignoreNextVisitorsOnNode: () => {
267
279
  ignoredNodes.add(`${currentLocation.absolutePointer}${currentLocation.pointer}`);
268
280
  },
269
- getVisitorData: getVisitorDataFn.bind(undefined, ruleId),
281
+ getVisitorData: () => getVisitorDataFn(ruleId),
270
282
  }, collectParents(context), context);
271
283
  }
272
284
  function reportFn(ruleId, severity, customMessage, opts) {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/openapi-core",
3
- "version": "2.25.4",
3
+ "version": "2.28.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "types": "lib/index.d.ts",
@@ -53,7 +53,7 @@
53
53
  ],
54
54
  "dependencies": {
55
55
  "@redocly/ajv": "^8.18.0",
56
- "@redocly/config": "^0.46.0",
56
+ "@redocly/config": "^0.48.0",
57
57
  "ajv": "npm:@redocly/ajv@8.18.0",
58
58
  "ajv-formats": "^3.0.1",
59
59
  "colorette": "^1.2.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubb/agent-prod",
3
- "version": "5.0.0-alpha.33",
3
+ "version": "5.0.0-alpha.35",
4
4
  "type": "module",
5
5
  "private": true,
6
6
  "dependencies": {
@@ -20,8 +20,8 @@
20
20
  "@readme/openapi-schemas": "3.1.0",
21
21
  "@readme/postman-to-openapi": "4.1.0",
22
22
  "@redocly/ajv": "8.18.3",
23
- "@redocly/config": "0.46.1",
24
- "@redocly/openapi-core": "2.25.4",
23
+ "@redocly/config": "0.48.0",
24
+ "@redocly/openapi-core": "2.28.0",
25
25
  "@stoplight/ordered-object-literal": "1.0.5",
26
26
  "@stoplight/types": "14.1.1",
27
27
  "@stoplight/yaml": "4.3.0",
@@ -37,7 +37,6 @@
37
37
  "compute-lcm": "1.1.2",
38
38
  "consola": "3.4.2",
39
39
  "d": "1.0.2",
40
- "empathic": "2.0.0",
41
40
  "es5-ext": "0.10.64",
42
41
  "es6-symbol": "3.1.4",
43
42
  "event-emitter": "0.3.5",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubb/agent",
3
- "version": "5.0.0-alpha.33",
3
+ "version": "5.0.0-alpha.35",
4
4
  "description": "Agent server for Kubb, enabling HTTP-based access to code generation capabilities.",
5
5
  "keywords": [
6
6
  "agent",
@@ -39,28 +39,28 @@
39
39
  "tinyexec": "^1.1.1",
40
40
  "unstorage": "^1.17.5",
41
41
  "ws": "^8.20.0",
42
- "@kubb/adapter-oas": "5.0.0-alpha.33",
43
- "@kubb/ast": "5.0.0-alpha.33",
44
- "@kubb/core": "5.0.0-alpha.33",
45
- "@kubb/parser-ts": "5.0.0-alpha.33",
46
- "@kubb/plugin-client": "5.0.0-alpha.33",
47
- "@kubb/plugin-cypress": "5.0.0-alpha.33",
48
- "@kubb/plugin-faker": "5.0.0-alpha.33",
49
- "@kubb/plugin-mcp": "5.0.0-alpha.33",
50
- "@kubb/plugin-msw": "5.0.0-alpha.33",
51
- "@kubb/plugin-oas": "5.0.0-alpha.33",
52
- "@kubb/plugin-react-query": "5.0.0-alpha.33",
53
- "@kubb/plugin-redoc": "5.0.0-alpha.33",
54
- "@kubb/plugin-solid-query": "5.0.0-alpha.33",
55
- "@kubb/plugin-svelte-query": "5.0.0-alpha.33",
56
- "@kubb/plugin-swr": "5.0.0-alpha.33",
57
- "@kubb/plugin-ts": "5.0.0-alpha.33",
58
- "@kubb/plugin-vue-query": "5.0.0-alpha.33",
59
- "@kubb/plugin-zod": "5.0.0-alpha.33"
42
+ "@kubb/adapter-oas": "5.0.0-alpha.35",
43
+ "@kubb/core": "5.0.0-alpha.35",
44
+ "@kubb/plugin-client": "5.0.0-alpha.35",
45
+ "@kubb/ast": "5.0.0-alpha.35",
46
+ "@kubb/parser-ts": "5.0.0-alpha.35",
47
+ "@kubb/plugin-cypress": "5.0.0-alpha.35",
48
+ "@kubb/plugin-faker": "5.0.0-alpha.35",
49
+ "@kubb/plugin-mcp": "5.0.0-alpha.35",
50
+ "@kubb/plugin-oas": "5.0.0-alpha.35",
51
+ "@kubb/plugin-react-query": "5.0.0-alpha.35",
52
+ "@kubb/plugin-msw": "5.0.0-alpha.35",
53
+ "@kubb/plugin-redoc": "5.0.0-alpha.35",
54
+ "@kubb/plugin-solid-query": "5.0.0-alpha.35",
55
+ "@kubb/plugin-swr": "5.0.0-alpha.35",
56
+ "@kubb/plugin-ts": "5.0.0-alpha.35",
57
+ "@kubb/plugin-vue-query": "5.0.0-alpha.35",
58
+ "@kubb/plugin-svelte-query": "5.0.0-alpha.35",
59
+ "@kubb/plugin-zod": "5.0.0-alpha.35"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@types/ws": "^8.18.1",
63
- "msw": "^2.13.0",
63
+ "msw": "^2.13.3",
64
64
  "nitropack": "^2.13.3",
65
65
  "vite": "^7.3.2",
66
66
  "@internals/utils": "0.0.0"
@@ -1,39 +0,0 @@
1
- // re-export existsSync?
2
- const { accessSync, constants } = require("node:fs");
3
- /**
4
- * Does the current process have {@link mode} access?
5
- * By default, checks if the path is visible to the proccess.
6
- *
7
- * @param mode A `fs.constants` value; default `F_OK`
8
- */
9
- function ok(path, mode) {
10
- try {
11
- accessSync(path, mode);
12
- return true;
13
- } catch {
14
- return false;
15
- }
16
- }
17
- /**
18
- * Can the current process write to this path?
19
- */
20
- function writable(path) {
21
- return ok(path, constants.W_OK);
22
- }
23
- /**
24
- * Can the current process read this path?
25
- */
26
- function readable(path) {
27
- return ok(path, constants.R_OK);
28
- }
29
- /**
30
- * Can the current process execute this path?
31
- */
32
- function executable(path) {
33
- return ok(path, constants.X_OK);
34
- }
35
-
36
- exports.ok = ok;
37
- exports.writable = writable;
38
- exports.readable = readable;
39
- exports.executable = executable;
@@ -1,34 +0,0 @@
1
- // re-export existsSync?
2
- import { accessSync, constants } from "node:fs";
3
- /**
4
- * Does the current process have {@link mode} access?
5
- * By default, checks if the path is visible to the proccess.
6
- *
7
- * @param mode A `fs.constants` value; default `F_OK`
8
- */
9
- export function ok(path, mode) {
10
- try {
11
- accessSync(path, mode);
12
- return true;
13
- } catch {
14
- return false;
15
- }
16
- }
17
- /**
18
- * Can the current process write to this path?
19
- */
20
- export function writable(path) {
21
- return ok(path, constants.W_OK);
22
- }
23
- /**
24
- * Can the current process read this path?
25
- */
26
- export function readable(path) {
27
- return ok(path, constants.R_OK);
28
- }
29
- /**
30
- * Can the current process execute this path?
31
- */
32
- export function executable(path) {
33
- return ok(path, constants.X_OK);
34
- }
@@ -1,81 +0,0 @@
1
- const { join } = require("node:path");
2
- const { existsSync, statSync } = require("node:fs");
3
- const walk = require("empathic/walk");
4
- /**
5
- * Find an item by name, walking parent directories until found.
6
- *
7
- * @param name The item name to find.
8
- * @returns The absolute path to the item, if found.
9
- */
10
- function up(name, options) {
11
- let dir, tmp;
12
- let start = options && options.cwd || "";
13
- for (dir of walk.up(start, options)) {
14
- tmp = join(dir, name);
15
- if (existsSync(tmp)) return tmp;
16
- }
17
- }
18
- /**
19
- * Get the first path that matches any of the names provided.
20
- *
21
- * > [NOTE]
22
- * > The order of {@link names} is respected.
23
- *
24
- * @param names The item names to find.
25
- * @returns The absolute path of the first item found, if any.
26
- */
27
- function any(names, options) {
28
- let dir, start = options && options.cwd || "";
29
- let j = 0, len = names.length, tmp;
30
- for (dir of walk.up(start, options)) {
31
- for (j = 0; j < len; j++) {
32
- tmp = join(dir, names[j]);
33
- if (existsSync(tmp)) return tmp;
34
- }
35
- }
36
- }
37
- /**
38
- * Find a file by name, walking parent directories until found.
39
- *
40
- * > [NOTE]
41
- * > This function only returns a value for file matches.
42
- * > A directory match with the same name will be ignored.
43
- *
44
- * @param name The file name to find.
45
- * @returns The absolute path to the file, if found.
46
- */
47
- function file(name, options) {
48
- let dir, tmp;
49
- let start = options && options.cwd || "";
50
- for (dir of walk.up(start, options)) {
51
- try {
52
- tmp = join(dir, name);
53
- if (statSync(tmp).isFile()) return tmp;
54
- } catch {}
55
- }
56
- }
57
- /**
58
- * Find a directory by name, walking parent directories until found.
59
- *
60
- * > [NOTE]
61
- * > This function only returns a value for directory matches.
62
- * > A file match with the same name will be ignored.
63
- *
64
- * @param name The directory name to find.
65
- * @returns The absolute path to the file, if found.
66
- */
67
- function dir(name, options) {
68
- let dir, tmp;
69
- let start = options && options.cwd || "";
70
- for (dir of walk.up(start, options)) {
71
- try {
72
- tmp = join(dir, name);
73
- if (statSync(tmp).isDirectory()) return tmp;
74
- } catch {}
75
- }
76
- }
77
-
78
- exports.up = up;
79
- exports.any = any;
80
- exports.file = file;
81
- exports.dir = dir;
@@ -1,76 +0,0 @@
1
- import { join } from "node:path";
2
- import { existsSync, statSync } from "node:fs";
3
- import * as walk from "empathic/walk";
4
- /**
5
- * Find an item by name, walking parent directories until found.
6
- *
7
- * @param name The item name to find.
8
- * @returns The absolute path to the item, if found.
9
- */
10
- export function up(name, options) {
11
- let dir, tmp;
12
- let start = options && options.cwd || "";
13
- for (dir of walk.up(start, options)) {
14
- tmp = join(dir, name);
15
- if (existsSync(tmp)) return tmp;
16
- }
17
- }
18
- /**
19
- * Get the first path that matches any of the names provided.
20
- *
21
- * > [NOTE]
22
- * > The order of {@link names} is respected.
23
- *
24
- * @param names The item names to find.
25
- * @returns The absolute path of the first item found, if any.
26
- */
27
- export function any(names, options) {
28
- let dir, start = options && options.cwd || "";
29
- let j = 0, len = names.length, tmp;
30
- for (dir of walk.up(start, options)) {
31
- for (j = 0; j < len; j++) {
32
- tmp = join(dir, names[j]);
33
- if (existsSync(tmp)) return tmp;
34
- }
35
- }
36
- }
37
- /**
38
- * Find a file by name, walking parent directories until found.
39
- *
40
- * > [NOTE]
41
- * > This function only returns a value for file matches.
42
- * > A directory match with the same name will be ignored.
43
- *
44
- * @param name The file name to find.
45
- * @returns The absolute path to the file, if found.
46
- */
47
- export function file(name, options) {
48
- let dir, tmp;
49
- let start = options && options.cwd || "";
50
- for (dir of walk.up(start, options)) {
51
- try {
52
- tmp = join(dir, name);
53
- if (statSync(tmp).isFile()) return tmp;
54
- } catch {}
55
- }
56
- }
57
- /**
58
- * Find a directory by name, walking parent directories until found.
59
- *
60
- * > [NOTE]
61
- * > This function only returns a value for directory matches.
62
- * > A file match with the same name will be ignored.
63
- *
64
- * @param name The directory name to find.
65
- * @returns The absolute path to the file, if found.
66
- */
67
- export function dir(name, options) {
68
- let dir, tmp;
69
- let start = options && options.cwd || "";
70
- for (dir of walk.up(start, options)) {
71
- try {
72
- tmp = join(dir, name);
73
- if (statSync(tmp).isDirectory()) return tmp;
74
- } catch {}
75
- }
76
- }
@@ -1,49 +0,0 @@
1
- {
2
- "name": "empathic",
3
- "version": "2.0.0",
4
- "repository": "lukeed/empathic",
5
- "description": "A set of small and fast Node.js utilities to understand your pathing needs.",
6
- "license": "MIT",
7
- "author": {
8
- "name": "Luke Edwards",
9
- "email": "luke.edwards05@gmail.com",
10
- "url": "https://lukeed.com"
11
- },
12
- "exports": {
13
- "./access": {
14
- "types": "./access.d.ts",
15
- "import": "./access.mjs",
16
- "require": "./access.js"
17
- },
18
- "./find": {
19
- "types": "./find.d.ts",
20
- "import": "./find.mjs",
21
- "require": "./find.js"
22
- },
23
- "./package": {
24
- "types": "./package.d.ts",
25
- "import": "./package.mjs",
26
- "require": "./package.js"
27
- },
28
- "./resolve": {
29
- "types": "./resolve.d.ts",
30
- "import": "./resolve.mjs",
31
- "require": "./resolve.js"
32
- },
33
- "./walk": {
34
- "types": "./walk.d.ts",
35
- "import": "./walk.mjs",
36
- "require": "./walk.js"
37
- },
38
- "./package.json": "./package.json"
39
- },
40
- "scripts": {
41
- "test": "uvu"
42
- },
43
- "engines": {
44
- "node": ">=14"
45
- },
46
- "devDependencies": {
47
- "uvu": "0.5"
48
- }
49
- }