fork of hey-api/openapi-ts because I need some additional things
1import path from 'node:path';
2
3import type { ExportModule, File, ImportModule } from '@hey-api/codegen-core';
4
5import { py } from '../../ts-python';
6
7const printer = py.createPrinter({
8 indentSize: 4,
9});
10
11/** Print a Python node to a string. */
12export function astToString(node: py.Node): string {
13 const result = printer.printFile(node);
14 return result;
15}
16
17export type SortGroup = number;
18export type SortDistance = number;
19export type SortModule = string;
20export type SortKey = [SortGroup, SortDistance, SortModule];
21
22export type ModuleExport = Omit<ExportModule, 'from'> & {
23 /** Module specifier for re-exports, e.g. `./foo`. */
24 modulePath: string;
25};
26
27export type ModuleImport = Omit<ImportModule, 'from'> & {
28 /** Module specifier for imports, e.g. `./foo`. */
29 modulePath: string;
30};
31
32export function moduleSortKey({
33 file,
34 fromFile,
35 root,
36}: {
37 file: Pick<File, 'finalPath'>;
38 fromFile: Pick<File, 'finalPath' | 'extension' | 'external' | 'name'>;
39 preferFileExtension: string;
40 root: string;
41}): SortKey {
42 const filePath = file.finalPath!.split(path.sep).join('/');
43 let modulePath = fromFile.finalPath!.split(path.sep).join('/');
44
45 // built-ins
46 // TODO
47
48 // external
49 if (fromFile.external && !path.isAbsolute(modulePath)) {
50 return [0, 0, modulePath];
51 }
52
53 // outside project root
54 if (!modulePath.startsWith(root.split(path.sep).join('/'))) {
55 return [1, 0, modulePath];
56 }
57
58 // local
59 const rel = path
60 .relative(path.dirname(filePath), path.dirname(modulePath))
61 .split(path.sep)
62 .join('/');
63
64 const segments = rel ? rel.split('/') : [];
65 const parentCount = segments.filter((s) => s === '..').length;
66
67 const leadingDots = '.'.repeat(parentCount + 1);
68
69 const pathSegments = segments.filter((s) => s !== '..' && s !== '.');
70
71 const filename = modulePath.split('/').at(-1)!;
72 // TODO: replace with extension check, there's an issue with external files
73 // not having extension set
74 const moduleName = filename.replace(/\.[^.]+$/, '');
75 // const moduleName = fromFile.extension
76 // ? filename.slice(0, -fromFile.extension.length)
77 // : filename;
78
79 // index/__init__ are implicit
80 const isImplicitModule = moduleName === 'index' || moduleName === '__init__';
81 if (!isImplicitModule) {
82 pathSegments.push(moduleName);
83 }
84
85 modulePath = pathSegments.length > 0 ? leadingDots + pathSegments.join('.') : leadingDots;
86
87 return [2, parentCount, modulePath];
88}