@webneat/codewiki 0.0.1
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 +21 -0
- package/README.md +59 -0
- package/dist/cli/bin.cjs +3206 -0
- package/dist/cli/bin.cjs.map +1 -0
- package/dist/cli/bin.d.cts +1 -0
- package/dist/cli/bin.d.ts +1 -0
- package/dist/cli/bin.js +3183 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/index.cjs +3209 -0
- package/dist/cli/index.cjs.map +1 -0
- package/dist/cli/index.d.cts +5 -0
- package/dist/cli/index.d.ts +5 -0
- package/dist/cli/index.js +3179 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.cjs +2453 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1678 -0
- package/dist/index.d.ts +1678 -0
- package/dist/index.js +2418 -0
- package/dist/index.js.map +1 -0
- package/migrations/v0.0.1.sql +138 -0
- package/package.json +75 -0
package/dist/cli/bin.js
ADDED
|
@@ -0,0 +1,3183 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __export = (target, all3) => {
|
|
4
|
+
for (var name in all3)
|
|
5
|
+
__defProp(target, name, { get: all3[name], enumerable: true });
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// src/cli/env.ts
|
|
9
|
+
import { existsSync } from "fs";
|
|
10
|
+
|
|
11
|
+
// src/internals/context.ts
|
|
12
|
+
import ts from "typescript";
|
|
13
|
+
import { fileURLToPath } from "url";
|
|
14
|
+
import Database from "better-sqlite3";
|
|
15
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
16
|
+
import path, { dirname, join as join2 } from "path";
|
|
17
|
+
import { drizzle } from "drizzle-orm/better-sqlite3";
|
|
18
|
+
|
|
19
|
+
// src/internals/errors.ts
|
|
20
|
+
import create_errors from "@webneat/errors";
|
|
21
|
+
var err = create_errors({
|
|
22
|
+
file_outside_project_path: (data) => `File "${data.file_path}" is outside project path "${data.project_path}"`,
|
|
23
|
+
file_not_found: (data) => `File not found: ${data.path}`,
|
|
24
|
+
db_error: (data) => `Database error in ${data.operation}: ${data.reason}`,
|
|
25
|
+
symbol_meta_parse_error: (data) => `Failed to parse symbol metadata for symbol ${data.symbol_id}: ${data.reason}`,
|
|
26
|
+
exported_symbol_not_found: (data) => `Exported symbol "${data.name}" not found in file with id ${data.file_id}`,
|
|
27
|
+
module_resolution_failed: (data) => `Failed to resolve module "${data.module}" from "${data.from}"`,
|
|
28
|
+
exporter_file_not_found: (data) => `Exporter file not found at "${data.path}" for module "${data.module}"`,
|
|
29
|
+
ast_parse_error: (data) => `AST parsing error in ${data.operation}: ${data.reason}`,
|
|
30
|
+
config_not_found: (data) => `No config found in database at ${data.db_path}`,
|
|
31
|
+
config_invalid_node_modules_paths: (data) => `Invalid node_modules_paths stored in database ${data.db_path}: ${data.reason}`,
|
|
32
|
+
symbol_missing_text: (data) => `Symbol ${data.symbol_id} (${data.name}) has no source text`,
|
|
33
|
+
symbol_node_not_found: (data) => `Symbol node not found for ${data.name} in ${data.file_path}`,
|
|
34
|
+
symbol_not_found: (data) => `Symbol "${data.name}" not found in file "${data.path}"`,
|
|
35
|
+
describe_dependency_failed: (data) => `Failed to describe ${data.package}#${data.name}: ${data.reason}`,
|
|
36
|
+
// CLI errors
|
|
37
|
+
could_not_read_file: (data) => `Could not read file ${data.path}: ${data.reason}`,
|
|
38
|
+
invalid_json: (data) => `Invalid JSON: ${data.reason}`,
|
|
39
|
+
invalid_config: (data) => `Invalid configuration: ${JSON.stringify(data.errors)}`,
|
|
40
|
+
invalid_type: (data) => `Invalid entity type: ${data.type}. Must be one of: dependency, symbol, file, directory`
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// src/db/migrate.ts
|
|
44
|
+
import { readdir, readFile } from "fs/promises";
|
|
45
|
+
import { join } from "path";
|
|
46
|
+
import { sql as sql2 } from "drizzle-orm";
|
|
47
|
+
|
|
48
|
+
// src/db/schema.ts
|
|
49
|
+
var schema_exports = {};
|
|
50
|
+
__export(schema_exports, {
|
|
51
|
+
configs: () => configs,
|
|
52
|
+
directories: () => directories,
|
|
53
|
+
directories_relations: () => directories_relations,
|
|
54
|
+
external_dependencies: () => external_dependencies,
|
|
55
|
+
external_dependencies_relations: () => external_dependencies_relations,
|
|
56
|
+
external_imports: () => external_imports,
|
|
57
|
+
external_imports_relations: () => external_imports_relations,
|
|
58
|
+
files: () => files,
|
|
59
|
+
files_relations: () => files_relations,
|
|
60
|
+
imports: () => imports,
|
|
61
|
+
imports_relations: () => imports_relations,
|
|
62
|
+
migrations: () => migrations,
|
|
63
|
+
symbol_external_links: () => symbol_external_links,
|
|
64
|
+
symbol_external_links_relations: () => symbol_external_links_relations,
|
|
65
|
+
symbol_internal_links: () => symbol_internal_links,
|
|
66
|
+
symbol_internal_links_relations: () => symbol_internal_links_relations,
|
|
67
|
+
symbols: () => symbols,
|
|
68
|
+
symbols_relations: () => symbols_relations
|
|
69
|
+
});
|
|
70
|
+
import { relations, sql } from "drizzle-orm";
|
|
71
|
+
import { sqliteTable, integer, text, index, uniqueIndex } from "drizzle-orm/sqlite-core";
|
|
72
|
+
var timestamps = {
|
|
73
|
+
created_at: integer("created_at", { mode: "timestamp" }).default(sql`(unixepoch())`).notNull(),
|
|
74
|
+
updated_at: integer("updated_at", { mode: "timestamp" }).default(sql`(unixepoch())`).notNull()
|
|
75
|
+
};
|
|
76
|
+
var migrations = sqliteTable("migrations", {
|
|
77
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
78
|
+
name: text("name").notNull().unique(),
|
|
79
|
+
created_at: timestamps.created_at
|
|
80
|
+
});
|
|
81
|
+
var configs = sqliteTable("configs", {
|
|
82
|
+
id: integer("id").primaryKey({ autoIncrement: false }).notNull().default(1),
|
|
83
|
+
project_path: text("project_path").notNull(),
|
|
84
|
+
description: text("description"),
|
|
85
|
+
package_json_path: text("package_json_path"),
|
|
86
|
+
node_modules_paths: text("node_modules_paths"),
|
|
87
|
+
...timestamps
|
|
88
|
+
});
|
|
89
|
+
var directories = sqliteTable(
|
|
90
|
+
"directories",
|
|
91
|
+
{
|
|
92
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
93
|
+
parent_id: integer("parent_id").references(() => directories.id, { onDelete: "cascade" }),
|
|
94
|
+
path: text("path").notNull().unique(),
|
|
95
|
+
description: text("description"),
|
|
96
|
+
state: text("state").$type().notNull().default("to_describe"),
|
|
97
|
+
error: text("error"),
|
|
98
|
+
...timestamps
|
|
99
|
+
},
|
|
100
|
+
(table) => ({
|
|
101
|
+
parent_idx: index("directories_parent_idx").on(table.parent_id),
|
|
102
|
+
path_idx: index("directories_path_idx").on(table.path),
|
|
103
|
+
state_idx: index("directories_state_idx").on(table.state)
|
|
104
|
+
})
|
|
105
|
+
);
|
|
106
|
+
var files = sqliteTable(
|
|
107
|
+
"files",
|
|
108
|
+
{
|
|
109
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
110
|
+
directory_id: integer("directory_id").notNull().references(() => directories.id, { onDelete: "cascade" }),
|
|
111
|
+
path: text("path").notNull().unique(),
|
|
112
|
+
hash: text("hash"),
|
|
113
|
+
description: text("description"),
|
|
114
|
+
state: text("state").$type().notNull().default("to_scan"),
|
|
115
|
+
error: text("error"),
|
|
116
|
+
...timestamps
|
|
117
|
+
},
|
|
118
|
+
(table) => ({
|
|
119
|
+
directory_idx: index("files_directory_idx").on(table.directory_id),
|
|
120
|
+
path_idx: index("files_path_idx").on(table.path),
|
|
121
|
+
hash_idx: index("files_hash_idx").on(table.hash),
|
|
122
|
+
state_idx: index("files_state_idx").on(table.state)
|
|
123
|
+
})
|
|
124
|
+
);
|
|
125
|
+
var external_dependencies = sqliteTable(
|
|
126
|
+
"external_dependencies",
|
|
127
|
+
{
|
|
128
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
129
|
+
package: text("package").notNull(),
|
|
130
|
+
subpath: text("subpath"),
|
|
131
|
+
name: text("name"),
|
|
132
|
+
version: text("version"),
|
|
133
|
+
github_repo: text("github_repo"),
|
|
134
|
+
is_builtin: integer("is_builtin", { mode: "boolean" }).default(false).notNull(),
|
|
135
|
+
description: text("description"),
|
|
136
|
+
state: text("state").$type().notNull().default("to_describe"),
|
|
137
|
+
error: text("error"),
|
|
138
|
+
...timestamps
|
|
139
|
+
},
|
|
140
|
+
(table) => ({
|
|
141
|
+
state_idx: index("external_dependencies_state_idx").on(table.state),
|
|
142
|
+
package_subpath_name_unique: uniqueIndex("external_dependencies_package_subpath_name_unique").on(table.package, table.subpath, table.name)
|
|
143
|
+
})
|
|
144
|
+
);
|
|
145
|
+
var external_imports = sqliteTable(
|
|
146
|
+
"external_imports",
|
|
147
|
+
{
|
|
148
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
149
|
+
file_id: integer("file_id").notNull().references(() => files.id, { onDelete: "cascade" }),
|
|
150
|
+
external_dependency_id: integer("external_dependency_id").notNull().references(() => external_dependencies.id, { onDelete: "cascade" }),
|
|
151
|
+
alias: text("alias").notNull(),
|
|
152
|
+
is_dynamic: integer("is_dynamic", { mode: "boolean" }).default(false).notNull(),
|
|
153
|
+
...timestamps
|
|
154
|
+
},
|
|
155
|
+
(table) => ({
|
|
156
|
+
file_idx: index("external_imports_file_idx").on(table.file_id),
|
|
157
|
+
external_dependency_idx: index("external_imports_external_dependency_idx").on(table.external_dependency_id)
|
|
158
|
+
})
|
|
159
|
+
);
|
|
160
|
+
var imports = sqliteTable(
|
|
161
|
+
"imports",
|
|
162
|
+
{
|
|
163
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
164
|
+
exporter_file_id: integer("exporter_file_id").notNull().references(() => files.id, { onDelete: "cascade" }),
|
|
165
|
+
importer_file_id: integer("importer_file_id").notNull().references(() => files.id, { onDelete: "cascade" }),
|
|
166
|
+
symbol_id: integer("symbol_id").references(() => symbols.id, { onDelete: "set null" }),
|
|
167
|
+
name: text("name").notNull(),
|
|
168
|
+
alias: text("alias").notNull(),
|
|
169
|
+
is_dynamic: integer("is_dynamic", { mode: "boolean" }).default(false).notNull(),
|
|
170
|
+
state: text("state").$type().notNull().default("to_link"),
|
|
171
|
+
error: text("error"),
|
|
172
|
+
...timestamps
|
|
173
|
+
},
|
|
174
|
+
(table) => ({
|
|
175
|
+
exporter_file_idx: index("imports_exporter_file_idx").on(table.exporter_file_id),
|
|
176
|
+
importer_file_idx: index("imports_importer_file_idx").on(table.importer_file_id),
|
|
177
|
+
symbol_idx: index("imports_symbol_idx").on(table.symbol_id),
|
|
178
|
+
state_idx: index("imports_state_idx").on(table.state)
|
|
179
|
+
})
|
|
180
|
+
);
|
|
181
|
+
var symbols = sqliteTable(
|
|
182
|
+
"symbols",
|
|
183
|
+
{
|
|
184
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
185
|
+
file_id: integer("file_id").notNull().references(() => files.id, { onDelete: "cascade" }),
|
|
186
|
+
type: text("type").notNull(),
|
|
187
|
+
// 'function', 'class', 'variable', 'type', 'class_method', 'class_property', 'other'
|
|
188
|
+
name: text("name").notNull(),
|
|
189
|
+
text: text("text"),
|
|
190
|
+
// source code
|
|
191
|
+
meta: text("meta"),
|
|
192
|
+
// JSON details
|
|
193
|
+
description: text("description"),
|
|
194
|
+
is_exported: integer("is_exported", { mode: "boolean" }).default(false).notNull(),
|
|
195
|
+
state: text("state").$type().notNull().default("to_link"),
|
|
196
|
+
error: text("error"),
|
|
197
|
+
...timestamps
|
|
198
|
+
},
|
|
199
|
+
(table) => ({
|
|
200
|
+
file_idx: index("symbols_file_idx").on(table.file_id),
|
|
201
|
+
type_idx: index("symbols_type_idx").on(table.type),
|
|
202
|
+
name_idx: index("symbols_name_idx").on(table.name),
|
|
203
|
+
is_exported_idx: index("symbols_is_exported_idx").on(table.is_exported),
|
|
204
|
+
state_idx: index("symbols_state_idx").on(table.state)
|
|
205
|
+
})
|
|
206
|
+
);
|
|
207
|
+
var symbol_internal_links = sqliteTable(
|
|
208
|
+
"symbol_internal_links",
|
|
209
|
+
{
|
|
210
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
211
|
+
from_file_id: integer("from_file_id").notNull().references(() => files.id, { onDelete: "cascade" }),
|
|
212
|
+
to_file_id: integer("to_file_id").notNull().references(() => files.id, { onDelete: "cascade" }),
|
|
213
|
+
from_symbol_id: integer("from_symbol_id").notNull().references(() => symbols.id, { onDelete: "cascade" }),
|
|
214
|
+
to_symbol_id: integer("to_symbol_id").notNull().references(() => symbols.id, { onDelete: "cascade" }),
|
|
215
|
+
state: text("state").$type().notNull().default("pending"),
|
|
216
|
+
error: text("error"),
|
|
217
|
+
...timestamps
|
|
218
|
+
},
|
|
219
|
+
(table) => ({
|
|
220
|
+
from_file_idx: index("symbol_internal_links_from_file_idx").on(table.from_file_id),
|
|
221
|
+
to_file_idx: index("symbol_internal_links_to_file_idx").on(table.to_file_id),
|
|
222
|
+
from_symbol_idx: index("symbol_internal_links_from_symbol_idx").on(table.from_symbol_id),
|
|
223
|
+
to_symbol_idx: index("symbol_internal_links_to_symbol_idx").on(table.to_symbol_id),
|
|
224
|
+
state_idx: index("symbol_internal_links_state_idx").on(table.state)
|
|
225
|
+
})
|
|
226
|
+
);
|
|
227
|
+
var symbol_external_links = sqliteTable(
|
|
228
|
+
"symbol_external_links",
|
|
229
|
+
{
|
|
230
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
231
|
+
symbol_id: integer("symbol_id").notNull().references(() => symbols.id, { onDelete: "cascade" }),
|
|
232
|
+
external_import_id: integer("external_import_id").notNull().references(() => external_imports.id, { onDelete: "cascade" }),
|
|
233
|
+
...timestamps
|
|
234
|
+
},
|
|
235
|
+
(table) => ({
|
|
236
|
+
symbol_idx: index("symbol_external_links_symbol_idx").on(table.symbol_id),
|
|
237
|
+
external_import_idx: index("symbol_external_links_external_import_idx").on(table.external_import_id)
|
|
238
|
+
})
|
|
239
|
+
);
|
|
240
|
+
var directories_relations = relations(directories, ({ one, many }) => ({
|
|
241
|
+
parent: one(directories, {
|
|
242
|
+
fields: [directories.parent_id],
|
|
243
|
+
references: [directories.id],
|
|
244
|
+
relationName: "subdirectories"
|
|
245
|
+
}),
|
|
246
|
+
subdirectories: many(directories, {
|
|
247
|
+
relationName: "subdirectories"
|
|
248
|
+
}),
|
|
249
|
+
files: many(files)
|
|
250
|
+
}));
|
|
251
|
+
var files_relations = relations(files, ({ one, many }) => ({
|
|
252
|
+
directory: one(directories, {
|
|
253
|
+
fields: [files.directory_id],
|
|
254
|
+
references: [directories.id]
|
|
255
|
+
}),
|
|
256
|
+
external_imports: many(external_imports),
|
|
257
|
+
imports_as_exporter: many(imports, {
|
|
258
|
+
relationName: "imports_as_exporter"
|
|
259
|
+
}),
|
|
260
|
+
imports_as_importer: many(imports, {
|
|
261
|
+
relationName: "imports_as_importer"
|
|
262
|
+
}),
|
|
263
|
+
symbols: many(symbols),
|
|
264
|
+
internal_links_from: many(symbol_internal_links, {
|
|
265
|
+
relationName: "file_internal_links_from"
|
|
266
|
+
}),
|
|
267
|
+
internal_links_to: many(symbol_internal_links, {
|
|
268
|
+
relationName: "file_internal_links_to"
|
|
269
|
+
})
|
|
270
|
+
}));
|
|
271
|
+
var external_dependencies_relations = relations(external_dependencies, ({ many }) => ({
|
|
272
|
+
imports: many(external_imports),
|
|
273
|
+
symbol_external_links: many(symbol_external_links)
|
|
274
|
+
}));
|
|
275
|
+
var external_imports_relations = relations(external_imports, ({ one }) => ({
|
|
276
|
+
file: one(files, {
|
|
277
|
+
fields: [external_imports.file_id],
|
|
278
|
+
references: [files.id]
|
|
279
|
+
}),
|
|
280
|
+
external_dependency: one(external_dependencies, {
|
|
281
|
+
fields: [external_imports.external_dependency_id],
|
|
282
|
+
references: [external_dependencies.id]
|
|
283
|
+
})
|
|
284
|
+
}));
|
|
285
|
+
var imports_relations = relations(imports, ({ one }) => ({
|
|
286
|
+
exporter_file: one(files, {
|
|
287
|
+
fields: [imports.exporter_file_id],
|
|
288
|
+
references: [files.id],
|
|
289
|
+
relationName: "imports_as_exporter"
|
|
290
|
+
}),
|
|
291
|
+
importer_file: one(files, {
|
|
292
|
+
fields: [imports.importer_file_id],
|
|
293
|
+
references: [files.id],
|
|
294
|
+
relationName: "imports_as_importer"
|
|
295
|
+
}),
|
|
296
|
+
symbol: one(symbols, {
|
|
297
|
+
fields: [imports.symbol_id],
|
|
298
|
+
references: [symbols.id]
|
|
299
|
+
})
|
|
300
|
+
}));
|
|
301
|
+
var symbols_relations = relations(symbols, ({ one, many }) => ({
|
|
302
|
+
file: one(files, {
|
|
303
|
+
fields: [symbols.file_id],
|
|
304
|
+
references: [files.id]
|
|
305
|
+
}),
|
|
306
|
+
imports: many(imports),
|
|
307
|
+
internal_links_from: many(symbol_internal_links, {
|
|
308
|
+
relationName: "internal_links_from"
|
|
309
|
+
}),
|
|
310
|
+
internal_links_to: many(symbol_internal_links, {
|
|
311
|
+
relationName: "internal_links_to"
|
|
312
|
+
}),
|
|
313
|
+
external_links: many(symbol_external_links)
|
|
314
|
+
}));
|
|
315
|
+
var symbol_internal_links_relations = relations(symbol_internal_links, ({ one }) => ({
|
|
316
|
+
from_file: one(files, {
|
|
317
|
+
fields: [symbol_internal_links.from_file_id],
|
|
318
|
+
references: [files.id],
|
|
319
|
+
relationName: "file_internal_links_from"
|
|
320
|
+
}),
|
|
321
|
+
to_file: one(files, {
|
|
322
|
+
fields: [symbol_internal_links.to_file_id],
|
|
323
|
+
references: [files.id],
|
|
324
|
+
relationName: "file_internal_links_to"
|
|
325
|
+
}),
|
|
326
|
+
from_symbol: one(symbols, {
|
|
327
|
+
fields: [symbol_internal_links.from_symbol_id],
|
|
328
|
+
references: [symbols.id],
|
|
329
|
+
relationName: "internal_links_from"
|
|
330
|
+
}),
|
|
331
|
+
to_symbol: one(symbols, {
|
|
332
|
+
fields: [symbol_internal_links.to_symbol_id],
|
|
333
|
+
references: [symbols.id],
|
|
334
|
+
relationName: "internal_links_to"
|
|
335
|
+
})
|
|
336
|
+
}));
|
|
337
|
+
var symbol_external_links_relations = relations(symbol_external_links, ({ one }) => ({
|
|
338
|
+
symbol: one(symbols, {
|
|
339
|
+
fields: [symbol_external_links.symbol_id],
|
|
340
|
+
references: [symbols.id]
|
|
341
|
+
}),
|
|
342
|
+
external_import: one(external_imports, {
|
|
343
|
+
fields: [symbol_external_links.external_import_id],
|
|
344
|
+
references: [external_imports.id]
|
|
345
|
+
})
|
|
346
|
+
}));
|
|
347
|
+
|
|
348
|
+
// src/db/migrate.ts
|
|
349
|
+
async function migrate(ctx) {
|
|
350
|
+
const [migration_filenames, applied_migration_names] = await Promise.all([get_migration_filenames(ctx), get_applied_migration_names(ctx)]);
|
|
351
|
+
for (const filename of migration_filenames) {
|
|
352
|
+
if (applied_migration_names.has(filename)) continue;
|
|
353
|
+
await apply_migration(ctx, filename);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
async function get_migration_filenames({ migrations_path }) {
|
|
357
|
+
const filenames = /* @__PURE__ */ new Set();
|
|
358
|
+
for (const entry of await readdir(migrations_path, { withFileTypes: true })) {
|
|
359
|
+
if (!entry.isFile() || !entry.name.endsWith(".sql")) continue;
|
|
360
|
+
filenames.add(entry.name);
|
|
361
|
+
}
|
|
362
|
+
return filenames;
|
|
363
|
+
}
|
|
364
|
+
async function get_applied_migration_names({ db: db6 }) {
|
|
365
|
+
const res = db6.get(sql2`SELECT name FROM sqlite_master WHERE type='table' AND name='migrations'`);
|
|
366
|
+
if (!res) return /* @__PURE__ */ new Set();
|
|
367
|
+
const applied = await db6.select({ name: migrations.name }).from(migrations);
|
|
368
|
+
return new Set(applied.map((x) => x.name));
|
|
369
|
+
}
|
|
370
|
+
async function apply_migration({ sqlite, migrations_path }, filename) {
|
|
371
|
+
const file_path = join(migrations_path, filename);
|
|
372
|
+
const queries = await readFile(file_path, "utf-8");
|
|
373
|
+
sqlite.transaction(() => {
|
|
374
|
+
sqlite.exec(queries);
|
|
375
|
+
sqlite.prepare("INSERT INTO migrations (name) VALUES (?)").run(filename);
|
|
376
|
+
})();
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// src/db/configs.ts
|
|
380
|
+
var configs_exports = {};
|
|
381
|
+
__export(configs_exports, {
|
|
382
|
+
get: () => get,
|
|
383
|
+
upsert: () => upsert
|
|
384
|
+
});
|
|
385
|
+
import { eq as eq2, sql as sql3 } from "drizzle-orm";
|
|
386
|
+
|
|
387
|
+
// src/db/common.ts
|
|
388
|
+
import { eq, like, or, and, asc, desc } from "drizzle-orm";
|
|
389
|
+
function safe_query(operation, fn) {
|
|
390
|
+
return err.safe(fn, (reason, ...args) => err.new("db_error", { operation, args: args.slice(1), reason }));
|
|
391
|
+
}
|
|
392
|
+
function do_search(db6, table, options) {
|
|
393
|
+
if (!options.select.includes("id")) options.select.push("id");
|
|
394
|
+
return db6.select(fields(table, options.select)).from(table).where(conditions(table, options.where)).orderBy(order(table, options.order_by)).offset(options.offset).limit(options.limit).all();
|
|
395
|
+
}
|
|
396
|
+
function fields(table, fields2) {
|
|
397
|
+
const res = {};
|
|
398
|
+
for (const field of fields2) res[field] = table[field];
|
|
399
|
+
return res;
|
|
400
|
+
}
|
|
401
|
+
function conditions(table, filters) {
|
|
402
|
+
if (!filters || Object.keys(filters).length === 0) return void 0;
|
|
403
|
+
const parts = [];
|
|
404
|
+
for (const [field, value] of Object.entries(filters)) {
|
|
405
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
406
|
+
const field_conditions = value.map((v) => condition(table, field, v));
|
|
407
|
+
parts.push(or(...field_conditions));
|
|
408
|
+
} else {
|
|
409
|
+
parts.push(condition(table, field, value));
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
return and(...parts);
|
|
413
|
+
}
|
|
414
|
+
function condition(table, field, value) {
|
|
415
|
+
if (typeof value === "object" && value !== null) {
|
|
416
|
+
if ("contains" in value) return like(table[field], `%${value.contains}%`);
|
|
417
|
+
if ("starts_with" in value) return like(table[field], `${value.starts_with}%`);
|
|
418
|
+
if ("ends_with" in value) return like(table[field], `%${value.ends_with}`);
|
|
419
|
+
return eq(table[field], JSON.stringify(value));
|
|
420
|
+
}
|
|
421
|
+
return eq(table[field], value);
|
|
422
|
+
}
|
|
423
|
+
function order(table, [field, direction]) {
|
|
424
|
+
return direction === "asc" ? asc(table[field]) : desc(table[field]);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// src/db/configs.ts
|
|
428
|
+
var get = safe_query(
|
|
429
|
+
"configs.get",
|
|
430
|
+
(ctx) => ctx.db.select().from(configs).where(eq2(configs.id, 1)).get()
|
|
431
|
+
);
|
|
432
|
+
var upsert = safe_query(
|
|
433
|
+
"configs.upsert",
|
|
434
|
+
(ctx, data) => ctx.db.insert(configs).values({ id: 1, ...data }).onConflictDoUpdate({
|
|
435
|
+
target: configs.id,
|
|
436
|
+
set: { ...data, updated_at: sql3`(unixepoch())` }
|
|
437
|
+
}).run()
|
|
438
|
+
);
|
|
439
|
+
|
|
440
|
+
// src/db/files.ts
|
|
441
|
+
var files_exports = {};
|
|
442
|
+
__export(files_exports, {
|
|
443
|
+
all: () => all,
|
|
444
|
+
by_directory_path: () => by_directory_path,
|
|
445
|
+
by_id: () => by_id,
|
|
446
|
+
by_id_and_state: () => by_id_and_state,
|
|
447
|
+
by_path: () => by_path,
|
|
448
|
+
by_state: () => by_state,
|
|
449
|
+
del: () => del,
|
|
450
|
+
del_by_dir: () => del_by_dir,
|
|
451
|
+
get_directory_ids: () => get_directory_ids,
|
|
452
|
+
imported_by: () => imported_by,
|
|
453
|
+
importing: () => importing,
|
|
454
|
+
insert: () => insert,
|
|
455
|
+
search: () => search,
|
|
456
|
+
update: () => update,
|
|
457
|
+
update_many: () => update_many,
|
|
458
|
+
using_dependency: () => using_dependency
|
|
459
|
+
});
|
|
460
|
+
import { eq as eq3, and as and2, inArray, or as or2, like as like2 } from "drizzle-orm";
|
|
461
|
+
|
|
462
|
+
// src/internals/utils.ts
|
|
463
|
+
import { readFileSync } from "fs";
|
|
464
|
+
var parse_json = err.safe(JSON.parse, (reason, text2) => err.new("invalid_json", { reason, text: text2 }));
|
|
465
|
+
var read_file = err.safe(
|
|
466
|
+
(path6) => readFileSync(path6, "utf-8"),
|
|
467
|
+
(reason, path6) => err.new("could_not_read_file", { path: path6, reason })
|
|
468
|
+
);
|
|
469
|
+
function group_by_unique(items, key) {
|
|
470
|
+
const groups = {};
|
|
471
|
+
for (const item of items) {
|
|
472
|
+
groups[key(item)] = item;
|
|
473
|
+
}
|
|
474
|
+
return groups;
|
|
475
|
+
}
|
|
476
|
+
function expand({ items, get_children, get_key }) {
|
|
477
|
+
const visited = /* @__PURE__ */ new Set();
|
|
478
|
+
const result = [];
|
|
479
|
+
const queue = [...items];
|
|
480
|
+
while (queue.length > 0) {
|
|
481
|
+
const item = queue.shift();
|
|
482
|
+
const key = get_key(item);
|
|
483
|
+
if (err.any(key)) return key;
|
|
484
|
+
if (visited.has(key)) continue;
|
|
485
|
+
visited.add(key);
|
|
486
|
+
result.push(item);
|
|
487
|
+
const children3 = get_children(item);
|
|
488
|
+
if (err.any(children3)) return children3;
|
|
489
|
+
queue.push(...children3);
|
|
490
|
+
}
|
|
491
|
+
return result;
|
|
492
|
+
}
|
|
493
|
+
function uniq(items) {
|
|
494
|
+
return [...new Set(items)];
|
|
495
|
+
}
|
|
496
|
+
function merge(a, b) {
|
|
497
|
+
const res = { ...a };
|
|
498
|
+
for (const key of Object.keys(b)) {
|
|
499
|
+
if (b[key] !== void 0) res[key] = b[key];
|
|
500
|
+
}
|
|
501
|
+
return res;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// src/db/defaults.ts
|
|
505
|
+
var files2 = {
|
|
506
|
+
select: ["id", "directory_id", "path", "state", "error"],
|
|
507
|
+
order_by: ["id", "asc"],
|
|
508
|
+
limit: 20,
|
|
509
|
+
offset: 0,
|
|
510
|
+
where: {}
|
|
511
|
+
};
|
|
512
|
+
var directories2 = {
|
|
513
|
+
select: ["id", "parent_id", "path", "state", "error"],
|
|
514
|
+
order_by: ["id", "asc"],
|
|
515
|
+
limit: 20,
|
|
516
|
+
offset: 0,
|
|
517
|
+
where: {}
|
|
518
|
+
};
|
|
519
|
+
var symbols2 = {
|
|
520
|
+
select: ["id", "file_id", "type", "name", "meta", "is_exported", "state", "error"],
|
|
521
|
+
order_by: ["id", "asc"],
|
|
522
|
+
limit: 20,
|
|
523
|
+
offset: 0,
|
|
524
|
+
where: {}
|
|
525
|
+
};
|
|
526
|
+
var external_dependencies2 = {
|
|
527
|
+
select: ["id", "package", "subpath", "name", "state", "error"],
|
|
528
|
+
order_by: ["id", "asc"],
|
|
529
|
+
limit: 20,
|
|
530
|
+
offset: 0,
|
|
531
|
+
where: {}
|
|
532
|
+
};
|
|
533
|
+
|
|
534
|
+
// src/db/files.ts
|
|
535
|
+
var default_select_fields = ["id", "directory_id", "path", "state", "error"];
|
|
536
|
+
var all = safe_query("files.all", (ctx) => ctx.db.select().from(files).all());
|
|
537
|
+
var search = safe_query("files.search", (ctx, options = {}) => {
|
|
538
|
+
return do_search(ctx.db, files, merge(files2, options));
|
|
539
|
+
});
|
|
540
|
+
var by_id = safe_query("files.by_id", (ctx, id) => ctx.db.select().from(files).where(eq3(files.id, id)).get());
|
|
541
|
+
var by_path = safe_query(
|
|
542
|
+
"files.by_path",
|
|
543
|
+
(ctx, path6) => ctx.db.select().from(files).where(eq3(files.path, path6)).get()
|
|
544
|
+
);
|
|
545
|
+
var by_state = safe_query(
|
|
546
|
+
"files.by_state",
|
|
547
|
+
(ctx, state) => ctx.db.select().from(files).where(eq3(files.state, state)).all()
|
|
548
|
+
);
|
|
549
|
+
var insert = safe_query("files.insert", (ctx, values) => ctx.db.insert(files).values(values).run());
|
|
550
|
+
var update = safe_query(
|
|
551
|
+
"files.update",
|
|
552
|
+
(ctx, file_id, values) => ctx.db.update(files).set(values).where(eq3(files.id, file_id)).run()
|
|
553
|
+
);
|
|
554
|
+
var update_many = safe_query(
|
|
555
|
+
"files.update_many",
|
|
556
|
+
(ctx, file_ids, values) => ctx.db.update(files).set(values).where(inArray(files.id, file_ids)).run()
|
|
557
|
+
);
|
|
558
|
+
var by_id_and_state = safe_query(
|
|
559
|
+
"files.by_id_and_state",
|
|
560
|
+
(ctx, params) => ctx.db.select().from(files).where(and2(eq3(files.id, params.id), eq3(files.state, params.state))).get()
|
|
561
|
+
);
|
|
562
|
+
var del = safe_query("files.delete", (ctx, file_id) => ctx.db.delete(files).where(eq3(files.id, file_id)).run());
|
|
563
|
+
var del_by_dir = safe_query(
|
|
564
|
+
"files.delete_by_dir",
|
|
565
|
+
(ctx, directory_id) => ctx.db.delete(files).where(eq3(files.directory_id, directory_id)).run()
|
|
566
|
+
);
|
|
567
|
+
var get_directory_ids = safe_query(
|
|
568
|
+
"files.get_directory_ids",
|
|
569
|
+
(ctx, file_ids) => ctx.db.select({ directory_id: files.directory_id }).from(files).where(inArray(files.id, file_ids)).all().map((x) => x.directory_id)
|
|
570
|
+
);
|
|
571
|
+
var by_directory_path = safe_query("files.by_directory_path", (ctx, dir_path, recursive = false) => {
|
|
572
|
+
let dir_ids;
|
|
573
|
+
if (recursive) {
|
|
574
|
+
if (dir_path === "/") {
|
|
575
|
+
dir_ids = ctx.db.select({ id: directories.id }).from(directories).all().map((d) => d.id);
|
|
576
|
+
} else {
|
|
577
|
+
dir_ids = ctx.db.select({ id: directories.id }).from(directories).where(or2(eq3(directories.path, dir_path), like2(directories.path, `${dir_path}/%`))).all().map((d) => d.id);
|
|
578
|
+
}
|
|
579
|
+
} else {
|
|
580
|
+
const dir = ctx.db.select({ id: directories.id }).from(directories).where(eq3(directories.path, dir_path)).get();
|
|
581
|
+
dir_ids = dir ? [dir.id] : [];
|
|
582
|
+
}
|
|
583
|
+
if (dir_ids.length === 0) return [];
|
|
584
|
+
return ctx.db.select().from(files).where(inArray(files.directory_id, dir_ids)).all();
|
|
585
|
+
});
|
|
586
|
+
var using_dependency = safe_query(
|
|
587
|
+
"files.using_dependency",
|
|
588
|
+
(ctx, external_dependency_id, fields_to_select = default_select_fields) => {
|
|
589
|
+
if (!fields_to_select.includes("id")) fields_to_select.push("id");
|
|
590
|
+
const imports2 = ctx.db.select({ file_id: external_imports.file_id }).from(external_imports).where(eq3(external_imports.external_dependency_id, external_dependency_id)).all();
|
|
591
|
+
const file_ids = uniq(imports2.map((i) => i.file_id));
|
|
592
|
+
if (file_ids.length === 0) return [];
|
|
593
|
+
return ctx.db.select(fields(files, fields_to_select)).from(files).where(inArray(files.id, file_ids)).all();
|
|
594
|
+
}
|
|
595
|
+
);
|
|
596
|
+
var imported_by = safe_query(
|
|
597
|
+
"files.imported_by",
|
|
598
|
+
(ctx, file_id, fields_to_select = default_select_fields) => {
|
|
599
|
+
if (!fields_to_select.includes("id")) fields_to_select.push("id");
|
|
600
|
+
const import_rows = ctx.db.select({ id: imports.exporter_file_id }).from(imports).where(eq3(imports.importer_file_id, file_id)).all();
|
|
601
|
+
const file_ids = uniq(import_rows.map((i) => i.id));
|
|
602
|
+
if (file_ids.length === 0) return [];
|
|
603
|
+
return ctx.db.select(fields(files, fields_to_select)).from(files).where(inArray(files.id, file_ids)).all();
|
|
604
|
+
}
|
|
605
|
+
);
|
|
606
|
+
var importing = safe_query(
|
|
607
|
+
"files.importing",
|
|
608
|
+
(ctx, file_id, fields_to_select = default_select_fields) => {
|
|
609
|
+
if (!fields_to_select.includes("id")) fields_to_select.push("id");
|
|
610
|
+
const import_records = ctx.db.select({ importer_file_id: imports.importer_file_id }).from(imports).where(eq3(imports.exporter_file_id, file_id)).all();
|
|
611
|
+
const file_ids = uniq(import_records.map((i) => i.importer_file_id));
|
|
612
|
+
if (file_ids.length === 0) return [];
|
|
613
|
+
return ctx.db.select(fields(files, fields_to_select)).from(files).where(inArray(files.id, file_ids)).all();
|
|
614
|
+
}
|
|
615
|
+
);
|
|
616
|
+
|
|
617
|
+
// src/db/directories.ts
|
|
618
|
+
var directories_exports = {};
|
|
619
|
+
__export(directories_exports, {
|
|
620
|
+
by_id: () => by_id2,
|
|
621
|
+
by_id_and_state: () => by_id_and_state2,
|
|
622
|
+
by_path: () => by_path2,
|
|
623
|
+
by_state: () => by_state2,
|
|
624
|
+
insert: () => insert2,
|
|
625
|
+
search: () => search2,
|
|
626
|
+
update: () => update2,
|
|
627
|
+
update_many: () => update_many2
|
|
628
|
+
});
|
|
629
|
+
import { eq as eq4, and as and3, inArray as inArray2 } from "drizzle-orm";
|
|
630
|
+
var by_id2 = safe_query(
|
|
631
|
+
"directories.by_id",
|
|
632
|
+
(ctx, id) => ctx.db.select().from(directories).where(eq4(directories.id, id)).get()
|
|
633
|
+
);
|
|
634
|
+
var by_path2 = safe_query(
|
|
635
|
+
"directories.by_path",
|
|
636
|
+
(ctx, path6) => ctx.db.select().from(directories).where(eq4(directories.path, path6)).get()
|
|
637
|
+
);
|
|
638
|
+
var by_state2 = safe_query(
|
|
639
|
+
"directories.by_state",
|
|
640
|
+
(ctx, state) => ctx.db.select().from(directories).where(eq4(directories.state, state)).all()
|
|
641
|
+
);
|
|
642
|
+
var insert2 = safe_query(
|
|
643
|
+
"directories.insert",
|
|
644
|
+
(ctx, values) => ctx.db.insert(directories).values(values).returning().get()
|
|
645
|
+
);
|
|
646
|
+
var update2 = safe_query(
|
|
647
|
+
"directories.update",
|
|
648
|
+
(ctx, id, values) => ctx.db.update(directories).set(values).where(eq4(directories.id, id)).run()
|
|
649
|
+
);
|
|
650
|
+
var update_many2 = safe_query(
|
|
651
|
+
"directories.update_many",
|
|
652
|
+
(ctx, ids, values) => ctx.db.update(directories).set(values).where(inArray2(directories.id, ids)).run()
|
|
653
|
+
);
|
|
654
|
+
var by_id_and_state2 = safe_query(
|
|
655
|
+
"directories.by_id_and_state",
|
|
656
|
+
(ctx, params) => ctx.db.select().from(directories).where(and3(eq4(directories.id, params.id), eq4(directories.state, params.state))).get()
|
|
657
|
+
);
|
|
658
|
+
var search2 = safe_query("directories.search", (ctx, options = {}) => {
|
|
659
|
+
return do_search(ctx.db, directories, merge(directories2, options));
|
|
660
|
+
});
|
|
661
|
+
|
|
662
|
+
// src/db/imports.ts
|
|
663
|
+
var imports_exports = {};
|
|
664
|
+
__export(imports_exports, {
|
|
665
|
+
by_exporter_file: () => by_exporter_file,
|
|
666
|
+
by_importer_file: () => by_importer_file,
|
|
667
|
+
by_state: () => by_state3,
|
|
668
|
+
del_by_importer_file: () => del_by_importer_file,
|
|
669
|
+
insert_many: () => insert_many,
|
|
670
|
+
update: () => update3
|
|
671
|
+
});
|
|
672
|
+
import { eq as eq5 } from "drizzle-orm";
|
|
673
|
+
var by_exporter_file = safe_query(
|
|
674
|
+
"imports.by_exporter_file",
|
|
675
|
+
(ctx, exporter_file_id) => ctx.db.select().from(imports).where(eq5(imports.exporter_file_id, exporter_file_id)).all()
|
|
676
|
+
);
|
|
677
|
+
var by_importer_file = safe_query(
|
|
678
|
+
"imports.by_importer_file",
|
|
679
|
+
(ctx, importer_file_id) => ctx.db.select().from(imports).where(eq5(imports.importer_file_id, importer_file_id)).all()
|
|
680
|
+
);
|
|
681
|
+
var insert_many = safe_query("imports.insert_many", (ctx, values) => ctx.db.insert(imports).values(values).run());
|
|
682
|
+
var del_by_importer_file = safe_query(
|
|
683
|
+
"imports.del_by_importer_file",
|
|
684
|
+
(ctx, file_id) => ctx.db.delete(imports).where(eq5(imports.importer_file_id, file_id)).run()
|
|
685
|
+
);
|
|
686
|
+
var by_state3 = safe_query(
|
|
687
|
+
"imports.by_state",
|
|
688
|
+
(ctx, state) => ctx.db.select().from(imports).where(eq5(imports.state, state)).all()
|
|
689
|
+
);
|
|
690
|
+
var update3 = safe_query(
|
|
691
|
+
"imports.update",
|
|
692
|
+
(ctx, id, data) => ctx.db.update(imports).set(data).where(eq5(imports.id, id)).run()
|
|
693
|
+
);
|
|
694
|
+
|
|
695
|
+
// src/db/symbols.ts
|
|
696
|
+
var symbols_exports = {};
|
|
697
|
+
__export(symbols_exports, {
|
|
698
|
+
by_file: () => by_file,
|
|
699
|
+
by_file_and_name: () => by_file_and_name,
|
|
700
|
+
by_id: () => by_id3,
|
|
701
|
+
by_id_and_state: () => by_id_and_state3,
|
|
702
|
+
by_state: () => by_state4,
|
|
703
|
+
del_by_file: () => del_by_file,
|
|
704
|
+
insert_many: () => insert_many2,
|
|
705
|
+
meta: () => meta,
|
|
706
|
+
referenced_by: () => referenced_by,
|
|
707
|
+
referencing: () => referencing,
|
|
708
|
+
search: () => search3,
|
|
709
|
+
update: () => update4,
|
|
710
|
+
using_dependency: () => using_dependency2
|
|
711
|
+
});
|
|
712
|
+
import { eq as eq6, and as and4, inArray as inArray3 } from "drizzle-orm";
|
|
713
|
+
var insert_many2 = safe_query("symbols.insert_many", (ctx, values) => ctx.db.insert(symbols).values(values).run());
|
|
714
|
+
var del_by_file = safe_query(
|
|
715
|
+
"symbols.delete_by_file",
|
|
716
|
+
(ctx, file_id) => ctx.db.delete(symbols).where(eq6(symbols.file_id, file_id)).run()
|
|
717
|
+
);
|
|
718
|
+
var by_file_and_name = safe_query(
|
|
719
|
+
"symbols.by_file_and_name",
|
|
720
|
+
(ctx, params) => ctx.db.select().from(symbols).where(and4(eq6(symbols.file_id, params.file_id), eq6(symbols.name, params.name), eq6(symbols.is_exported, params.is_exported))).get()
|
|
721
|
+
);
|
|
722
|
+
var by_state4 = safe_query(
|
|
723
|
+
"symbols.by_state",
|
|
724
|
+
(ctx, state) => ctx.db.select().from(symbols).where(eq6(symbols.state, state)).all()
|
|
725
|
+
);
|
|
726
|
+
var by_file = safe_query(
|
|
727
|
+
"symbols.by_file",
|
|
728
|
+
(ctx, file_id) => ctx.db.select().from(symbols).where(eq6(symbols.file_id, file_id)).all()
|
|
729
|
+
);
|
|
730
|
+
var update4 = safe_query(
|
|
731
|
+
"symbols.update",
|
|
732
|
+
(ctx, id, data) => ctx.db.update(symbols).set(data).where(eq6(symbols.id, id)).run()
|
|
733
|
+
);
|
|
734
|
+
var by_id3 = safe_query("symbols.by_id", (ctx, id) => ctx.db.select().from(symbols).where(eq6(symbols.id, id)).get());
|
|
735
|
+
var by_id_and_state3 = safe_query(
|
|
736
|
+
"symbols.by_id_and_state",
|
|
737
|
+
(ctx, params) => ctx.db.select().from(symbols).where(and4(eq6(symbols.id, params.id), eq6(symbols.state, params.state))).get()
|
|
738
|
+
);
|
|
739
|
+
function meta(symbol) {
|
|
740
|
+
return err.catch(
|
|
741
|
+
() => JSON.parse(symbol.meta),
|
|
742
|
+
(reason) => err.new("symbol_meta_parse_error", { reason, symbol_id: symbol.id, meta: symbol.meta })
|
|
743
|
+
);
|
|
744
|
+
}
|
|
745
|
+
var search3 = safe_query("symbols.search", (ctx, options = {}) => {
|
|
746
|
+
return do_search(ctx.db, symbols, merge(symbols2, options));
|
|
747
|
+
});
|
|
748
|
+
var referenced_by = safe_query(
|
|
749
|
+
"symbols.referenced_by",
|
|
750
|
+
(ctx, symbol_id, fields_to_select = symbols2.select) => {
|
|
751
|
+
if (!fields_to_select.includes("id")) fields_to_select.push("id");
|
|
752
|
+
const link_records = ctx.db.select({ id: symbol_internal_links.to_symbol_id }).from(symbol_internal_links).where(eq6(symbol_internal_links.from_symbol_id, symbol_id)).all();
|
|
753
|
+
const symbol_ids = uniq(link_records.map((i) => i.id).filter((id) => id !== null));
|
|
754
|
+
if (symbol_ids.length === 0) return [];
|
|
755
|
+
return ctx.db.select(fields(symbols, fields_to_select)).from(symbols).where(inArray3(symbols.id, symbol_ids)).all();
|
|
756
|
+
}
|
|
757
|
+
);
|
|
758
|
+
var referencing = safe_query(
|
|
759
|
+
"symbols.referencing",
|
|
760
|
+
(ctx, symbol_id, fields_to_select = symbols2.select) => {
|
|
761
|
+
if (!fields_to_select.includes("id")) fields_to_select.push("id");
|
|
762
|
+
const link_records = ctx.db.select({ id: symbol_internal_links.from_symbol_id }).from(symbol_internal_links).where(eq6(symbol_internal_links.to_symbol_id, symbol_id)).all();
|
|
763
|
+
const symbol_ids = uniq(link_records.map((i) => i.id).filter((id) => id !== null));
|
|
764
|
+
if (symbol_ids.length === 0) return [];
|
|
765
|
+
return ctx.db.select(fields(symbols, fields_to_select)).from(symbols).where(inArray3(symbols.id, symbol_ids)).all();
|
|
766
|
+
}
|
|
767
|
+
);
|
|
768
|
+
var using_dependency2 = safe_query(
|
|
769
|
+
"symbols.using_dependency",
|
|
770
|
+
(ctx, dependency_id, fields_to_select = symbols2.select) => {
|
|
771
|
+
if (!fields_to_select.includes("id")) fields_to_select.push("id");
|
|
772
|
+
const link_records = ctx.db.select({ symbol_id: symbol_external_links.symbol_id }).from(symbol_external_links).innerJoin(external_imports, eq6(symbol_external_links.external_import_id, external_imports.id)).where(eq6(external_imports.external_dependency_id, dependency_id)).all();
|
|
773
|
+
const symbol_ids = uniq(link_records.map((i) => i.symbol_id));
|
|
774
|
+
if (symbol_ids.length === 0) return [];
|
|
775
|
+
return ctx.db.select(fields(symbols, fields_to_select)).from(symbols).where(inArray3(symbols.id, symbol_ids)).all();
|
|
776
|
+
}
|
|
777
|
+
);
|
|
778
|
+
|
|
779
|
+
// src/db/external_dependencies.ts
|
|
780
|
+
var external_dependencies_exports = {};
|
|
781
|
+
__export(external_dependencies_exports, {
|
|
782
|
+
all: () => all2,
|
|
783
|
+
by_id: () => by_id4,
|
|
784
|
+
by_package_subpath_and_name: () => by_package_subpath_and_name,
|
|
785
|
+
by_state: () => by_state5,
|
|
786
|
+
get_or_create: () => get_or_create,
|
|
787
|
+
insert: () => insert3,
|
|
788
|
+
search: () => search4,
|
|
789
|
+
update: () => update5,
|
|
790
|
+
used_by_file: () => used_by_file,
|
|
791
|
+
used_by_symbol: () => used_by_symbol
|
|
792
|
+
});
|
|
793
|
+
import { eq as eq7, and as and5, sql as sql4, inArray as inArray4 } from "drizzle-orm";
|
|
794
|
+
var by_id4 = safe_query(
|
|
795
|
+
"external_dependencies.by_id",
|
|
796
|
+
(ctx, id) => ctx.db.select().from(external_dependencies).where(eq7(external_dependencies.id, id)).get()
|
|
797
|
+
);
|
|
798
|
+
var by_state5 = safe_query(
|
|
799
|
+
"external_dependencies.by_state",
|
|
800
|
+
(ctx, state) => ctx.db.select().from(external_dependencies).where(eq7(external_dependencies.state, state)).all()
|
|
801
|
+
);
|
|
802
|
+
var by_package_subpath_and_name = safe_query(
|
|
803
|
+
"external_dependencies.by_package_subpath_and_name",
|
|
804
|
+
(ctx, params) => ctx.db.select().from(external_dependencies).where(
|
|
805
|
+
and5(
|
|
806
|
+
eq7(external_dependencies.package, params.package),
|
|
807
|
+
params.subpath === null ? sql4`${external_dependencies.subpath} IS NULL` : eq7(external_dependencies.subpath, params.subpath),
|
|
808
|
+
params.name === null ? sql4`${external_dependencies.name} IS NULL` : eq7(external_dependencies.name, params.name)
|
|
809
|
+
)
|
|
810
|
+
).get()
|
|
811
|
+
);
|
|
812
|
+
var insert3 = safe_query(
|
|
813
|
+
"external_dependencies.insert",
|
|
814
|
+
(ctx, value) => ctx.db.insert(external_dependencies).values(value).returning().get()
|
|
815
|
+
);
|
|
816
|
+
var update5 = safe_query(
|
|
817
|
+
"external_dependencies.update",
|
|
818
|
+
(ctx, id, data) => ctx.db.update(external_dependencies).set(data).where(eq7(external_dependencies.id, id)).run()
|
|
819
|
+
);
|
|
820
|
+
var all2 = safe_query("external_dependencies.all", (ctx) => ctx.db.select().from(external_dependencies).all());
|
|
821
|
+
function get_or_create(ctx, value) {
|
|
822
|
+
return err.pipe(
|
|
823
|
+
() => by_package_subpath_and_name(ctx, { package: value.package, subpath: value.subpath ?? null, name: value.name ?? null }),
|
|
824
|
+
(existing) => existing || insert3(ctx, value)
|
|
825
|
+
);
|
|
826
|
+
}
|
|
827
|
+
var search4 = safe_query(
|
|
828
|
+
"external_dependencies.search",
|
|
829
|
+
(ctx, options = {}) => {
|
|
830
|
+
return do_search(ctx.db, external_dependencies, merge(external_dependencies2, options));
|
|
831
|
+
}
|
|
832
|
+
);
|
|
833
|
+
var used_by_file = safe_query(
|
|
834
|
+
"external_dependencies.used_by_file",
|
|
835
|
+
(ctx, file_id, fields_to_select = external_dependencies2.select) => {
|
|
836
|
+
if (!fields_to_select.includes("id")) fields_to_select.push("id");
|
|
837
|
+
const imports_records = ctx.db.select({ external_dependency_id: external_imports.external_dependency_id }).from(external_imports).where(eq7(external_imports.file_id, file_id)).all();
|
|
838
|
+
const dependency_ids = uniq(imports_records.map((r) => r.external_dependency_id));
|
|
839
|
+
if (dependency_ids.length === 0) return [];
|
|
840
|
+
return ctx.db.select(fields(external_dependencies, fields_to_select)).from(external_dependencies).where(inArray4(external_dependencies.id, dependency_ids)).all();
|
|
841
|
+
}
|
|
842
|
+
);
|
|
843
|
+
var used_by_symbol = safe_query(
|
|
844
|
+
"external_dependencies.used_by_symbol",
|
|
845
|
+
(ctx, symbol_id, fields_to_select = external_dependencies2.select) => {
|
|
846
|
+
if (!fields_to_select.includes("id")) fields_to_select.push("id");
|
|
847
|
+
const link_records = ctx.db.select({ external_import_id: symbol_external_links.external_import_id }).from(symbol_external_links).where(eq7(symbol_external_links.symbol_id, symbol_id)).all();
|
|
848
|
+
if (link_records.length === 0) return [];
|
|
849
|
+
const external_import_ids = uniq(link_records.map((r) => r.external_import_id));
|
|
850
|
+
const imports_records = ctx.db.select({ external_dependency_id: external_imports.external_dependency_id }).from(external_imports).where(inArray4(external_imports.id, external_import_ids)).all();
|
|
851
|
+
const dependency_ids = uniq(imports_records.map((r) => r.external_dependency_id));
|
|
852
|
+
if (dependency_ids.length === 0) return [];
|
|
853
|
+
return ctx.db.select(fields(external_dependencies, fields_to_select)).from(external_dependencies).where(inArray4(external_dependencies.id, dependency_ids)).all();
|
|
854
|
+
}
|
|
855
|
+
);
|
|
856
|
+
|
|
857
|
+
// src/db/external_imports.ts
|
|
858
|
+
var external_imports_exports = {};
|
|
859
|
+
__export(external_imports_exports, {
|
|
860
|
+
by_external_dependency: () => by_external_dependency,
|
|
861
|
+
by_file: () => by_file2,
|
|
862
|
+
by_symbol: () => by_symbol,
|
|
863
|
+
del_by_file: () => del_by_file2,
|
|
864
|
+
insert_many: () => insert_many3
|
|
865
|
+
});
|
|
866
|
+
import { eq as eq8 } from "drizzle-orm";
|
|
867
|
+
var insert_many3 = safe_query(
|
|
868
|
+
"external_imports.insert_many",
|
|
869
|
+
(ctx, values) => ctx.db.insert(external_imports).values(values).run()
|
|
870
|
+
);
|
|
871
|
+
var del_by_file2 = safe_query(
|
|
872
|
+
"external_imports.delete_by_file",
|
|
873
|
+
(ctx, file_id) => ctx.db.delete(external_imports).where(eq8(external_imports.file_id, file_id)).run()
|
|
874
|
+
);
|
|
875
|
+
var by_file2 = safe_query(
|
|
876
|
+
"external_imports.by_file",
|
|
877
|
+
(ctx, file_id) => ctx.db.select().from(external_imports).where(eq8(external_imports.file_id, file_id)).all()
|
|
878
|
+
);
|
|
879
|
+
var by_external_dependency = safe_query(
|
|
880
|
+
"external_imports.by_external_dependency",
|
|
881
|
+
(ctx, external_dependency_id) => ctx.db.select().from(external_imports).where(eq8(external_imports.external_dependency_id, external_dependency_id)).all()
|
|
882
|
+
);
|
|
883
|
+
var by_symbol = safe_query(
|
|
884
|
+
"external_imports.by_symbol",
|
|
885
|
+
(ctx, symbol_id) => ctx.db.query.symbol_external_links.findMany({
|
|
886
|
+
where: eq8(symbol_external_links.symbol_id, symbol_id),
|
|
887
|
+
with: {
|
|
888
|
+
external_import: {
|
|
889
|
+
with: {
|
|
890
|
+
external_dependency: true
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
})
|
|
895
|
+
);
|
|
896
|
+
|
|
897
|
+
// src/db/symbol_internal_links.ts
|
|
898
|
+
var symbol_internal_links_exports = {};
|
|
899
|
+
__export(symbol_internal_links_exports, {
|
|
900
|
+
by_from_symbol: () => by_from_symbol,
|
|
901
|
+
del_by_from_symbol: () => del_by_from_symbol,
|
|
902
|
+
exists: () => exists,
|
|
903
|
+
insert: () => insert4
|
|
904
|
+
});
|
|
905
|
+
import { and as and6, eq as eq9 } from "drizzle-orm";
|
|
906
|
+
var by_from_symbol = safe_query(
|
|
907
|
+
"symbol_internal_links.by_from_symbol",
|
|
908
|
+
(ctx, from_symbol_id) => ctx.db.query.symbol_internal_links.findMany({
|
|
909
|
+
where: eq9(symbol_internal_links.from_symbol_id, from_symbol_id),
|
|
910
|
+
with: {
|
|
911
|
+
to_symbol: {
|
|
912
|
+
with: {
|
|
913
|
+
file: true
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
})
|
|
918
|
+
);
|
|
919
|
+
var insert4 = safe_query(
|
|
920
|
+
"symbol_internal_links.insert",
|
|
921
|
+
(ctx, value) => ctx.db.insert(symbol_internal_links).values(value).run()
|
|
922
|
+
);
|
|
923
|
+
var exists = safe_query(
|
|
924
|
+
"symbol_internal_links.exists",
|
|
925
|
+
(ctx, params) => ctx.db.select({ id: symbol_internal_links.id }).from(symbol_internal_links).where(and6(eq9(symbol_internal_links.from_symbol_id, params.from_symbol_id), eq9(symbol_internal_links.to_symbol_id, params.to_symbol_id))).get()
|
|
926
|
+
);
|
|
927
|
+
var del_by_from_symbol = safe_query(
|
|
928
|
+
"symbol_internal_links.del_by_from_symbol",
|
|
929
|
+
(ctx, from_symbol_id) => ctx.db.delete(symbol_internal_links).where(eq9(symbol_internal_links.from_symbol_id, from_symbol_id)).run()
|
|
930
|
+
);
|
|
931
|
+
|
|
932
|
+
// src/db/symbol_external_links.ts
|
|
933
|
+
var symbol_external_links_exports = {};
|
|
934
|
+
__export(symbol_external_links_exports, {
|
|
935
|
+
by_external_import: () => by_external_import,
|
|
936
|
+
by_symbol: () => by_symbol2,
|
|
937
|
+
del_by_symbol: () => del_by_symbol,
|
|
938
|
+
exists: () => exists2,
|
|
939
|
+
insert: () => insert5
|
|
940
|
+
});
|
|
941
|
+
import { and as and7, eq as eq10 } from "drizzle-orm";
|
|
942
|
+
var by_symbol2 = safe_query(
|
|
943
|
+
"symbol_external_links.by_symbol",
|
|
944
|
+
(ctx, symbol_id) => ctx.db.select().from(symbol_external_links).where(eq10(symbol_external_links.symbol_id, symbol_id)).all()
|
|
945
|
+
);
|
|
946
|
+
var insert5 = safe_query(
|
|
947
|
+
"symbol_external_links.insert",
|
|
948
|
+
(ctx, value) => ctx.db.insert(symbol_external_links).values(value).run()
|
|
949
|
+
);
|
|
950
|
+
var by_external_import = safe_query(
|
|
951
|
+
"symbol_external_links.by_external_import",
|
|
952
|
+
(ctx, external_import_id) => ctx.db.select().from(symbol_external_links).where(eq10(symbol_external_links.external_import_id, external_import_id)).all()
|
|
953
|
+
);
|
|
954
|
+
var exists2 = safe_query(
|
|
955
|
+
"symbol_external_links.exists",
|
|
956
|
+
(ctx, params) => ctx.db.select({ id: symbol_external_links.id }).from(symbol_external_links).where(and7(eq10(symbol_external_links.symbol_id, params.symbol_id), eq10(symbol_external_links.external_import_id, params.external_import_id))).get()
|
|
957
|
+
);
|
|
958
|
+
var del_by_symbol = safe_query(
|
|
959
|
+
"symbol_external_links.del_by_symbol",
|
|
960
|
+
(ctx, symbol_id) => ctx.db.delete(symbol_external_links).where(eq10(symbol_external_links.symbol_id, symbol_id)).run()
|
|
961
|
+
);
|
|
962
|
+
|
|
963
|
+
// src/internals/context.ts
|
|
964
|
+
async function create_context(sqlite, db6, config) {
|
|
965
|
+
const project_path = path.resolve(config.project_path);
|
|
966
|
+
const currentDir = dirname(fileURLToPath(import.meta.url));
|
|
967
|
+
const migrations_path = currentDir.includes("/dist") ? join2(currentDir, "../migrations") : join2(currentDir, "../../migrations");
|
|
968
|
+
const tsconfig_path = join2(project_path, "tsconfig.json");
|
|
969
|
+
if (!ts.sys.fileExists(tsconfig_path)) {
|
|
970
|
+
throw err.new("file_not_found", { path: tsconfig_path });
|
|
971
|
+
}
|
|
972
|
+
const tsconfig = ts.parseJsonConfigFileContent(ts.readConfigFile(tsconfig_path, ts.sys.readFile).config, ts.sys, project_path);
|
|
973
|
+
const program = ts.createProgram({ rootNames: tsconfig.fileNames, options: tsconfig.options });
|
|
974
|
+
const package_json_path = config.package_json_path ?? path.join(project_path, "package.json");
|
|
975
|
+
const node_modules_paths = config.node_modules_paths ?? [path.join(project_path, "node_modules")];
|
|
976
|
+
const dependencies2 = await get_dependencies(package_json_path, node_modules_paths);
|
|
977
|
+
const ctx = { db: db6, sqlite, migrations_path, project_path, program, dependencies: dependencies2 };
|
|
978
|
+
await migrate(ctx);
|
|
979
|
+
err.or_throw(
|
|
980
|
+
configs_exports.upsert(ctx, {
|
|
981
|
+
project_path,
|
|
982
|
+
description: config.description ?? null,
|
|
983
|
+
package_json_path: config.package_json_path ?? null,
|
|
984
|
+
node_modules_paths: config.node_modules_paths ? JSON.stringify(config.node_modules_paths) : null
|
|
985
|
+
})
|
|
986
|
+
);
|
|
987
|
+
return ctx;
|
|
988
|
+
}
|
|
989
|
+
async function context_from_config(config) {
|
|
990
|
+
const sqlite = new Database(config.db_path);
|
|
991
|
+
sqlite.pragma("foreign_keys = ON");
|
|
992
|
+
const db6 = drizzle(sqlite, { schema: schema_exports });
|
|
993
|
+
return create_context(sqlite, db6, config);
|
|
994
|
+
}
|
|
995
|
+
async function context_from_db(db_path) {
|
|
996
|
+
const sqlite = new Database(db_path);
|
|
997
|
+
sqlite.pragma("foreign_keys = ON");
|
|
998
|
+
const db6 = drizzle(sqlite, { schema: schema_exports });
|
|
999
|
+
const temp_ctx = { db: db6, sqlite };
|
|
1000
|
+
const stored = err.or_throw(configs_exports.get(temp_ctx));
|
|
1001
|
+
if (!stored) {
|
|
1002
|
+
sqlite.close();
|
|
1003
|
+
throw err.new("config_not_found", { db_path });
|
|
1004
|
+
}
|
|
1005
|
+
let node_modules_paths;
|
|
1006
|
+
if (stored.node_modules_paths) {
|
|
1007
|
+
try {
|
|
1008
|
+
node_modules_paths = JSON.parse(stored.node_modules_paths);
|
|
1009
|
+
} catch (parse_error) {
|
|
1010
|
+
sqlite.close();
|
|
1011
|
+
throw err.new("config_invalid_node_modules_paths", { db_path, reason: parse_error });
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
return create_context(sqlite, db6, {
|
|
1015
|
+
db_path,
|
|
1016
|
+
project_path: stored.project_path,
|
|
1017
|
+
description: stored.description ?? void 0,
|
|
1018
|
+
package_json_path: stored.package_json_path ?? void 0,
|
|
1019
|
+
node_modules_paths
|
|
1020
|
+
});
|
|
1021
|
+
}
|
|
1022
|
+
async function get_dependencies(package_json_path, node_modules_paths) {
|
|
1023
|
+
const dependencies2 = {};
|
|
1024
|
+
const package_json = JSON.parse(await readFile2(package_json_path, "utf-8"));
|
|
1025
|
+
const packages = { ...package_json.dependencies ?? {}, ...package_json.devDependencies ?? {} };
|
|
1026
|
+
for (const [name, version] of Object.entries(packages)) {
|
|
1027
|
+
dependencies2[name] = { name, version, github_repo: await get_github_repo(node_modules_paths, name) };
|
|
1028
|
+
}
|
|
1029
|
+
return dependencies2;
|
|
1030
|
+
}
|
|
1031
|
+
async function get_github_repo(node_modules_paths, package_name) {
|
|
1032
|
+
for (const node_modules_path of node_modules_paths) {
|
|
1033
|
+
try {
|
|
1034
|
+
const package_json_path = path.join(node_modules_path, package_name, "package.json");
|
|
1035
|
+
const package_json = JSON.parse(await readFile2(package_json_path, "utf-8"));
|
|
1036
|
+
const url = package_json.repository?.url || package_json.repository;
|
|
1037
|
+
if (typeof url === "string") {
|
|
1038
|
+
let repo = url.split("/").slice(-2).join("/");
|
|
1039
|
+
if (repo.endsWith(".git")) repo = repo.slice(0, -4);
|
|
1040
|
+
return repo.split(":").pop();
|
|
1041
|
+
}
|
|
1042
|
+
} catch {
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
return void 0;
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
// src/cli/env.ts
|
|
1049
|
+
var env = {
|
|
1050
|
+
read_file,
|
|
1051
|
+
file_exists: (path6) => existsSync(path6),
|
|
1052
|
+
argv: () => process.argv,
|
|
1053
|
+
log: (...args) => console.log(...args),
|
|
1054
|
+
error: (...args) => console.error(...args),
|
|
1055
|
+
exit: (code) => process.exit(code)
|
|
1056
|
+
};
|
|
1057
|
+
|
|
1058
|
+
// src/cli/index.ts
|
|
1059
|
+
import { Command as Command30 } from "commander";
|
|
1060
|
+
|
|
1061
|
+
// src/cli/commands/update.ts
|
|
1062
|
+
import { Command } from "commander";
|
|
1063
|
+
|
|
1064
|
+
// src/cli/commands/_common.ts
|
|
1065
|
+
import "zod";
|
|
1066
|
+
|
|
1067
|
+
// src/cli/schema.ts
|
|
1068
|
+
import { z } from "zod";
|
|
1069
|
+
var Config = z.object({
|
|
1070
|
+
db_path: z.string().describe("Path to SQLite database"),
|
|
1071
|
+
project_path: z.string().describe("Path to TypeScript project"),
|
|
1072
|
+
description: z.string().optional(),
|
|
1073
|
+
package_json_path: z.string().optional(),
|
|
1074
|
+
node_modules_paths: z.array(z.string()).optional()
|
|
1075
|
+
});
|
|
1076
|
+
var StringFilter = z.union([
|
|
1077
|
+
z.string(),
|
|
1078
|
+
z.object({ contains: z.string() }),
|
|
1079
|
+
z.object({ starts_with: z.string() }),
|
|
1080
|
+
z.object({ ends_with: z.string() })
|
|
1081
|
+
]);
|
|
1082
|
+
var OrderDirection = z.enum(["asc", "desc"]);
|
|
1083
|
+
var FileField = z.enum(["id", "directory_id", "path", "description", "state", "error"]);
|
|
1084
|
+
var FileState = z.enum(["to_scan", "to_describe", "ready"]);
|
|
1085
|
+
var FileSearchOptions = z.object({
|
|
1086
|
+
select: z.array(FileField).optional(),
|
|
1087
|
+
limit: z.number().int().positive().optional(),
|
|
1088
|
+
offset: z.number().int().nonnegative().optional(),
|
|
1089
|
+
where: z.object({
|
|
1090
|
+
id: z.number().optional(),
|
|
1091
|
+
directory_id: z.number().optional(),
|
|
1092
|
+
path: StringFilter.optional(),
|
|
1093
|
+
description: StringFilter.optional(),
|
|
1094
|
+
state: z.union([FileState, z.object({ contains: z.string() })]).optional(),
|
|
1095
|
+
error: StringFilter.optional()
|
|
1096
|
+
}).optional(),
|
|
1097
|
+
order_by: z.tuple([FileField, OrderDirection]).optional()
|
|
1098
|
+
});
|
|
1099
|
+
var FileRelationOptions = z.object({
|
|
1100
|
+
select: z.array(FileField).optional(),
|
|
1101
|
+
limit: z.number().int().positive().optional(),
|
|
1102
|
+
offset: z.number().int().nonnegative().optional(),
|
|
1103
|
+
deep: z.boolean().optional()
|
|
1104
|
+
});
|
|
1105
|
+
var SymbolField = z.enum(["id", "file_id", "type", "name", "text", "meta", "description", "is_exported", "state", "error"]);
|
|
1106
|
+
var SymbolType = z.enum(["function", "class", "class_method", "class_property", "variable", "type"]);
|
|
1107
|
+
var SymbolState = z.enum(["to_link", "to_describe", "ready"]);
|
|
1108
|
+
var SymbolSearchOptions = z.object({
|
|
1109
|
+
select: z.array(SymbolField).optional(),
|
|
1110
|
+
limit: z.number().int().positive().optional(),
|
|
1111
|
+
offset: z.number().int().nonnegative().optional(),
|
|
1112
|
+
where: z.object({
|
|
1113
|
+
id: z.number().optional(),
|
|
1114
|
+
file_id: z.number().optional(),
|
|
1115
|
+
type: z.union([SymbolType, z.object({ contains: z.string() })]).optional(),
|
|
1116
|
+
name: StringFilter.optional(),
|
|
1117
|
+
text: StringFilter.optional(),
|
|
1118
|
+
meta: StringFilter.optional(),
|
|
1119
|
+
description: StringFilter.optional(),
|
|
1120
|
+
is_exported: z.boolean().optional(),
|
|
1121
|
+
state: z.union([SymbolState, z.object({ contains: z.string() })]).optional(),
|
|
1122
|
+
error: StringFilter.optional()
|
|
1123
|
+
}).optional(),
|
|
1124
|
+
order_by: z.tuple([SymbolField, OrderDirection]).optional()
|
|
1125
|
+
});
|
|
1126
|
+
var SymbolRelationOptions = z.object({
|
|
1127
|
+
select: z.array(SymbolField).optional(),
|
|
1128
|
+
limit: z.number().int().positive().optional(),
|
|
1129
|
+
offset: z.number().int().nonnegative().optional(),
|
|
1130
|
+
deep: z.boolean().optional()
|
|
1131
|
+
});
|
|
1132
|
+
var DirectoryField = z.enum(["id", "parent_id", "path", "description", "state", "error"]);
|
|
1133
|
+
var DirectoryState = z.enum(["to_describe", "ready"]);
|
|
1134
|
+
var DirectorySearchOptions = z.object({
|
|
1135
|
+
select: z.array(DirectoryField).optional(),
|
|
1136
|
+
limit: z.number().int().positive().optional(),
|
|
1137
|
+
offset: z.number().int().nonnegative().optional(),
|
|
1138
|
+
where: z.object({
|
|
1139
|
+
id: z.number().optional(),
|
|
1140
|
+
parent_id: z.number().optional(),
|
|
1141
|
+
path: StringFilter.optional(),
|
|
1142
|
+
description: StringFilter.optional(),
|
|
1143
|
+
state: z.union([DirectoryState, z.object({ contains: z.string() })]).optional(),
|
|
1144
|
+
error: StringFilter.optional()
|
|
1145
|
+
}).optional(),
|
|
1146
|
+
order_by: z.tuple([DirectoryField, OrderDirection]).optional()
|
|
1147
|
+
});
|
|
1148
|
+
var DirectoryRelationOptions = z.object({
|
|
1149
|
+
select: z.array(DirectoryField).optional(),
|
|
1150
|
+
limit: z.number().int().positive().optional(),
|
|
1151
|
+
offset: z.number().int().nonnegative().optional(),
|
|
1152
|
+
deep: z.boolean().optional()
|
|
1153
|
+
});
|
|
1154
|
+
var DependencyField = z.enum(["id", "package", "subpath", "name", "version", "github_repo", "is_builtin", "description", "state", "error"]);
|
|
1155
|
+
var DependencyState = z.enum(["to_describe", "ready"]);
|
|
1156
|
+
var DependencySearchOptions = z.object({
|
|
1157
|
+
select: z.array(DependencyField).optional(),
|
|
1158
|
+
limit: z.number().int().positive().optional(),
|
|
1159
|
+
offset: z.number().int().nonnegative().optional(),
|
|
1160
|
+
where: z.object({
|
|
1161
|
+
id: z.number().optional(),
|
|
1162
|
+
package: StringFilter.optional(),
|
|
1163
|
+
subpath: StringFilter.optional(),
|
|
1164
|
+
name: StringFilter.optional(),
|
|
1165
|
+
version: StringFilter.optional(),
|
|
1166
|
+
github_repo: StringFilter.optional(),
|
|
1167
|
+
is_builtin: z.boolean().optional(),
|
|
1168
|
+
description: StringFilter.optional(),
|
|
1169
|
+
state: z.union([DependencyState, z.object({ contains: z.string() })]).optional(),
|
|
1170
|
+
error: StringFilter.optional()
|
|
1171
|
+
}).optional(),
|
|
1172
|
+
order_by: z.tuple([DependencyField, OrderDirection]).optional()
|
|
1173
|
+
});
|
|
1174
|
+
var DependencySelectOptions = z.object({
|
|
1175
|
+
select: z.array(DependencyField).optional(),
|
|
1176
|
+
limit: z.number().int().positive().optional(),
|
|
1177
|
+
offset: z.number().int().nonnegative().optional()
|
|
1178
|
+
});
|
|
1179
|
+
|
|
1180
|
+
// src/update/track_changes.ts
|
|
1181
|
+
import path2 from "path";
|
|
1182
|
+
import "typescript";
|
|
1183
|
+
import { stat } from "fs/promises";
|
|
1184
|
+
|
|
1185
|
+
// src/update/events.ts
|
|
1186
|
+
function file_updated(ctx, file_id) {
|
|
1187
|
+
const impacted_files_ids = err.or_throw(
|
|
1188
|
+
expand({
|
|
1189
|
+
items: [file_id],
|
|
1190
|
+
get_key: (id) => id,
|
|
1191
|
+
get_children: (id) => {
|
|
1192
|
+
const imports2 = imports_exports.by_exporter_file(ctx, id);
|
|
1193
|
+
if (err.any(imports2)) return imports2;
|
|
1194
|
+
return imports2.map((x) => x.importer_file_id);
|
|
1195
|
+
}
|
|
1196
|
+
})
|
|
1197
|
+
);
|
|
1198
|
+
const dir_ids = err.or_throw(files_exports.get_directory_ids(ctx, impacted_files_ids));
|
|
1199
|
+
const impacted_dirs_ids = err.or_throw(
|
|
1200
|
+
expand({
|
|
1201
|
+
items: dir_ids,
|
|
1202
|
+
get_key: (id) => id,
|
|
1203
|
+
get_children: (id) => {
|
|
1204
|
+
const dir = directories_exports.by_id(ctx, id);
|
|
1205
|
+
if (err.any(dir)) return dir;
|
|
1206
|
+
return dir?.parent_id ? [dir.parent_id] : [];
|
|
1207
|
+
}
|
|
1208
|
+
})
|
|
1209
|
+
);
|
|
1210
|
+
err.or_throw(files_exports.update_many(ctx, impacted_files_ids, { state: "to_scan" }));
|
|
1211
|
+
err.or_throw(directories_exports.update_many(ctx, impacted_dirs_ids, { state: "to_describe" }));
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
// src/update/track_changes.ts
|
|
1215
|
+
async function track_changes(ctx) {
|
|
1216
|
+
const db_files = err.or_throw(files_exports.all(ctx));
|
|
1217
|
+
const { created, updated, deleted } = await changes(ctx, get_source_files(ctx), db_files);
|
|
1218
|
+
for (const { source_file, hash } of created) handle_new_source_file(ctx, source_file, hash);
|
|
1219
|
+
for (const { db_file, hash } of updated) handle_changed_source_file(ctx, db_file, hash);
|
|
1220
|
+
for (const { db_file } of deleted) handle_deleted_source_file(ctx, db_file);
|
|
1221
|
+
}
|
|
1222
|
+
function get_source_files(ctx) {
|
|
1223
|
+
const src_files = [];
|
|
1224
|
+
for (const file of ctx.program.getSourceFiles()) {
|
|
1225
|
+
if (ctx.program.isSourceFileDefaultLibrary(file)) continue;
|
|
1226
|
+
if (ctx.program.isSourceFileFromExternalLibrary(file)) continue;
|
|
1227
|
+
if (!path2.resolve(file.fileName).startsWith(ctx.project_path)) continue;
|
|
1228
|
+
src_files.push(file);
|
|
1229
|
+
}
|
|
1230
|
+
return src_files;
|
|
1231
|
+
}
|
|
1232
|
+
function handle_new_source_file(ctx, file, hash) {
|
|
1233
|
+
const file_path = err.or_throw(get_file_path(ctx, file));
|
|
1234
|
+
const dirs_paths = err.or_throw(get_parents_paths(ctx, file));
|
|
1235
|
+
let parent_dir_id = null;
|
|
1236
|
+
for (const dir_path of dirs_paths) {
|
|
1237
|
+
let dir = err.or_throw(directories_exports.by_path(ctx, dir_path));
|
|
1238
|
+
if (dir) {
|
|
1239
|
+
err.or_throw(directories_exports.update(ctx, dir.id, { state: "to_describe" }));
|
|
1240
|
+
} else {
|
|
1241
|
+
dir = err.or_throw(directories_exports.insert(ctx, { path: dir_path, state: "to_describe", parent_id: parent_dir_id }));
|
|
1242
|
+
}
|
|
1243
|
+
parent_dir_id = dir.id;
|
|
1244
|
+
}
|
|
1245
|
+
err.or_throw(files_exports.insert(ctx, { directory_id: parent_dir_id, path: file_path, state: "to_scan", hash }));
|
|
1246
|
+
}
|
|
1247
|
+
function handle_changed_source_file(ctx, db_file, hash) {
|
|
1248
|
+
file_updated(ctx, db_file.id);
|
|
1249
|
+
err.or_throw(files_exports.update(ctx, db_file.id, { hash }));
|
|
1250
|
+
}
|
|
1251
|
+
function handle_deleted_source_file(ctx, db_file) {
|
|
1252
|
+
err.or_throw(handle_changed_source_file(ctx, db_file, ""));
|
|
1253
|
+
err.or_throw(files_exports.del(ctx, db_file.id));
|
|
1254
|
+
}
|
|
1255
|
+
async function changes(ctx, source_files, db_files) {
|
|
1256
|
+
const created = [];
|
|
1257
|
+
const updated = [];
|
|
1258
|
+
const deleted = [];
|
|
1259
|
+
const db_files_index = group_by_unique(db_files, (x) => x.path);
|
|
1260
|
+
const source_files_index = group_by_unique(source_files, (x) => err.or(get_file_path(ctx, x), ""));
|
|
1261
|
+
const filenames = new Set(Object.keys(source_files_index).concat(Object.keys(db_files_index)));
|
|
1262
|
+
for (const filename of filenames) {
|
|
1263
|
+
const db_file = db_files_index[filename];
|
|
1264
|
+
const source_file = source_files_index[filename];
|
|
1265
|
+
if (!db_file && source_file) created.push({ source_file, hash: await file_signature(source_file.fileName) });
|
|
1266
|
+
if (db_file && !source_file) deleted.push({ db_file });
|
|
1267
|
+
if (db_file && source_file) {
|
|
1268
|
+
const hash = await file_signature(source_file.fileName);
|
|
1269
|
+
if (db_file.hash !== hash) updated.push({ db_file, source_file, hash });
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
return { created, updated, deleted };
|
|
1273
|
+
}
|
|
1274
|
+
function get_file_path(ctx, file) {
|
|
1275
|
+
const absolute_path = path2.resolve(file.fileName);
|
|
1276
|
+
if (absolute_path.startsWith(ctx.project_path)) return absolute_path.slice(ctx.project_path.length);
|
|
1277
|
+
return err.new("file_outside_project_path", { file_path: absolute_path, project_path: ctx.project_path });
|
|
1278
|
+
}
|
|
1279
|
+
function get_parents_paths(ctx, file) {
|
|
1280
|
+
const file_path = get_file_path(ctx, file);
|
|
1281
|
+
if (err.any(file_path)) return file_path;
|
|
1282
|
+
const dirs = [];
|
|
1283
|
+
let current = path2.dirname(file_path);
|
|
1284
|
+
while (current !== path2.sep) {
|
|
1285
|
+
dirs.push(current);
|
|
1286
|
+
current = path2.dirname(current);
|
|
1287
|
+
}
|
|
1288
|
+
dirs.push(current);
|
|
1289
|
+
return dirs.reverse();
|
|
1290
|
+
}
|
|
1291
|
+
async function file_signature(file_path) {
|
|
1292
|
+
const stats = await stat(file_path);
|
|
1293
|
+
return `${stats.mtimeMs}:${stats.size}`;
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
// src/update/sync_external_dependencies.ts
|
|
1297
|
+
async function sync_external_dependencies(ctx) {
|
|
1298
|
+
const db_deps = err.or_throw(external_dependencies_exports.all(ctx));
|
|
1299
|
+
for (const ctx_dep of Object.values(ctx.dependencies)) {
|
|
1300
|
+
const existing = db_deps.filter((d) => d.package === ctx_dep.name);
|
|
1301
|
+
if (existing.length === 0) continue;
|
|
1302
|
+
const needs_update = existing.some((d) => d.version !== ctx_dep.version || (d.github_repo || "") !== (ctx_dep.github_repo || ""));
|
|
1303
|
+
if (!needs_update) continue;
|
|
1304
|
+
for (const db_dep of existing) {
|
|
1305
|
+
err.or_throw(
|
|
1306
|
+
external_dependencies_exports.update(ctx, db_dep.id, {
|
|
1307
|
+
version: ctx_dep.version,
|
|
1308
|
+
github_repo: ctx_dep.github_repo,
|
|
1309
|
+
state: "to_describe",
|
|
1310
|
+
error: null
|
|
1311
|
+
})
|
|
1312
|
+
);
|
|
1313
|
+
const files5 = err.or_throw(files_exports.using_dependency(ctx, db_dep.id, ["id"]));
|
|
1314
|
+
for (const file of files5) file_updated(ctx, file.id);
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
// src/update/scan_files/scan_files.ts
|
|
1320
|
+
import path4 from "path";
|
|
1321
|
+
import ts10 from "typescript";
|
|
1322
|
+
|
|
1323
|
+
// src/update/scan_files/imports.ts
|
|
1324
|
+
import ts4 from "typescript";
|
|
1325
|
+
|
|
1326
|
+
// src/update/scan_files/common.ts
|
|
1327
|
+
import path3 from "path";
|
|
1328
|
+
import ts3 from "typescript";
|
|
1329
|
+
function is_external_module(ctx, source_file, module_path) {
|
|
1330
|
+
const resolved = ts3.resolveModuleName(module_path, source_file.fileName, ctx.program.getCompilerOptions(), ts3.sys);
|
|
1331
|
+
if (!resolved.resolvedModule) return true;
|
|
1332
|
+
const resolved_path = path3.resolve(resolved.resolvedModule.resolvedFileName);
|
|
1333
|
+
return !resolved_path.startsWith(ctx.project_path);
|
|
1334
|
+
}
|
|
1335
|
+
function has_export_modifier(node) {
|
|
1336
|
+
if (!ts3.canHaveModifiers(node)) return false;
|
|
1337
|
+
const modifiers = ts3.getModifiers(node);
|
|
1338
|
+
if (!modifiers) return false;
|
|
1339
|
+
return modifiers.some((m) => m.kind === ts3.SyntaxKind.ExportKeyword);
|
|
1340
|
+
}
|
|
1341
|
+
function has_default_modifier(node) {
|
|
1342
|
+
if (!ts3.canHaveModifiers(node)) return false;
|
|
1343
|
+
const modifiers = ts3.getModifiers(node);
|
|
1344
|
+
if (!modifiers) return false;
|
|
1345
|
+
return modifiers.some((m) => m.kind === ts3.SyntaxKind.DefaultKeyword);
|
|
1346
|
+
}
|
|
1347
|
+
function extract_parameters(node, source_file) {
|
|
1348
|
+
return node.parameters.map((param) => ({
|
|
1349
|
+
name: ts3.isIdentifier(param.name) ? param.name.text : param.name.getText(source_file),
|
|
1350
|
+
type: param.type ? param.type.getText(source_file) : null,
|
|
1351
|
+
optional: !!param.questionToken,
|
|
1352
|
+
rest: !!param.dotDotDotToken,
|
|
1353
|
+
default: param.initializer ? param.initializer.getText(source_file) : null
|
|
1354
|
+
}));
|
|
1355
|
+
}
|
|
1356
|
+
function extract_type_parameters(node, source_file) {
|
|
1357
|
+
if (!("typeParameters" in node) || !node.typeParameters) return [];
|
|
1358
|
+
return node.typeParameters.map((tp) => tp.getText(source_file));
|
|
1359
|
+
}
|
|
1360
|
+
function extract_jsdoc_comment(node, source_file) {
|
|
1361
|
+
const sf = source_file || node.getSourceFile();
|
|
1362
|
+
if (!sf) return null;
|
|
1363
|
+
const sourceText = sf.getFullText();
|
|
1364
|
+
const ranges = ts3.getLeadingCommentRanges(sourceText, node.getFullStart());
|
|
1365
|
+
if (!ranges || ranges.length === 0) return null;
|
|
1366
|
+
const lastComment = ranges[ranges.length - 1];
|
|
1367
|
+
if (!lastComment) return null;
|
|
1368
|
+
const commentText = sourceText.slice(lastComment.pos, lastComment.end);
|
|
1369
|
+
if (commentText.startsWith("/**")) {
|
|
1370
|
+
return commentText;
|
|
1371
|
+
}
|
|
1372
|
+
return null;
|
|
1373
|
+
}
|
|
1374
|
+
function extract_decorators(node, source_file) {
|
|
1375
|
+
if (!ts3.canHaveDecorators(node)) return [];
|
|
1376
|
+
const decorators = ts3.getDecorators(node);
|
|
1377
|
+
if (!decorators) return [];
|
|
1378
|
+
const sf = source_file || node.getSourceFile();
|
|
1379
|
+
return decorators.map((decorator) => {
|
|
1380
|
+
const expr = decorator.expression;
|
|
1381
|
+
if (ts3.isIdentifier(expr)) {
|
|
1382
|
+
return { name: expr.text };
|
|
1383
|
+
}
|
|
1384
|
+
if (ts3.isCallExpression(expr) && ts3.isIdentifier(expr.expression)) {
|
|
1385
|
+
return {
|
|
1386
|
+
name: expr.expression.text,
|
|
1387
|
+
arguments: expr.arguments.map((arg) => arg.getText(sf))
|
|
1388
|
+
};
|
|
1389
|
+
}
|
|
1390
|
+
return { name: decorator.expression.getText(sf) };
|
|
1391
|
+
});
|
|
1392
|
+
}
|
|
1393
|
+
function is_builtin_module(package_name) {
|
|
1394
|
+
const builtins = [
|
|
1395
|
+
"fs",
|
|
1396
|
+
"path",
|
|
1397
|
+
"http",
|
|
1398
|
+
"https",
|
|
1399
|
+
"url",
|
|
1400
|
+
"crypto",
|
|
1401
|
+
"os",
|
|
1402
|
+
"util",
|
|
1403
|
+
"stream",
|
|
1404
|
+
"events",
|
|
1405
|
+
"buffer",
|
|
1406
|
+
"child_process",
|
|
1407
|
+
"cluster",
|
|
1408
|
+
"dns",
|
|
1409
|
+
"net",
|
|
1410
|
+
"tls",
|
|
1411
|
+
"dgram",
|
|
1412
|
+
"readline",
|
|
1413
|
+
"repl",
|
|
1414
|
+
"vm",
|
|
1415
|
+
"zlib",
|
|
1416
|
+
"assert",
|
|
1417
|
+
"querystring",
|
|
1418
|
+
"string_decoder",
|
|
1419
|
+
"timers",
|
|
1420
|
+
"tty",
|
|
1421
|
+
"v8",
|
|
1422
|
+
"worker_threads"
|
|
1423
|
+
];
|
|
1424
|
+
return builtins.includes(package_name) || package_name.startsWith("node:");
|
|
1425
|
+
}
|
|
1426
|
+
function is_dynamic_import(node) {
|
|
1427
|
+
if (!ts3.isCallExpression(node)) return false;
|
|
1428
|
+
if (node.expression.kind !== ts3.SyntaxKind.ImportKeyword) return false;
|
|
1429
|
+
if (node.arguments.length !== 1) return false;
|
|
1430
|
+
const arg = node.arguments[0];
|
|
1431
|
+
if (!arg) return false;
|
|
1432
|
+
return ts3.isStringLiteral(arg);
|
|
1433
|
+
}
|
|
1434
|
+
|
|
1435
|
+
// src/update/scan_files/imports.ts
|
|
1436
|
+
function is_import(ctx, source_file, node) {
|
|
1437
|
+
if (!ts4.isImportDeclaration(node) || !node.moduleSpecifier || !ts4.isStringLiteral(node.moduleSpecifier)) return false;
|
|
1438
|
+
return !is_external_module(ctx, source_file, node.moduleSpecifier.text);
|
|
1439
|
+
}
|
|
1440
|
+
function extract_import(ctx, source_file, node, file_id) {
|
|
1441
|
+
const imports2 = [];
|
|
1442
|
+
const clause = node.importClause;
|
|
1443
|
+
if (!clause || !node.moduleSpecifier || !ts4.isStringLiteral(node.moduleSpecifier)) return imports2;
|
|
1444
|
+
const exporter_file_id = resolve_exporter_file(ctx, source_file, node.moduleSpecifier.text);
|
|
1445
|
+
if (err.any(exporter_file_id)) return imports2;
|
|
1446
|
+
if (clause.name) {
|
|
1447
|
+
imports2.push({
|
|
1448
|
+
importer_file_id: file_id,
|
|
1449
|
+
exporter_file_id,
|
|
1450
|
+
name: "default",
|
|
1451
|
+
alias: clause.name.text,
|
|
1452
|
+
state: "to_link"
|
|
1453
|
+
});
|
|
1454
|
+
}
|
|
1455
|
+
if (clause.namedBindings && ts4.isNamedImports(clause.namedBindings)) {
|
|
1456
|
+
for (const element of clause.namedBindings.elements) {
|
|
1457
|
+
imports2.push({
|
|
1458
|
+
importer_file_id: file_id,
|
|
1459
|
+
exporter_file_id,
|
|
1460
|
+
name: (element.propertyName || element.name).text,
|
|
1461
|
+
alias: element.name.text,
|
|
1462
|
+
state: "to_link"
|
|
1463
|
+
});
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
if (clause.namedBindings && ts4.isNamespaceImport(clause.namedBindings)) {
|
|
1467
|
+
imports2.push({
|
|
1468
|
+
importer_file_id: file_id,
|
|
1469
|
+
exporter_file_id,
|
|
1470
|
+
name: "*",
|
|
1471
|
+
alias: clause.namedBindings.name.text,
|
|
1472
|
+
state: "to_link"
|
|
1473
|
+
});
|
|
1474
|
+
}
|
|
1475
|
+
return imports2;
|
|
1476
|
+
}
|
|
1477
|
+
function extract_dynamic_import(ctx, source_file, node, file_id) {
|
|
1478
|
+
const arg = node.arguments[0];
|
|
1479
|
+
const module_specifier = arg.text;
|
|
1480
|
+
const exporter_file_id = resolve_exporter_file(ctx, source_file, module_specifier);
|
|
1481
|
+
if (err.any(exporter_file_id)) return null;
|
|
1482
|
+
return {
|
|
1483
|
+
importer_file_id: file_id,
|
|
1484
|
+
exporter_file_id,
|
|
1485
|
+
name: "*",
|
|
1486
|
+
alias: "__dynamic_import__",
|
|
1487
|
+
state: "to_link",
|
|
1488
|
+
is_dynamic: true
|
|
1489
|
+
};
|
|
1490
|
+
}
|
|
1491
|
+
function resolve_exporter_file(ctx, source_file, module_specifier) {
|
|
1492
|
+
const resolution = ts4.resolveModuleName(module_specifier, source_file.fileName, ctx.program.getCompilerOptions(), ts4.sys);
|
|
1493
|
+
if (!resolution.resolvedModule) {
|
|
1494
|
+
return err.new("module_resolution_failed", { module: module_specifier, from: source_file.fileName });
|
|
1495
|
+
}
|
|
1496
|
+
const resolved_path = resolution.resolvedModule.resolvedFileName;
|
|
1497
|
+
const file_path = resolved_path.startsWith(ctx.project_path) ? resolved_path.slice(ctx.project_path.length) : resolved_path;
|
|
1498
|
+
const file = files_exports.by_path(ctx, file_path);
|
|
1499
|
+
if (err.any(file)) return file;
|
|
1500
|
+
if (!file) {
|
|
1501
|
+
return err.new("exporter_file_not_found", { path: file_path, module: module_specifier });
|
|
1502
|
+
}
|
|
1503
|
+
return file.id;
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1506
|
+
// src/update/scan_files/external_imports.ts
|
|
1507
|
+
import ts5 from "typescript";
|
|
1508
|
+
function is_external_import(ctx, source_file, node) {
|
|
1509
|
+
if (!ts5.isImportDeclaration(node) || !node.moduleSpecifier || !ts5.isStringLiteral(node.moduleSpecifier)) return false;
|
|
1510
|
+
return is_external_module(ctx, source_file, node.moduleSpecifier.text);
|
|
1511
|
+
}
|
|
1512
|
+
function parse_module_specifier(spec) {
|
|
1513
|
+
let is_builtin = false;
|
|
1514
|
+
let normalized = spec;
|
|
1515
|
+
if (spec.startsWith("node:")) {
|
|
1516
|
+
normalized = spec.slice(5);
|
|
1517
|
+
is_builtin = true;
|
|
1518
|
+
} else {
|
|
1519
|
+
is_builtin = is_builtin_module(spec);
|
|
1520
|
+
}
|
|
1521
|
+
if (normalized.startsWith("@")) {
|
|
1522
|
+
const parts = normalized.split("/");
|
|
1523
|
+
if (parts.length <= 2) {
|
|
1524
|
+
return { pkg: normalized, subpath: null, is_builtin };
|
|
1525
|
+
}
|
|
1526
|
+
const pkg = `${parts[0]}/${parts[1]}`;
|
|
1527
|
+
const subpath = "/" + parts.slice(2).join("/");
|
|
1528
|
+
return { pkg, subpath, is_builtin };
|
|
1529
|
+
} else {
|
|
1530
|
+
const slash_idx = normalized.indexOf("/");
|
|
1531
|
+
if (slash_idx === -1) {
|
|
1532
|
+
return { pkg: normalized, subpath: null, is_builtin };
|
|
1533
|
+
}
|
|
1534
|
+
const pkg = normalized.slice(0, slash_idx);
|
|
1535
|
+
const subpath = normalized.slice(slash_idx);
|
|
1536
|
+
return { pkg, subpath, is_builtin };
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
function extract_external_import_info(node) {
|
|
1540
|
+
const results = [];
|
|
1541
|
+
const module_specifier = node.moduleSpecifier.text;
|
|
1542
|
+
const { pkg, subpath, is_builtin } = parse_module_specifier(module_specifier);
|
|
1543
|
+
const clause = node.importClause;
|
|
1544
|
+
if (!clause) {
|
|
1545
|
+
results.push({
|
|
1546
|
+
package: pkg,
|
|
1547
|
+
subpath,
|
|
1548
|
+
name: null,
|
|
1549
|
+
alias: "__side_effect__",
|
|
1550
|
+
is_builtin
|
|
1551
|
+
});
|
|
1552
|
+
return results;
|
|
1553
|
+
}
|
|
1554
|
+
if (clause.name) {
|
|
1555
|
+
results.push({
|
|
1556
|
+
package: pkg,
|
|
1557
|
+
subpath,
|
|
1558
|
+
name: "default",
|
|
1559
|
+
alias: clause.name.text,
|
|
1560
|
+
is_builtin
|
|
1561
|
+
});
|
|
1562
|
+
}
|
|
1563
|
+
if (clause.namedBindings && ts5.isNamedImports(clause.namedBindings)) {
|
|
1564
|
+
for (const element of clause.namedBindings.elements) {
|
|
1565
|
+
results.push({
|
|
1566
|
+
package: pkg,
|
|
1567
|
+
subpath,
|
|
1568
|
+
name: (element.propertyName || element.name).text,
|
|
1569
|
+
alias: element.name.text,
|
|
1570
|
+
is_builtin
|
|
1571
|
+
});
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
if (clause.namedBindings && ts5.isNamespaceImport(clause.namedBindings)) {
|
|
1575
|
+
results.push({
|
|
1576
|
+
package: pkg,
|
|
1577
|
+
subpath,
|
|
1578
|
+
name: "*",
|
|
1579
|
+
alias: clause.namedBindings.name.text,
|
|
1580
|
+
is_builtin
|
|
1581
|
+
});
|
|
1582
|
+
}
|
|
1583
|
+
return results;
|
|
1584
|
+
}
|
|
1585
|
+
function extract_external_import(ctx, node, file_id) {
|
|
1586
|
+
const infos = extract_external_import_info(node);
|
|
1587
|
+
const external_imports2 = [];
|
|
1588
|
+
for (const info of infos) {
|
|
1589
|
+
const dep_meta = Object.values(ctx.dependencies).find((dep) => info.package.startsWith(dep.name));
|
|
1590
|
+
const dependency = external_dependencies_exports.get_or_create(ctx, {
|
|
1591
|
+
package: info.package,
|
|
1592
|
+
subpath: info.subpath,
|
|
1593
|
+
name: info.name,
|
|
1594
|
+
version: dep_meta?.version,
|
|
1595
|
+
github_repo: dep_meta?.github_repo,
|
|
1596
|
+
is_builtin: info.is_builtin,
|
|
1597
|
+
state: "to_describe"
|
|
1598
|
+
});
|
|
1599
|
+
if (err.any(dependency)) return dependency;
|
|
1600
|
+
external_imports2.push({ file_id, external_dependency_id: dependency.id, alias: info.alias, is_dynamic: false });
|
|
1601
|
+
}
|
|
1602
|
+
return external_imports2;
|
|
1603
|
+
}
|
|
1604
|
+
function extract_external_dynamic_import(ctx, node, file_id) {
|
|
1605
|
+
const arg = node.arguments[0];
|
|
1606
|
+
const module_specifier = arg.text;
|
|
1607
|
+
const { pkg, subpath, is_builtin } = parse_module_specifier(module_specifier);
|
|
1608
|
+
const dep_meta = Object.values(ctx.dependencies).find((dep) => pkg.startsWith(dep.name));
|
|
1609
|
+
const dependency = external_dependencies_exports.get_or_create(ctx, {
|
|
1610
|
+
package: pkg,
|
|
1611
|
+
subpath,
|
|
1612
|
+
name: "*",
|
|
1613
|
+
version: dep_meta?.version,
|
|
1614
|
+
github_repo: dep_meta?.github_repo,
|
|
1615
|
+
is_builtin,
|
|
1616
|
+
state: "to_describe"
|
|
1617
|
+
});
|
|
1618
|
+
if (err.any(dependency)) return dependency;
|
|
1619
|
+
return { file_id, external_dependency_id: dependency.id, alias: "__dynamic_import__", is_dynamic: true };
|
|
1620
|
+
}
|
|
1621
|
+
|
|
1622
|
+
// src/update/scan_files/types.ts
|
|
1623
|
+
import ts6 from "typescript";
|
|
1624
|
+
function is_type(node) {
|
|
1625
|
+
return ts6.isTypeAliasDeclaration(node) || ts6.isInterfaceDeclaration(node) || ts6.isEnumDeclaration(node);
|
|
1626
|
+
}
|
|
1627
|
+
function extract_type_symbol(node, file_id, source_file) {
|
|
1628
|
+
const meta2 = ts6.isEnumDeclaration(node) ? extract_enum_meta(node, source_file) : ts6.isInterfaceDeclaration(node) ? extract_interface_meta(node, source_file) : extract_type_alias_meta(node, source_file);
|
|
1629
|
+
return {
|
|
1630
|
+
file_id,
|
|
1631
|
+
type: "type",
|
|
1632
|
+
name: node.name.text,
|
|
1633
|
+
text: node.getText(source_file),
|
|
1634
|
+
meta: JSON.stringify(meta2),
|
|
1635
|
+
is_exported: has_export_modifier(node),
|
|
1636
|
+
state: "to_link"
|
|
1637
|
+
};
|
|
1638
|
+
}
|
|
1639
|
+
function extract_enum_meta(node, source_file) {
|
|
1640
|
+
const enum_values = {};
|
|
1641
|
+
for (const member of node.members) {
|
|
1642
|
+
if (ts6.isIdentifier(member.name) || ts6.isStringLiteral(member.name)) {
|
|
1643
|
+
const name = member.name.text;
|
|
1644
|
+
const value = member.initializer ? member.initializer.getText(source_file) : "auto";
|
|
1645
|
+
enum_values[name] = value;
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
return {
|
|
1649
|
+
kind: "enum",
|
|
1650
|
+
type_parameters: [],
|
|
1651
|
+
extends: [],
|
|
1652
|
+
members: [],
|
|
1653
|
+
enum_values,
|
|
1654
|
+
decorators: extract_decorators(node, source_file),
|
|
1655
|
+
comment: extract_jsdoc_comment(node, source_file)
|
|
1656
|
+
};
|
|
1657
|
+
}
|
|
1658
|
+
function extract_interface_meta(node, source_file) {
|
|
1659
|
+
const members = [];
|
|
1660
|
+
for (const member of node.members) {
|
|
1661
|
+
if (ts6.isPropertySignature(member) && ts6.isIdentifier(member.name)) {
|
|
1662
|
+
members.push({
|
|
1663
|
+
name: member.name.text,
|
|
1664
|
+
type: member.type ? member.type.getText(source_file) : "any",
|
|
1665
|
+
optional: !!member.questionToken
|
|
1666
|
+
});
|
|
1667
|
+
} else if (ts6.isMethodSignature(member) && ts6.isIdentifier(member.name)) {
|
|
1668
|
+
const params = member.parameters.map((p) => {
|
|
1669
|
+
const param_type = p.type ? p.type.getText(source_file) : "any";
|
|
1670
|
+
return `${p.name.getText(source_file)}: ${param_type}`;
|
|
1671
|
+
}).join(", ");
|
|
1672
|
+
const return_type = member.type ? member.type.getText(source_file) : "void";
|
|
1673
|
+
members.push({
|
|
1674
|
+
name: member.name.text,
|
|
1675
|
+
type: `(${params}) => ${return_type}`,
|
|
1676
|
+
optional: !!member.questionToken
|
|
1677
|
+
});
|
|
1678
|
+
}
|
|
1679
|
+
}
|
|
1680
|
+
const extends_clauses = node.heritageClauses?.filter((c) => c.token === ts6.SyntaxKind.ExtendsKeyword).flatMap((c) => c.types.map((t) => t.expression.getText(source_file))) || [];
|
|
1681
|
+
return {
|
|
1682
|
+
kind: "interface",
|
|
1683
|
+
type_parameters: extract_type_parameters(node, source_file),
|
|
1684
|
+
extends: extends_clauses,
|
|
1685
|
+
members,
|
|
1686
|
+
enum_values: {},
|
|
1687
|
+
decorators: extract_decorators(node, source_file),
|
|
1688
|
+
comment: extract_jsdoc_comment(node, source_file)
|
|
1689
|
+
};
|
|
1690
|
+
}
|
|
1691
|
+
function extract_type_alias_meta(node, source_file) {
|
|
1692
|
+
return {
|
|
1693
|
+
kind: "type_alias",
|
|
1694
|
+
type_parameters: extract_type_parameters(node, source_file),
|
|
1695
|
+
extends: [],
|
|
1696
|
+
members: [],
|
|
1697
|
+
enum_values: {},
|
|
1698
|
+
decorators: extract_decorators(node, source_file),
|
|
1699
|
+
comment: extract_jsdoc_comment(node, source_file)
|
|
1700
|
+
};
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1703
|
+
// src/update/scan_files/functions.ts
|
|
1704
|
+
import ts7 from "typescript";
|
|
1705
|
+
function is_function(node) {
|
|
1706
|
+
if (!ts7.isFunctionDeclaration(node)) return false;
|
|
1707
|
+
return !!node.name || has_default_modifier(node);
|
|
1708
|
+
}
|
|
1709
|
+
function extract_function_symbol(node, file_id, source_file) {
|
|
1710
|
+
const is_default = has_default_modifier(node);
|
|
1711
|
+
const name = is_default ? "default" : node.name?.text || "default";
|
|
1712
|
+
const meta2 = {
|
|
1713
|
+
kind: "function_declaration",
|
|
1714
|
+
parameters: extract_parameters(node, source_file),
|
|
1715
|
+
return_type: node.type ? node.type.getText(source_file) : null,
|
|
1716
|
+
type_parameters: extract_type_parameters(node, source_file),
|
|
1717
|
+
modifiers: {
|
|
1718
|
+
async: !!node.modifiers?.some((m) => m.kind === ts7.SyntaxKind.AsyncKeyword),
|
|
1719
|
+
generator: !!node.asteriskToken
|
|
1720
|
+
},
|
|
1721
|
+
decorators: extract_decorators(node, source_file),
|
|
1722
|
+
comment: extract_jsdoc_comment(node, source_file)
|
|
1723
|
+
};
|
|
1724
|
+
return {
|
|
1725
|
+
file_id,
|
|
1726
|
+
type: "function",
|
|
1727
|
+
name,
|
|
1728
|
+
text: node.getText(source_file),
|
|
1729
|
+
meta: JSON.stringify(meta2),
|
|
1730
|
+
is_exported: has_export_modifier(node),
|
|
1731
|
+
state: "to_link"
|
|
1732
|
+
};
|
|
1733
|
+
}
|
|
1734
|
+
|
|
1735
|
+
// src/update/scan_files/variables.ts
|
|
1736
|
+
import ts8 from "typescript";
|
|
1737
|
+
function is_function_declaration(declaration) {
|
|
1738
|
+
return !!(declaration.initializer && (ts8.isArrowFunction(declaration.initializer) || ts8.isFunctionExpression(declaration.initializer)));
|
|
1739
|
+
}
|
|
1740
|
+
function extract_variable_symbol(node, file_id, source_file) {
|
|
1741
|
+
const symbols4 = [];
|
|
1742
|
+
const is_exported = has_export_modifier(node);
|
|
1743
|
+
const declaration_kind = node.declarationList.flags & ts8.NodeFlags.Const ? "const" : node.declarationList.flags & ts8.NodeFlags.Let ? "let" : "var";
|
|
1744
|
+
for (const declaration of node.declarationList.declarations) {
|
|
1745
|
+
if (!ts8.isIdentifier(declaration.name)) continue;
|
|
1746
|
+
if (is_function_declaration(declaration)) {
|
|
1747
|
+
const func_node = declaration.initializer;
|
|
1748
|
+
const meta2 = {
|
|
1749
|
+
kind: ts8.isArrowFunction(func_node) ? "arrow_function" : "function_expression",
|
|
1750
|
+
parameters: extract_parameters(func_node, source_file),
|
|
1751
|
+
return_type: func_node.type ? func_node.type.getText(source_file) : null,
|
|
1752
|
+
type_parameters: extract_type_parameters(func_node, source_file),
|
|
1753
|
+
modifiers: {
|
|
1754
|
+
async: !!func_node.modifiers?.some((m) => m.kind === ts8.SyntaxKind.AsyncKeyword),
|
|
1755
|
+
generator: ts8.isFunctionExpression(func_node) && !!func_node.asteriskToken
|
|
1756
|
+
},
|
|
1757
|
+
decorators: extract_decorators(node, source_file),
|
|
1758
|
+
comment: extract_jsdoc_comment(node, source_file)
|
|
1759
|
+
};
|
|
1760
|
+
symbols4.push({
|
|
1761
|
+
file_id,
|
|
1762
|
+
type: "function",
|
|
1763
|
+
name: declaration.name.text,
|
|
1764
|
+
text: node.getText(source_file),
|
|
1765
|
+
meta: JSON.stringify(meta2),
|
|
1766
|
+
is_exported,
|
|
1767
|
+
state: "to_link"
|
|
1768
|
+
});
|
|
1769
|
+
} else {
|
|
1770
|
+
const meta2 = {
|
|
1771
|
+
declaration_kind,
|
|
1772
|
+
type: declaration.type ? declaration.type.getText(source_file) : null,
|
|
1773
|
+
value: declaration.initializer ? declaration.initializer.getText(source_file) : null,
|
|
1774
|
+
decorators: extract_decorators(node, source_file),
|
|
1775
|
+
comment: extract_jsdoc_comment(node, source_file)
|
|
1776
|
+
};
|
|
1777
|
+
symbols4.push({
|
|
1778
|
+
file_id,
|
|
1779
|
+
type: "variable",
|
|
1780
|
+
name: declaration.name.text,
|
|
1781
|
+
text: node.getText(source_file),
|
|
1782
|
+
meta: JSON.stringify(meta2),
|
|
1783
|
+
is_exported,
|
|
1784
|
+
state: "to_link"
|
|
1785
|
+
});
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
return symbols4;
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1791
|
+
// src/update/scan_files/classes.ts
|
|
1792
|
+
import ts9 from "typescript";
|
|
1793
|
+
function is_class(node) {
|
|
1794
|
+
if (!ts9.isClassDeclaration(node)) return false;
|
|
1795
|
+
return !!node.name || has_default_modifier(node);
|
|
1796
|
+
}
|
|
1797
|
+
function extract_class_symbol(node, file_id, source_file) {
|
|
1798
|
+
const is_default = has_default_modifier(node);
|
|
1799
|
+
const name = is_default ? "default" : node.name?.text || "default";
|
|
1800
|
+
const meta2 = {
|
|
1801
|
+
extends: node.heritageClauses?.find((c) => c.token === ts9.SyntaxKind.ExtendsKeyword)?.types[0]?.expression.getText(source_file) || null,
|
|
1802
|
+
implements: node.heritageClauses?.find((c) => c.token === ts9.SyntaxKind.ImplementsKeyword)?.types.map((t) => t.expression.getText(source_file)) || [],
|
|
1803
|
+
type_parameters: extract_type_parameters(node, source_file),
|
|
1804
|
+
modifiers: {
|
|
1805
|
+
abstract: !!node.modifiers?.some((m) => m.kind === ts9.SyntaxKind.AbstractKeyword)
|
|
1806
|
+
},
|
|
1807
|
+
decorators: extract_decorators(node, source_file),
|
|
1808
|
+
comment: extract_jsdoc_comment(node, source_file)
|
|
1809
|
+
};
|
|
1810
|
+
return {
|
|
1811
|
+
file_id,
|
|
1812
|
+
type: "class",
|
|
1813
|
+
name,
|
|
1814
|
+
text: node.getText(source_file),
|
|
1815
|
+
meta: JSON.stringify(meta2),
|
|
1816
|
+
is_exported: has_export_modifier(node),
|
|
1817
|
+
state: "to_link"
|
|
1818
|
+
};
|
|
1819
|
+
}
|
|
1820
|
+
function get_visibility(member) {
|
|
1821
|
+
if (!ts9.canHaveModifiers(member)) return null;
|
|
1822
|
+
const modifiers = ts9.getModifiers(member);
|
|
1823
|
+
if (!modifiers) return null;
|
|
1824
|
+
if (modifiers.some((m) => m.kind === ts9.SyntaxKind.PrivateKeyword)) return "private";
|
|
1825
|
+
if (modifiers.some((m) => m.kind === ts9.SyntaxKind.ProtectedKeyword)) return "protected";
|
|
1826
|
+
if (modifiers.some((m) => m.kind === ts9.SyntaxKind.PublicKeyword)) return "public";
|
|
1827
|
+
return null;
|
|
1828
|
+
}
|
|
1829
|
+
function extract_class_fields(node, file_id, source_file) {
|
|
1830
|
+
const symbols4 = [];
|
|
1831
|
+
if (!node.name) return symbols4;
|
|
1832
|
+
const class_name = node.name.text;
|
|
1833
|
+
node.members.forEach((member) => {
|
|
1834
|
+
if (ts9.isMethodDeclaration(member) && member.name && ts9.isIdentifier(member.name)) {
|
|
1835
|
+
const meta2 = {
|
|
1836
|
+
class_name,
|
|
1837
|
+
visibility: get_visibility(member),
|
|
1838
|
+
parameters: extract_parameters(member, source_file),
|
|
1839
|
+
return_type: member.type ? member.type.getText(source_file) : null,
|
|
1840
|
+
type_parameters: extract_type_parameters(member, source_file),
|
|
1841
|
+
modifiers: {
|
|
1842
|
+
static: !!member.modifiers?.some((m) => m.kind === ts9.SyntaxKind.StaticKeyword),
|
|
1843
|
+
async: !!member.modifiers?.some((m) => m.kind === ts9.SyntaxKind.AsyncKeyword),
|
|
1844
|
+
abstract: !!member.modifiers?.some((m) => m.kind === ts9.SyntaxKind.AbstractKeyword),
|
|
1845
|
+
readonly: !!member.modifiers?.some((m) => m.kind === ts9.SyntaxKind.ReadonlyKeyword)
|
|
1846
|
+
},
|
|
1847
|
+
decorators: extract_decorators(member, source_file),
|
|
1848
|
+
comment: extract_jsdoc_comment(member, source_file)
|
|
1849
|
+
};
|
|
1850
|
+
symbols4.push({
|
|
1851
|
+
file_id,
|
|
1852
|
+
type: "class_method",
|
|
1853
|
+
name: `${class_name}.${member.name.text}`,
|
|
1854
|
+
text: member.getText(source_file),
|
|
1855
|
+
meta: JSON.stringify(meta2),
|
|
1856
|
+
is_exported: false,
|
|
1857
|
+
state: "to_link"
|
|
1858
|
+
});
|
|
1859
|
+
}
|
|
1860
|
+
if (ts9.isPropertyDeclaration(member) && member.name && ts9.isIdentifier(member.name)) {
|
|
1861
|
+
const meta2 = {
|
|
1862
|
+
class_name,
|
|
1863
|
+
visibility: get_visibility(member),
|
|
1864
|
+
type: member.type ? member.type.getText(source_file) : null,
|
|
1865
|
+
optional: !!member.questionToken,
|
|
1866
|
+
modifiers: {
|
|
1867
|
+
static: !!member.modifiers?.some((m) => m.kind === ts9.SyntaxKind.StaticKeyword),
|
|
1868
|
+
readonly: !!member.modifiers?.some((m) => m.kind === ts9.SyntaxKind.ReadonlyKeyword),
|
|
1869
|
+
abstract: !!member.modifiers?.some((m) => m.kind === ts9.SyntaxKind.AbstractKeyword)
|
|
1870
|
+
},
|
|
1871
|
+
decorators: extract_decorators(member, source_file),
|
|
1872
|
+
comment: extract_jsdoc_comment(member, source_file)
|
|
1873
|
+
};
|
|
1874
|
+
symbols4.push({
|
|
1875
|
+
file_id,
|
|
1876
|
+
type: "class_property",
|
|
1877
|
+
name: `${class_name}.${member.name.text}`,
|
|
1878
|
+
text: member.getText(source_file),
|
|
1879
|
+
meta: JSON.stringify(meta2),
|
|
1880
|
+
is_exported: false,
|
|
1881
|
+
state: "to_link"
|
|
1882
|
+
});
|
|
1883
|
+
}
|
|
1884
|
+
});
|
|
1885
|
+
return symbols4;
|
|
1886
|
+
}
|
|
1887
|
+
|
|
1888
|
+
// src/update/scan_files/scan_files.ts
|
|
1889
|
+
async function scan_files(ctx) {
|
|
1890
|
+
const files5 = err.or_throw(files_exports.by_state(ctx, "to_scan"));
|
|
1891
|
+
for (const file of files5) {
|
|
1892
|
+
const res = scan_file(ctx, file);
|
|
1893
|
+
if (err.any(res)) {
|
|
1894
|
+
err.or_throw(files_exports.update(ctx, file.id, { error: String(res) }));
|
|
1895
|
+
} else {
|
|
1896
|
+
err.or_throw(files_exports.update(ctx, file.id, { state: "to_describe", error: null }));
|
|
1897
|
+
}
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
function scan_file(ctx, file) {
|
|
1901
|
+
return err.pipe(
|
|
1902
|
+
() => symbols_exports.del_by_file(ctx, file.id),
|
|
1903
|
+
() => imports_exports.del_by_importer_file(ctx, file.id),
|
|
1904
|
+
() => external_imports_exports.del_by_file(ctx, file.id),
|
|
1905
|
+
() => get_source_file(ctx, file.path),
|
|
1906
|
+
(source_file) => parse_file(ctx, source_file, file.id),
|
|
1907
|
+
({ imports: imports2, symbols: symbols4, external_imports: external_imports2 }) => err.pipe(
|
|
1908
|
+
() => external_imports2.length && external_imports_exports.insert_many(ctx, external_imports2),
|
|
1909
|
+
() => imports2.length && imports_exports.insert_many(ctx, imports2),
|
|
1910
|
+
() => symbols4.length && symbols_exports.insert_many(ctx, symbols4)
|
|
1911
|
+
)
|
|
1912
|
+
);
|
|
1913
|
+
}
|
|
1914
|
+
function get_source_file(ctx, file_path) {
|
|
1915
|
+
const source_file = ctx.program.getSourceFile(path4.join(ctx.project_path, file_path));
|
|
1916
|
+
if (!source_file) return err.new("file_not_found", { path: file_path });
|
|
1917
|
+
return source_file;
|
|
1918
|
+
}
|
|
1919
|
+
function parse_file(ctx, source_file, file_id) {
|
|
1920
|
+
const imports2 = [];
|
|
1921
|
+
const symbols4 = [];
|
|
1922
|
+
const external_imports2 = [];
|
|
1923
|
+
function find_dynamic_imports(node) {
|
|
1924
|
+
if (is_dynamic_import(node)) {
|
|
1925
|
+
const arg = node.arguments[0];
|
|
1926
|
+
if (is_external_module(ctx, source_file, arg.text)) {
|
|
1927
|
+
const result = extract_external_dynamic_import(ctx, node, file_id);
|
|
1928
|
+
if (err.any(result)) return result;
|
|
1929
|
+
external_imports2.push(result);
|
|
1930
|
+
} else {
|
|
1931
|
+
const result = extract_dynamic_import(ctx, source_file, node, file_id);
|
|
1932
|
+
if (result) imports2.push(result);
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
ts10.forEachChild(node, find_dynamic_imports);
|
|
1936
|
+
}
|
|
1937
|
+
let error = void 0;
|
|
1938
|
+
ts10.forEachChild(source_file, (statement) => {
|
|
1939
|
+
if (error) return;
|
|
1940
|
+
const res = parse_node(ctx, source_file, statement, file_id);
|
|
1941
|
+
if (err.any(res)) {
|
|
1942
|
+
error = res;
|
|
1943
|
+
return;
|
|
1944
|
+
}
|
|
1945
|
+
imports2.push(...res.imports);
|
|
1946
|
+
symbols4.push(...res.symbols);
|
|
1947
|
+
external_imports2.push(...res.external_imports);
|
|
1948
|
+
error = find_dynamic_imports(statement);
|
|
1949
|
+
});
|
|
1950
|
+
if (error) return error;
|
|
1951
|
+
return { imports: imports2, symbols: symbols4, external_imports: external_imports2 };
|
|
1952
|
+
}
|
|
1953
|
+
function parse_node(ctx, source_file, node, file_id) {
|
|
1954
|
+
const imports2 = [];
|
|
1955
|
+
const symbols4 = [];
|
|
1956
|
+
const external_imports2 = [];
|
|
1957
|
+
if (is_external_import(ctx, source_file, node)) {
|
|
1958
|
+
const result = extract_external_import(ctx, node, file_id);
|
|
1959
|
+
if (err.any(result)) return result;
|
|
1960
|
+
external_imports2.push(...result);
|
|
1961
|
+
} else if (is_import(ctx, source_file, node)) {
|
|
1962
|
+
imports2.push(...extract_import(ctx, source_file, node, file_id));
|
|
1963
|
+
} else if (ts10.isExportAssignment(node) && !node.isExportEquals) {
|
|
1964
|
+
symbols4.push({
|
|
1965
|
+
file_id,
|
|
1966
|
+
type: "variable",
|
|
1967
|
+
name: "default",
|
|
1968
|
+
text: node.getText(source_file),
|
|
1969
|
+
meta: JSON.stringify({
|
|
1970
|
+
declaration_kind: "const",
|
|
1971
|
+
type: null,
|
|
1972
|
+
value: node.expression.getText(source_file),
|
|
1973
|
+
decorators: [],
|
|
1974
|
+
comment: null
|
|
1975
|
+
}),
|
|
1976
|
+
is_exported: true,
|
|
1977
|
+
state: "to_link"
|
|
1978
|
+
});
|
|
1979
|
+
} else if (ts10.isExportDeclaration(node) && node.exportClause && ts10.isNamedExports(node.exportClause) && !node.moduleSpecifier) {
|
|
1980
|
+
for (const element of node.exportClause.elements) {
|
|
1981
|
+
if (element.name.text === "default") {
|
|
1982
|
+
const localName = element.propertyName?.text || element.name.text;
|
|
1983
|
+
symbols4.push({
|
|
1984
|
+
file_id,
|
|
1985
|
+
type: "variable",
|
|
1986
|
+
name: "default",
|
|
1987
|
+
text: node.getText(source_file),
|
|
1988
|
+
meta: JSON.stringify({ declaration_kind: "const", type: null, value: localName, is_reexport: true, decorators: [], comment: null }),
|
|
1989
|
+
is_exported: true,
|
|
1990
|
+
state: "to_link"
|
|
1991
|
+
});
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
} else if (is_type(node)) {
|
|
1995
|
+
symbols4.push(extract_type_symbol(node, file_id, source_file));
|
|
1996
|
+
} else if (is_function(node)) {
|
|
1997
|
+
symbols4.push(extract_function_symbol(node, file_id, source_file));
|
|
1998
|
+
} else if (ts10.isVariableStatement(node)) {
|
|
1999
|
+
symbols4.push(...extract_variable_symbol(node, file_id, source_file));
|
|
2000
|
+
} else if (is_class(node)) {
|
|
2001
|
+
symbols4.push(extract_class_symbol(node, file_id, source_file));
|
|
2002
|
+
symbols4.push(...extract_class_fields(node, file_id, source_file));
|
|
2003
|
+
}
|
|
2004
|
+
return { imports: imports2, symbols: symbols4, external_imports: external_imports2 };
|
|
2005
|
+
}
|
|
2006
|
+
|
|
2007
|
+
// src/update/link_imports.ts
|
|
2008
|
+
async function link_imports(ctx) {
|
|
2009
|
+
const imports2 = err.or_throw(imports_exports.by_state(ctx, "to_link"));
|
|
2010
|
+
let i = 0;
|
|
2011
|
+
for (const import_ of imports2) {
|
|
2012
|
+
const res = link_import(ctx, import_);
|
|
2013
|
+
if (err.any(res)) err.or_throw(imports_exports.update(ctx, import_.id, { error: String(res) }));
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
function link_import(ctx, import_) {
|
|
2017
|
+
if (import_.name === "*") {
|
|
2018
|
+
return imports_exports.update(ctx, import_.id, { state: "ready", error: null });
|
|
2019
|
+
}
|
|
2020
|
+
const symbol = symbols_exports.by_file_and_name(ctx, { file_id: import_.exporter_file_id, name: import_.name, is_exported: true });
|
|
2021
|
+
if (err.any(symbol)) return symbol;
|
|
2022
|
+
if (!symbol) return err.new("exported_symbol_not_found", { name: import_.name, file_id: import_.exporter_file_id });
|
|
2023
|
+
return imports_exports.update(ctx, import_.id, { symbol_id: symbol.id, state: "ready", error: null });
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
// src/update/link_symbols.ts
|
|
2027
|
+
import path5 from "path";
|
|
2028
|
+
import ts11 from "typescript";
|
|
2029
|
+
async function link_symbols(ctx) {
|
|
2030
|
+
const symbols4 = err.or_throw(symbols_exports.by_state(ctx, "to_link"));
|
|
2031
|
+
let i = 0;
|
|
2032
|
+
for (const symbol of symbols4) {
|
|
2033
|
+
const res = link_symbol(ctx, symbol);
|
|
2034
|
+
if (err.any(res)) {
|
|
2035
|
+
err.or_throw(symbols_exports.update(ctx, symbol.id, { error: String(res) }));
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
}
|
|
2039
|
+
function link_symbol(ctx, symbol) {
|
|
2040
|
+
if (!symbol.text) return err.new("symbol_missing_text", { symbol_id: symbol.id, name: symbol.name });
|
|
2041
|
+
const resolutions = find_symbol_references(ctx, symbol);
|
|
2042
|
+
if (err.any(resolutions)) return resolutions;
|
|
2043
|
+
for (const resolution of resolutions) {
|
|
2044
|
+
if (resolution.type === "internal") create_internal_link(ctx, symbol, resolution);
|
|
2045
|
+
if (resolution.type === "external") create_external_link(ctx, symbol, resolution);
|
|
2046
|
+
}
|
|
2047
|
+
return symbols_exports.update(ctx, symbol.id, { state: "to_describe", error: null });
|
|
2048
|
+
}
|
|
2049
|
+
function find_symbol_references(ctx, symbol) {
|
|
2050
|
+
const file = files_exports.by_id(ctx, symbol.file_id);
|
|
2051
|
+
if (err.any(file)) return file;
|
|
2052
|
+
if (!file) return err.new("file_not_found", { path: `file_id=${symbol.file_id}` });
|
|
2053
|
+
const file_path = path5.join(ctx.project_path, file.path);
|
|
2054
|
+
const source_file = ctx.program.getSourceFile(file_path);
|
|
2055
|
+
if (!source_file) return err.new("file_not_found", { path: file_path });
|
|
2056
|
+
const symbol_node = find_symbol_node(source_file, symbol);
|
|
2057
|
+
if (!symbol_node) return err.new("symbol_node_not_found", { symbol_id: symbol.id, name: symbol.name, file_path: file.path });
|
|
2058
|
+
const type_checker = ctx.program.getTypeChecker();
|
|
2059
|
+
const resolutions = [];
|
|
2060
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2061
|
+
function visit(node) {
|
|
2062
|
+
const ts_symbol = type_checker.getSymbolAtLocation(node);
|
|
2063
|
+
if (!ts11.isIdentifier(node) || is_declaration(node.parent, node) || !ts_symbol) {
|
|
2064
|
+
ts11.forEachChild(node, visit);
|
|
2065
|
+
return;
|
|
2066
|
+
}
|
|
2067
|
+
const resolution = resolve_ts_symbol(ctx, type_checker, ts_symbol, symbol);
|
|
2068
|
+
if (resolution) {
|
|
2069
|
+
const key = `${resolution.type}:${resolution.type === "internal" ? resolution.symbol_id : resolution.external_import_id}`;
|
|
2070
|
+
if (!seen.has(key)) {
|
|
2071
|
+
seen.add(key);
|
|
2072
|
+
resolutions.push(resolution);
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
ts11.forEachChild(node, visit);
|
|
2076
|
+
}
|
|
2077
|
+
visit(symbol_node);
|
|
2078
|
+
return resolutions;
|
|
2079
|
+
}
|
|
2080
|
+
function resolve_ts_symbol(ctx, type_checker, ts_symbol, from_symbol) {
|
|
2081
|
+
let symbol_to_use = ts_symbol;
|
|
2082
|
+
if (ts_symbol.flags & ts11.SymbolFlags.Alias) {
|
|
2083
|
+
symbol_to_use = type_checker.getAliasedSymbol(ts_symbol) || symbol_to_use;
|
|
2084
|
+
}
|
|
2085
|
+
const declarations = symbol_to_use.getDeclarations();
|
|
2086
|
+
if (!declarations || declarations.length === 0 || !declarations[0]) return null;
|
|
2087
|
+
const declaration_source_file = declarations[0].getSourceFile();
|
|
2088
|
+
if (declaration_source_file.fileName.includes("/lib.") && !declaration_source_file.fileName.includes("node_modules")) {
|
|
2089
|
+
return null;
|
|
2090
|
+
}
|
|
2091
|
+
if (!declaration_source_file.fileName.startsWith(ctx.project_path) || declaration_source_file.fileName.includes("node_modules")) {
|
|
2092
|
+
const external_import_links = external_imports_exports.by_file(ctx, from_symbol.file_id);
|
|
2093
|
+
if (err.any(external_import_links)) return null;
|
|
2094
|
+
for (const ext_import of external_import_links) {
|
|
2095
|
+
const ext_dep = external_dependencies_exports.by_id(ctx, ext_import.external_dependency_id);
|
|
2096
|
+
if (err.any(ext_dep) || !ext_dep) continue;
|
|
2097
|
+
if (ext_import.alias === symbol_to_use.name || ext_dep.name === symbol_to_use.name) {
|
|
2098
|
+
return { type: "external", external_import_id: ext_import.id };
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
return null;
|
|
2102
|
+
}
|
|
2103
|
+
let file_path = declaration_source_file.fileName;
|
|
2104
|
+
if (file_path.startsWith(ctx.project_path)) {
|
|
2105
|
+
file_path = file_path.substring(ctx.project_path.length);
|
|
2106
|
+
}
|
|
2107
|
+
const file = files_exports.by_path(ctx, file_path);
|
|
2108
|
+
if (err.any(file) || !file) return null;
|
|
2109
|
+
if (file.id === from_symbol.file_id) {
|
|
2110
|
+
const file_symbols2 = symbols_exports.by_file(ctx, file.id);
|
|
2111
|
+
if (err.any(file_symbols2)) return null;
|
|
2112
|
+
for (const file_symbol of file_symbols2) {
|
|
2113
|
+
if (file_symbol.name === symbol_to_use.name && file_symbol.id !== from_symbol.id) {
|
|
2114
|
+
return { type: "internal", symbol_id: file_symbol.id, file_id: file.id };
|
|
2115
|
+
}
|
|
2116
|
+
}
|
|
2117
|
+
return null;
|
|
2118
|
+
}
|
|
2119
|
+
const file_symbols = symbols_exports.by_file(ctx, file.id);
|
|
2120
|
+
if (err.any(file_symbols)) return null;
|
|
2121
|
+
for (const file_symbol of file_symbols) {
|
|
2122
|
+
if (file_symbol.name === symbol_to_use.name) {
|
|
2123
|
+
return { type: "internal", symbol_id: file_symbol.id, file_id: file.id };
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
2126
|
+
return null;
|
|
2127
|
+
}
|
|
2128
|
+
function find_symbol_node(source_file, symbol) {
|
|
2129
|
+
let result;
|
|
2130
|
+
function visit(node) {
|
|
2131
|
+
if (result) return;
|
|
2132
|
+
if (matches_symbol(node, symbol)) {
|
|
2133
|
+
result = node;
|
|
2134
|
+
return;
|
|
2135
|
+
}
|
|
2136
|
+
ts11.forEachChild(node, visit);
|
|
2137
|
+
}
|
|
2138
|
+
visit(source_file);
|
|
2139
|
+
return result;
|
|
2140
|
+
}
|
|
2141
|
+
function matches_symbol(node, symbol) {
|
|
2142
|
+
if (symbol.name === "default") {
|
|
2143
|
+
if (symbol.type === "function" && ts11.isFunctionDeclaration(node)) return has_default_modifier(node);
|
|
2144
|
+
if (symbol.type === "class" && ts11.isClassDeclaration(node)) return has_default_modifier(node);
|
|
2145
|
+
if (symbol.type === "variable") {
|
|
2146
|
+
if (ts11.isExportAssignment(node) && !node.isExportEquals) return true;
|
|
2147
|
+
if (ts11.isExportDeclaration(node) && node.exportClause && ts11.isNamedExports(node.exportClause)) {
|
|
2148
|
+
return node.exportClause.elements.some((element) => element.name.text === "default");
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
if (symbol.type === "function") {
|
|
2153
|
+
if (ts11.isVariableStatement(node)) {
|
|
2154
|
+
const declarations = node.declarationList.declarations;
|
|
2155
|
+
for (const decl of declarations) {
|
|
2156
|
+
if (ts11.isIdentifier(decl.name) && decl.name.text === symbol.name) {
|
|
2157
|
+
const initializer = decl.initializer;
|
|
2158
|
+
if (initializer && (ts11.isArrowFunction(initializer) || ts11.isFunctionExpression(initializer))) {
|
|
2159
|
+
return true;
|
|
2160
|
+
}
|
|
2161
|
+
}
|
|
2162
|
+
}
|
|
2163
|
+
return false;
|
|
2164
|
+
}
|
|
2165
|
+
if (ts11.isFunctionDeclaration(node)) {
|
|
2166
|
+
return get_node_name(node) === symbol.name;
|
|
2167
|
+
}
|
|
2168
|
+
return false;
|
|
2169
|
+
}
|
|
2170
|
+
if (symbol.type === "class") {
|
|
2171
|
+
if (!ts11.isClassDeclaration(node)) return false;
|
|
2172
|
+
return get_node_name(node) === symbol.name;
|
|
2173
|
+
}
|
|
2174
|
+
if (symbol.type === "type") {
|
|
2175
|
+
if (!ts11.isTypeAliasDeclaration(node) && !ts11.isInterfaceDeclaration(node) && !ts11.isEnumDeclaration(node)) return false;
|
|
2176
|
+
return get_node_name(node) === symbol.name;
|
|
2177
|
+
}
|
|
2178
|
+
if (symbol.type === "variable") {
|
|
2179
|
+
if (ts11.isVariableStatement(node)) {
|
|
2180
|
+
const declarations = node.declarationList.declarations;
|
|
2181
|
+
for (const decl of declarations) {
|
|
2182
|
+
if (ts11.isIdentifier(decl.name) && decl.name.text === symbol.name) {
|
|
2183
|
+
const initializer = decl.initializer;
|
|
2184
|
+
if (!initializer || !ts11.isArrowFunction(initializer) && !ts11.isFunctionExpression(initializer)) {
|
|
2185
|
+
return true;
|
|
2186
|
+
}
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
return false;
|
|
2191
|
+
}
|
|
2192
|
+
if (symbol.type === "class_method") {
|
|
2193
|
+
if (!ts11.isMethodDeclaration(node)) return false;
|
|
2194
|
+
const method_name = get_node_name(node);
|
|
2195
|
+
if (!method_name) return false;
|
|
2196
|
+
const class_node = node.parent;
|
|
2197
|
+
if (!class_node || !ts11.isClassDeclaration(class_node)) return false;
|
|
2198
|
+
const class_name = get_node_name(class_node);
|
|
2199
|
+
if (!class_name) return false;
|
|
2200
|
+
return `${class_name}.${method_name}` === symbol.name;
|
|
2201
|
+
}
|
|
2202
|
+
if (symbol.type === "class_property") {
|
|
2203
|
+
if (!ts11.isPropertyDeclaration(node)) return false;
|
|
2204
|
+
const prop_name = get_node_name(node);
|
|
2205
|
+
if (!prop_name) return false;
|
|
2206
|
+
const class_node = node.parent;
|
|
2207
|
+
if (!class_node || !ts11.isClassDeclaration(class_node)) return false;
|
|
2208
|
+
const class_name = get_node_name(class_node);
|
|
2209
|
+
if (!class_name) return false;
|
|
2210
|
+
return `${class_name}.${prop_name}` === symbol.name;
|
|
2211
|
+
}
|
|
2212
|
+
return false;
|
|
2213
|
+
}
|
|
2214
|
+
function get_node_name(node) {
|
|
2215
|
+
if (!("name" in node)) return void 0;
|
|
2216
|
+
const nodeWithName = node;
|
|
2217
|
+
if (nodeWithName.name && ts11.isIdentifier(nodeWithName.name)) {
|
|
2218
|
+
return nodeWithName.name.text;
|
|
2219
|
+
}
|
|
2220
|
+
return void 0;
|
|
2221
|
+
}
|
|
2222
|
+
function is_declaration(parent, identifier) {
|
|
2223
|
+
if (!parent) return false;
|
|
2224
|
+
if (ts11.isFunctionDeclaration(parent) && parent.name === identifier) return true;
|
|
2225
|
+
if (ts11.isClassDeclaration(parent) && parent.name === identifier) return true;
|
|
2226
|
+
if (ts11.isInterfaceDeclaration(parent) && parent.name === identifier) return true;
|
|
2227
|
+
if (ts11.isTypeAliasDeclaration(parent) && parent.name === identifier) return true;
|
|
2228
|
+
if (ts11.isEnumDeclaration(parent) && parent.name === identifier) return true;
|
|
2229
|
+
if (ts11.isVariableDeclaration(parent) && parent.name === identifier) return true;
|
|
2230
|
+
if (ts11.isParameter(parent) && parent.name === identifier) return true;
|
|
2231
|
+
if (ts11.isPropertyDeclaration(parent) && parent.name === identifier) return true;
|
|
2232
|
+
if (ts11.isMethodDeclaration(parent) && parent.name === identifier) return true;
|
|
2233
|
+
if (ts11.isTypeParameterDeclaration(parent) && parent.name === identifier) return true;
|
|
2234
|
+
if (ts11.isImportClause(parent) && parent.name === identifier) return true;
|
|
2235
|
+
if (ts11.isImportSpecifier(parent) && (parent.name === identifier || parent.propertyName === identifier)) return true;
|
|
2236
|
+
if (ts11.isNamespaceImport(parent) && parent.name === identifier) return true;
|
|
2237
|
+
return false;
|
|
2238
|
+
}
|
|
2239
|
+
function create_internal_link(ctx, from_symbol, resolution) {
|
|
2240
|
+
const existing = symbol_internal_links_exports.exists(ctx, {
|
|
2241
|
+
from_symbol_id: from_symbol.id,
|
|
2242
|
+
to_symbol_id: resolution.symbol_id
|
|
2243
|
+
});
|
|
2244
|
+
if (err.any(existing)) return existing;
|
|
2245
|
+
if (existing) return;
|
|
2246
|
+
return symbol_internal_links_exports.insert(ctx, {
|
|
2247
|
+
from_file_id: from_symbol.file_id,
|
|
2248
|
+
to_file_id: resolution.file_id,
|
|
2249
|
+
from_symbol_id: from_symbol.id,
|
|
2250
|
+
to_symbol_id: resolution.symbol_id,
|
|
2251
|
+
state: "pending"
|
|
2252
|
+
});
|
|
2253
|
+
}
|
|
2254
|
+
function create_external_link(ctx, from_symbol, resolution) {
|
|
2255
|
+
const existing = symbol_external_links_exports.exists(ctx, {
|
|
2256
|
+
symbol_id: from_symbol.id,
|
|
2257
|
+
external_import_id: resolution.external_import_id
|
|
2258
|
+
});
|
|
2259
|
+
if (err.any(existing)) return existing;
|
|
2260
|
+
if (existing) return;
|
|
2261
|
+
return symbol_external_links_exports.insert(ctx, {
|
|
2262
|
+
symbol_id: from_symbol.id,
|
|
2263
|
+
external_import_id: resolution.external_import_id
|
|
2264
|
+
});
|
|
2265
|
+
}
|
|
2266
|
+
|
|
2267
|
+
// src/update/index.ts
|
|
2268
|
+
async function update6(ctx) {
|
|
2269
|
+
await track_changes(ctx);
|
|
2270
|
+
await sync_external_dependencies(ctx);
|
|
2271
|
+
await scan_files(ctx);
|
|
2272
|
+
await link_imports(ctx);
|
|
2273
|
+
await link_symbols(ctx);
|
|
2274
|
+
}
|
|
2275
|
+
|
|
2276
|
+
// src/counts.ts
|
|
2277
|
+
import { count } from "drizzle-orm";
|
|
2278
|
+
var counts = safe_query("counts", (ctx) => {
|
|
2279
|
+
const symbol_counts = ctx.db.select({ state: symbols.state, count: count() }).from(symbols).groupBy(symbols.state).all();
|
|
2280
|
+
const file_counts = ctx.db.select({ state: files.state, count: count() }).from(files).groupBy(files.state).all();
|
|
2281
|
+
const dir_counts = ctx.db.select({ state: directories.state, count: count() }).from(directories).groupBy(directories.state).all();
|
|
2282
|
+
const dep_counts = ctx.db.select({ state: external_dependencies.state, count: count() }).from(external_dependencies).groupBy(external_dependencies.state).all();
|
|
2283
|
+
return {
|
|
2284
|
+
symbols: get_groups(symbol_counts, ["to_link", "to_describe", "ready"]),
|
|
2285
|
+
files: get_groups(file_counts, ["to_scan", "to_describe", "ready"]),
|
|
2286
|
+
directories: get_groups(dir_counts, ["to_describe", "ready"]),
|
|
2287
|
+
dependencies: get_groups(dep_counts, ["to_describe", "ready"])
|
|
2288
|
+
};
|
|
2289
|
+
});
|
|
2290
|
+
function get_groups(items, states) {
|
|
2291
|
+
const groups = { total: 0 };
|
|
2292
|
+
for (const state of states) groups[state] = 0;
|
|
2293
|
+
for (const item of items) {
|
|
2294
|
+
if (!states.includes(item.state)) continue;
|
|
2295
|
+
groups[item.state] = (groups[item.state] || 0) + item.count;
|
|
2296
|
+
groups.total += item.count;
|
|
2297
|
+
}
|
|
2298
|
+
return groups;
|
|
2299
|
+
}
|
|
2300
|
+
|
|
2301
|
+
// src/files.ts
|
|
2302
|
+
function files_wiki(ctx) {
|
|
2303
|
+
return {
|
|
2304
|
+
get: (id) => get2(ctx, id),
|
|
2305
|
+
search: (options) => search5(ctx, options),
|
|
2306
|
+
set_description: (id, description) => set_description(ctx, id, description),
|
|
2307
|
+
imported_by_file: (file_id, options) => imported_by_file(ctx, file_id, options),
|
|
2308
|
+
importing_file: (file_id, options) => importing_file(ctx, file_id, options),
|
|
2309
|
+
importing_dependency: (dependency_id, options) => importing_dependency(ctx, dependency_id, options)
|
|
2310
|
+
};
|
|
2311
|
+
}
|
|
2312
|
+
function get2(ctx, id) {
|
|
2313
|
+
return err.or_throw(files_exports.by_id(ctx, id)) ?? null;
|
|
2314
|
+
}
|
|
2315
|
+
function search5(ctx, options) {
|
|
2316
|
+
return err.or_throw(files_exports.search(ctx, options));
|
|
2317
|
+
}
|
|
2318
|
+
function set_description(ctx, id, description) {
|
|
2319
|
+
err.or_throw(files_exports.update(ctx, id, { description }));
|
|
2320
|
+
}
|
|
2321
|
+
function imported_by_file(ctx, file_id, options = {}) {
|
|
2322
|
+
let imported_files = err.or_throw(files_exports.imported_by(ctx, file_id, options.select));
|
|
2323
|
+
if (options.deep) {
|
|
2324
|
+
imported_files = err.or_throw(
|
|
2325
|
+
expand({
|
|
2326
|
+
items: imported_files,
|
|
2327
|
+
get_children: (file) => files_exports.imported_by(ctx, file.id, options.select),
|
|
2328
|
+
get_key: (file) => file.id
|
|
2329
|
+
})
|
|
2330
|
+
);
|
|
2331
|
+
}
|
|
2332
|
+
const start = options.offset ?? 0;
|
|
2333
|
+
const end = options.limit ? start + options.limit : imported_files.length;
|
|
2334
|
+
return imported_files.slice(start, end);
|
|
2335
|
+
}
|
|
2336
|
+
function importing_file(ctx, file_id, options = {}) {
|
|
2337
|
+
let importing_files = err.or_throw(files_exports.importing(ctx, file_id, options.select));
|
|
2338
|
+
if (options.deep) {
|
|
2339
|
+
importing_files = err.or_throw(
|
|
2340
|
+
expand({
|
|
2341
|
+
items: importing_files,
|
|
2342
|
+
get_children: (file) => files_exports.importing(ctx, file.id, options.select),
|
|
2343
|
+
get_key: (file) => file.id
|
|
2344
|
+
})
|
|
2345
|
+
);
|
|
2346
|
+
}
|
|
2347
|
+
const start = options.offset ?? 0;
|
|
2348
|
+
const end = options.limit ? start + options.limit : importing_files.length;
|
|
2349
|
+
return importing_files.slice(start, end);
|
|
2350
|
+
}
|
|
2351
|
+
function importing_dependency(ctx, dependency_id, options = {}) {
|
|
2352
|
+
let files_using_dependency = err.or_throw(files_exports.using_dependency(ctx, dependency_id, options.select));
|
|
2353
|
+
if (options.deep) {
|
|
2354
|
+
files_using_dependency = err.or_throw(
|
|
2355
|
+
expand({
|
|
2356
|
+
items: files_using_dependency,
|
|
2357
|
+
get_children: (file) => files_exports.importing(ctx, file.id, options.select),
|
|
2358
|
+
get_key: (file) => file.id
|
|
2359
|
+
})
|
|
2360
|
+
);
|
|
2361
|
+
}
|
|
2362
|
+
const start = options.offset ?? 0;
|
|
2363
|
+
const end = options.limit ? start + options.limit : files_using_dependency.length;
|
|
2364
|
+
return files_using_dependency.slice(start, end);
|
|
2365
|
+
}
|
|
2366
|
+
|
|
2367
|
+
// src/symbols.ts
|
|
2368
|
+
function symbols_wiki(ctx) {
|
|
2369
|
+
return {
|
|
2370
|
+
get: (id) => get3(ctx, id),
|
|
2371
|
+
search: (options) => search6(ctx, options),
|
|
2372
|
+
set_description: (id, description) => set_description2(ctx, id, description),
|
|
2373
|
+
referencing_symbol: (symbol_id, options) => referencing_symbol(ctx, symbol_id, options),
|
|
2374
|
+
referenced_by_symbol: (symbol_id, options) => referenced_by_symbol(ctx, symbol_id, options),
|
|
2375
|
+
using_dependency: (dependency_id, options) => using_dependency3(ctx, dependency_id, options)
|
|
2376
|
+
};
|
|
2377
|
+
}
|
|
2378
|
+
function get3(ctx, id) {
|
|
2379
|
+
return err.or_throw(symbols_exports.by_id(ctx, id)) ?? null;
|
|
2380
|
+
}
|
|
2381
|
+
function search6(ctx, options) {
|
|
2382
|
+
return err.or_throw(symbols_exports.search(ctx, options));
|
|
2383
|
+
}
|
|
2384
|
+
function set_description2(ctx, id, description) {
|
|
2385
|
+
err.or_throw(symbols_exports.update(ctx, id, { description }));
|
|
2386
|
+
}
|
|
2387
|
+
function referenced_by_symbol(ctx, symbol_id, options = {}) {
|
|
2388
|
+
let referenced_symbols = err.or_throw(symbols_exports.referenced_by(ctx, symbol_id, options.select));
|
|
2389
|
+
if (options.deep) {
|
|
2390
|
+
referenced_symbols = err.or_throw(
|
|
2391
|
+
expand({
|
|
2392
|
+
items: referenced_symbols,
|
|
2393
|
+
get_children: (symbol) => symbols_exports.referenced_by(ctx, symbol.id, options.select),
|
|
2394
|
+
get_key: (symbol) => symbol.id
|
|
2395
|
+
})
|
|
2396
|
+
);
|
|
2397
|
+
}
|
|
2398
|
+
const start = options.offset ?? 0;
|
|
2399
|
+
const end = options.limit ? start + options.limit : referenced_symbols.length;
|
|
2400
|
+
return referenced_symbols.slice(start, end);
|
|
2401
|
+
}
|
|
2402
|
+
function referencing_symbol(ctx, symbol_id, options = {}) {
|
|
2403
|
+
let referencing_symbols = err.or_throw(symbols_exports.referencing(ctx, symbol_id, options.select));
|
|
2404
|
+
if (options.deep) {
|
|
2405
|
+
referencing_symbols = err.or_throw(
|
|
2406
|
+
expand({
|
|
2407
|
+
items: referencing_symbols,
|
|
2408
|
+
get_children: (symbol) => symbols_exports.referencing(ctx, symbol.id, options.select),
|
|
2409
|
+
get_key: (symbol) => symbol.id
|
|
2410
|
+
})
|
|
2411
|
+
);
|
|
2412
|
+
}
|
|
2413
|
+
const start = options.offset ?? 0;
|
|
2414
|
+
const end = options.limit ? start + options.limit : referencing_symbols.length;
|
|
2415
|
+
return referencing_symbols.slice(start, end);
|
|
2416
|
+
}
|
|
2417
|
+
function using_dependency3(ctx, dependency_id, options = {}) {
|
|
2418
|
+
let symbols_using_dep = err.or_throw(symbols_exports.using_dependency(ctx, dependency_id, options.select));
|
|
2419
|
+
if (options.deep) {
|
|
2420
|
+
symbols_using_dep = err.or_throw(
|
|
2421
|
+
expand({
|
|
2422
|
+
items: symbols_using_dep,
|
|
2423
|
+
get_children: (symbol) => symbols_exports.referencing(ctx, symbol.id, options.select),
|
|
2424
|
+
get_key: (symbol) => symbol.id
|
|
2425
|
+
})
|
|
2426
|
+
);
|
|
2427
|
+
}
|
|
2428
|
+
const start = options.offset ?? 0;
|
|
2429
|
+
const end = options.limit ? start + options.limit : symbols_using_dep.length;
|
|
2430
|
+
return symbols_using_dep.slice(start, end);
|
|
2431
|
+
}
|
|
2432
|
+
|
|
2433
|
+
// src/directories.ts
|
|
2434
|
+
function directories_wiki(ctx) {
|
|
2435
|
+
return {
|
|
2436
|
+
get: (id) => get4(ctx, id),
|
|
2437
|
+
search: (options) => search7(ctx, options),
|
|
2438
|
+
set_description: (id, description) => set_description3(ctx, id, description),
|
|
2439
|
+
children: (parent_id, options) => children(ctx, parent_id, options),
|
|
2440
|
+
files: (directory_id, options) => directory_files(ctx, directory_id, options)
|
|
2441
|
+
};
|
|
2442
|
+
}
|
|
2443
|
+
function get4(ctx, id) {
|
|
2444
|
+
return err.or_throw(directories_exports.by_id(ctx, id)) ?? null;
|
|
2445
|
+
}
|
|
2446
|
+
function search7(ctx, options) {
|
|
2447
|
+
return err.or_throw(directories_exports.search(ctx, options));
|
|
2448
|
+
}
|
|
2449
|
+
function set_description3(ctx, id, description) {
|
|
2450
|
+
err.or_throw(directories_exports.update(ctx, id, { description }));
|
|
2451
|
+
}
|
|
2452
|
+
function children(ctx, parent_id, options = {}) {
|
|
2453
|
+
let child_directories = err.or_throw(directories_exports.search(ctx, { select: options.select, where: { parent_id }, limit: 1e4 }));
|
|
2454
|
+
if (options.deep) {
|
|
2455
|
+
child_directories = err.or_throw(
|
|
2456
|
+
expand({
|
|
2457
|
+
items: child_directories,
|
|
2458
|
+
get_children: (dir) => directories_exports.search(ctx, { select: options.select, where: { parent_id: dir.id }, limit: 1e4 }),
|
|
2459
|
+
get_key: (dir) => dir.id
|
|
2460
|
+
})
|
|
2461
|
+
);
|
|
2462
|
+
}
|
|
2463
|
+
const start = options.offset ?? 0;
|
|
2464
|
+
const end = options.limit ? start + options.limit : child_directories.length;
|
|
2465
|
+
return child_directories.slice(start, end);
|
|
2466
|
+
}
|
|
2467
|
+
function directory_files(ctx, directory_id, options = {}) {
|
|
2468
|
+
let files_list = err.or_throw(files_exports.search(ctx, { select: options.select, where: { directory_id }, limit: 1e4 }));
|
|
2469
|
+
if (options.deep) {
|
|
2470
|
+
const all_subdirs = err.or_throw(
|
|
2471
|
+
expand({
|
|
2472
|
+
items: err.or_throw(directories_exports.search(ctx, { select: ["id"], where: { parent_id: directory_id }, limit: 1e4 })),
|
|
2473
|
+
get_children: (dir) => directories_exports.search(ctx, { select: ["id"], where: { parent_id: dir.id }, limit: 1e4 }),
|
|
2474
|
+
get_key: (dir) => dir.id
|
|
2475
|
+
})
|
|
2476
|
+
);
|
|
2477
|
+
for (const subdir of all_subdirs) {
|
|
2478
|
+
const subdir_files = err.or_throw(
|
|
2479
|
+
files_exports.search(ctx, { select: options.select, where: { directory_id: subdir.id }, limit: 1e4 })
|
|
2480
|
+
);
|
|
2481
|
+
subdir_files.forEach((x) => files_list.push(x));
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
const start = options.offset ?? 0;
|
|
2485
|
+
const end = options.limit ? start + options.limit : files_list.length;
|
|
2486
|
+
return files_list.slice(start, end);
|
|
2487
|
+
}
|
|
2488
|
+
|
|
2489
|
+
// src/dependencies.ts
|
|
2490
|
+
function dependencies_wiki(ctx) {
|
|
2491
|
+
return {
|
|
2492
|
+
get: (id) => get5(ctx, id),
|
|
2493
|
+
search: (options) => search8(ctx, options),
|
|
2494
|
+
set_description: (id, description) => set_description4(ctx, id, description),
|
|
2495
|
+
used_by_file: (file_id, options) => used_by_file2(ctx, file_id, options),
|
|
2496
|
+
used_by_symbol: (symbol_id, options) => used_by_symbol2(ctx, symbol_id, options)
|
|
2497
|
+
};
|
|
2498
|
+
}
|
|
2499
|
+
function get5(ctx, id) {
|
|
2500
|
+
return err.or_throw(external_dependencies_exports.by_id(ctx, id)) ?? null;
|
|
2501
|
+
}
|
|
2502
|
+
function search8(ctx, options) {
|
|
2503
|
+
return err.or_throw(external_dependencies_exports.search(ctx, options));
|
|
2504
|
+
}
|
|
2505
|
+
function set_description4(ctx, id, description) {
|
|
2506
|
+
err.or_throw(external_dependencies_exports.update(ctx, id, { description, state: "ready", error: null }));
|
|
2507
|
+
}
|
|
2508
|
+
function used_by_file2(ctx, file_id, options) {
|
|
2509
|
+
return err.or_throw(external_dependencies_exports.used_by_file(ctx, file_id, options?.select));
|
|
2510
|
+
}
|
|
2511
|
+
function used_by_symbol2(ctx, symbol_id, options) {
|
|
2512
|
+
return err.or_throw(external_dependencies_exports.used_by_symbol(ctx, symbol_id, options?.select));
|
|
2513
|
+
}
|
|
2514
|
+
|
|
2515
|
+
// src/index.ts
|
|
2516
|
+
async function create(config) {
|
|
2517
|
+
const ctx = await context_from_config(config);
|
|
2518
|
+
return {
|
|
2519
|
+
config,
|
|
2520
|
+
update: () => update6(ctx),
|
|
2521
|
+
counts: () => err.or_throw(counts(ctx)),
|
|
2522
|
+
files: files_wiki(ctx),
|
|
2523
|
+
symbols: symbols_wiki(ctx),
|
|
2524
|
+
directories: directories_wiki(ctx),
|
|
2525
|
+
dependencies: dependencies_wiki(ctx)
|
|
2526
|
+
};
|
|
2527
|
+
}
|
|
2528
|
+
async function load(db_path) {
|
|
2529
|
+
const ctx = await context_from_db(db_path);
|
|
2530
|
+
const stored = ctx.db.select().from(schema_exports.configs).get();
|
|
2531
|
+
const config = {
|
|
2532
|
+
db_path,
|
|
2533
|
+
project_path: stored.project_path,
|
|
2534
|
+
description: stored.description ?? void 0,
|
|
2535
|
+
package_json_path: stored.package_json_path ?? void 0,
|
|
2536
|
+
node_modules_paths: stored.node_modules_paths ? JSON.parse(stored.node_modules_paths) : void 0
|
|
2537
|
+
};
|
|
2538
|
+
return {
|
|
2539
|
+
config,
|
|
2540
|
+
update: () => update6(ctx),
|
|
2541
|
+
counts: () => err.or_throw(counts(ctx)),
|
|
2542
|
+
files: files_wiki(ctx),
|
|
2543
|
+
symbols: symbols_wiki(ctx),
|
|
2544
|
+
directories: directories_wiki(ctx),
|
|
2545
|
+
dependencies: dependencies_wiki(ctx)
|
|
2546
|
+
};
|
|
2547
|
+
}
|
|
2548
|
+
|
|
2549
|
+
// src/cli/commands/_common.ts
|
|
2550
|
+
var config_path = "codewiki.json";
|
|
2551
|
+
async function load_wiki() {
|
|
2552
|
+
try {
|
|
2553
|
+
const content = err.or_throw(env.read_file(config_path));
|
|
2554
|
+
const raw_config = err.or_throw(parse_json(content));
|
|
2555
|
+
const res = Config.safeParse(raw_config);
|
|
2556
|
+
if (!res.success) throw err.new("invalid_config", { errors: res.error.issues });
|
|
2557
|
+
const config = res.data;
|
|
2558
|
+
if (env.file_exists(config.db_path)) return load(config.db_path);
|
|
2559
|
+
return create(config);
|
|
2560
|
+
} catch (error) {
|
|
2561
|
+
if (error.type === "could_not_read_file") {
|
|
2562
|
+
env.error(`Error: Configuration file ${config_path} not found`);
|
|
2563
|
+
} else if (error.type === "invalid_json") {
|
|
2564
|
+
env.error(`Error: Invalid JSON in ${config_path}`);
|
|
2565
|
+
} else if (error.type === "invalid_config") {
|
|
2566
|
+
env.error("Error: Invalid configuration");
|
|
2567
|
+
} else if (error.message) {
|
|
2568
|
+
env.error(`Error: ${error.message}`);
|
|
2569
|
+
} else {
|
|
2570
|
+
env.error(`Error: ${String(error)}`);
|
|
2571
|
+
}
|
|
2572
|
+
process.exit(1);
|
|
2573
|
+
}
|
|
2574
|
+
}
|
|
2575
|
+
function parse_options(options_json, schema, context) {
|
|
2576
|
+
let parsed_json;
|
|
2577
|
+
try {
|
|
2578
|
+
parsed_json = err.or_throw(parse_json(options_json));
|
|
2579
|
+
} catch (error) {
|
|
2580
|
+
env.log(`Error: Invalid JSON in ${context}`);
|
|
2581
|
+
const error_msg = error.data?.reason?.message || "JSON parse error";
|
|
2582
|
+
env.log(` ${error_msg}`);
|
|
2583
|
+
process.exit(1);
|
|
2584
|
+
}
|
|
2585
|
+
const validation_result = schema.safeParse(parsed_json);
|
|
2586
|
+
if (!validation_result.success) {
|
|
2587
|
+
env.log(`Error: Invalid options format in ${context}`);
|
|
2588
|
+
env.log("");
|
|
2589
|
+
for (const issue of validation_result.error.issues) {
|
|
2590
|
+
const path6 = issue.path.length > 0 ? issue.path.join(".") : "root";
|
|
2591
|
+
env.log(` \u2022 ${path6}: ${issue.message}`);
|
|
2592
|
+
}
|
|
2593
|
+
env.log("");
|
|
2594
|
+
env.log(`Run 'codewiki ${context.split(" ")[0]} --help' for usage information`);
|
|
2595
|
+
process.exit(1);
|
|
2596
|
+
}
|
|
2597
|
+
return validation_result.data;
|
|
2598
|
+
}
|
|
2599
|
+
|
|
2600
|
+
// src/cli/utils.ts
|
|
2601
|
+
import dedent from "dedent";
|
|
2602
|
+
function format_counts(counts2) {
|
|
2603
|
+
const total_to_describe = Object.values(counts2).reduce((a, b) => a + b.to_describe, 0);
|
|
2604
|
+
return dedent`
|
|
2605
|
+
stats:
|
|
2606
|
+
directories: ${count_text(counts2.directories)}
|
|
2607
|
+
files: ${count_text(counts2.files)}
|
|
2608
|
+
symbols: ${count_text(counts2.symbols)}
|
|
2609
|
+
dependencies: ${count_text(counts2.dependencies)}
|
|
2610
|
+
|
|
2611
|
+
${total_to_describe} items to describe, run \`codewiki describe\` to start describing the codebase
|
|
2612
|
+
`;
|
|
2613
|
+
}
|
|
2614
|
+
function count_text({ total, ...states }) {
|
|
2615
|
+
return `${total} (${Object.entries(states).map(([name, value]) => `${value} ${name.replace("_", " ")}`).join(", ")})`;
|
|
2616
|
+
}
|
|
2617
|
+
|
|
2618
|
+
// src/cli/commands/update.ts
|
|
2619
|
+
var update7 = new Command("update");
|
|
2620
|
+
update7.description("Reads current files and updates the wiki database");
|
|
2621
|
+
update7.action(async () => {
|
|
2622
|
+
const wiki = await load_wiki();
|
|
2623
|
+
await wiki.update();
|
|
2624
|
+
env.log("Update complete.\n");
|
|
2625
|
+
const counts2 = wiki.counts();
|
|
2626
|
+
const status2 = format_counts(counts2);
|
|
2627
|
+
env.log(status2);
|
|
2628
|
+
});
|
|
2629
|
+
|
|
2630
|
+
// src/cli/commands/status.ts
|
|
2631
|
+
import { Command as Command2 } from "commander";
|
|
2632
|
+
var status = new Command2("status");
|
|
2633
|
+
status.description("Show the status of the wiki");
|
|
2634
|
+
status.action(async () => {
|
|
2635
|
+
const wiki = await load_wiki();
|
|
2636
|
+
const counts2 = wiki.counts();
|
|
2637
|
+
env.log(format_counts(counts2));
|
|
2638
|
+
});
|
|
2639
|
+
|
|
2640
|
+
// src/cli/commands/describe.ts
|
|
2641
|
+
import dedent2 from "dedent";
|
|
2642
|
+
import { Command as Command3 } from "commander";
|
|
2643
|
+
var describe = new Command3("describe");
|
|
2644
|
+
describe.description("Show the next item to describe");
|
|
2645
|
+
describe.action(async () => {
|
|
2646
|
+
const wiki = await load_wiki();
|
|
2647
|
+
const next = get_next_to_describe(wiki);
|
|
2648
|
+
if (!next) return env.log("All items are described!");
|
|
2649
|
+
if (next.type === "dependency") return describe_dependency(next.entity);
|
|
2650
|
+
env.log(
|
|
2651
|
+
`All external dependencies are described, and we don't support describing other items yet (we are implementing the right order ...). You are done for now!`
|
|
2652
|
+
);
|
|
2653
|
+
});
|
|
2654
|
+
function describe_dependency(dep) {
|
|
2655
|
+
env.log(dedent2`
|
|
2656
|
+
Your task is to describe the following dependency:
|
|
2657
|
+
|
|
2658
|
+
import { ${dep.name} } from '${dep.package}${dep.subpath || ""}'
|
|
2659
|
+
|
|
2660
|
+
package: ${dep.package}
|
|
2661
|
+
version: ${dep.version}
|
|
2662
|
+
github: ${dep.github_repo || "N/A"}
|
|
2663
|
+
|
|
2664
|
+
Write a concise developer documentation on the usage of this \`${dep.name}\` into a markdown file, then run the following command to save the description:
|
|
2665
|
+
\`codewiki dependencies set-description ${dep.id} <markdown-file>\`
|
|
2666
|
+
`);
|
|
2667
|
+
}
|
|
2668
|
+
function get_next_to_describe(wiki) {
|
|
2669
|
+
const deps = wiki.dependencies.search({
|
|
2670
|
+
where: { state: "to_describe" },
|
|
2671
|
+
limit: 1,
|
|
2672
|
+
select: ["id", "package", "subpath", "name", "version", "github_repo"]
|
|
2673
|
+
});
|
|
2674
|
+
if (deps.length > 0) {
|
|
2675
|
+
return { type: "dependency", entity: deps[0] };
|
|
2676
|
+
}
|
|
2677
|
+
const symbols4 = wiki.symbols.search({
|
|
2678
|
+
where: { state: "to_describe" },
|
|
2679
|
+
limit: 1,
|
|
2680
|
+
select: ["id", "name", "type", "file_id", "is_exported"]
|
|
2681
|
+
});
|
|
2682
|
+
if (symbols4.length > 0) {
|
|
2683
|
+
return { type: "symbol", entity: symbols4[0] };
|
|
2684
|
+
}
|
|
2685
|
+
const files5 = wiki.files.search({
|
|
2686
|
+
where: { state: "to_describe" },
|
|
2687
|
+
limit: 1,
|
|
2688
|
+
select: ["id", "path"]
|
|
2689
|
+
});
|
|
2690
|
+
if (files5.length > 0) {
|
|
2691
|
+
return { type: "file", entity: files5[0] };
|
|
2692
|
+
}
|
|
2693
|
+
const directories4 = wiki.directories.search({
|
|
2694
|
+
where: { state: "to_describe" },
|
|
2695
|
+
limit: 1,
|
|
2696
|
+
select: ["id", "path"]
|
|
2697
|
+
});
|
|
2698
|
+
if (directories4.length > 0) {
|
|
2699
|
+
return { type: "directory", entity: directories4[0] };
|
|
2700
|
+
}
|
|
2701
|
+
return null;
|
|
2702
|
+
}
|
|
2703
|
+
|
|
2704
|
+
// src/cli/commands/files/index.ts
|
|
2705
|
+
import { Command as Command10 } from "commander";
|
|
2706
|
+
import dedent3 from "dedent";
|
|
2707
|
+
|
|
2708
|
+
// src/cli/commands/files/get.ts
|
|
2709
|
+
import { Command as Command4 } from "commander";
|
|
2710
|
+
var get6 = new Command4("get");
|
|
2711
|
+
get6.description("Get a file by ID");
|
|
2712
|
+
get6.argument("<id>", "File ID");
|
|
2713
|
+
get6.action(async (id) => {
|
|
2714
|
+
const wiki = await load_wiki();
|
|
2715
|
+
const file = wiki.files.get(Number(id));
|
|
2716
|
+
env.log(JSON.stringify(file, null, 2));
|
|
2717
|
+
});
|
|
2718
|
+
|
|
2719
|
+
// src/cli/commands/files/search.ts
|
|
2720
|
+
import { Command as Command5 } from "commander";
|
|
2721
|
+
var search9 = new Command5("search");
|
|
2722
|
+
search9.description("Search files with JSON options");
|
|
2723
|
+
search9.argument("<options>", "JSON options for search");
|
|
2724
|
+
search9.action(async (options_json) => {
|
|
2725
|
+
const wiki = await load_wiki();
|
|
2726
|
+
const options = parse_options(options_json, FileSearchOptions, "files search");
|
|
2727
|
+
const results = wiki.files.search(options);
|
|
2728
|
+
env.log(JSON.stringify(results, null, 2));
|
|
2729
|
+
});
|
|
2730
|
+
|
|
2731
|
+
// src/cli/commands/files/set-description.ts
|
|
2732
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
2733
|
+
import { Command as Command6 } from "commander";
|
|
2734
|
+
var set_description5 = new Command6("set-description");
|
|
2735
|
+
set_description5.description("Set description for a file");
|
|
2736
|
+
set_description5.argument("<file-id>", "File ID");
|
|
2737
|
+
set_description5.argument("<markdown-file>", "Path to markdown file");
|
|
2738
|
+
set_description5.action(async (id, file) => {
|
|
2739
|
+
const wiki = await load_wiki();
|
|
2740
|
+
try {
|
|
2741
|
+
const content = readFileSync2(file, "utf-8");
|
|
2742
|
+
wiki.files.set_description(Number(id), content);
|
|
2743
|
+
env.log("Description saved. Run `codewiki describe` to describe the next item.");
|
|
2744
|
+
} catch (err2) {
|
|
2745
|
+
env.error(`Error: ${err2.message}`);
|
|
2746
|
+
env.exit(1);
|
|
2747
|
+
}
|
|
2748
|
+
});
|
|
2749
|
+
|
|
2750
|
+
// src/cli/commands/files/imported-by-file.ts
|
|
2751
|
+
import { Command as Command7 } from "commander";
|
|
2752
|
+
var imported_by_file2 = new Command7("imported-by-file");
|
|
2753
|
+
imported_by_file2.description("Files imported by the given file");
|
|
2754
|
+
imported_by_file2.argument("<file-id>", "File ID");
|
|
2755
|
+
imported_by_file2.argument("<options>", "JSON options");
|
|
2756
|
+
imported_by_file2.action(async (file_id, options_json) => {
|
|
2757
|
+
const wiki = await load_wiki();
|
|
2758
|
+
const options = parse_options(options_json, FileRelationOptions, "files imported-by-file");
|
|
2759
|
+
const results = wiki.files.imported_by_file(Number(file_id), options);
|
|
2760
|
+
env.log(JSON.stringify(results, null, 2));
|
|
2761
|
+
});
|
|
2762
|
+
|
|
2763
|
+
// src/cli/commands/files/importing-file.ts
|
|
2764
|
+
import { Command as Command8 } from "commander";
|
|
2765
|
+
var importing_file2 = new Command8("importing-file");
|
|
2766
|
+
importing_file2.description("Files importing the given file");
|
|
2767
|
+
importing_file2.argument("<file-id>", "File ID");
|
|
2768
|
+
importing_file2.argument("<options>", "JSON options");
|
|
2769
|
+
importing_file2.action(async (file_id, options_json) => {
|
|
2770
|
+
const wiki = await load_wiki();
|
|
2771
|
+
const options = parse_options(options_json, FileRelationOptions, "files importing-file");
|
|
2772
|
+
const results = wiki.files.importing_file(Number(file_id), options);
|
|
2773
|
+
env.log(JSON.stringify(results, null, 2));
|
|
2774
|
+
});
|
|
2775
|
+
|
|
2776
|
+
// src/cli/commands/files/importing-dependency.ts
|
|
2777
|
+
import { Command as Command9 } from "commander";
|
|
2778
|
+
var importing_dependency2 = new Command9("importing-dependency");
|
|
2779
|
+
importing_dependency2.description("Files importing the given dependency");
|
|
2780
|
+
importing_dependency2.argument("<dep-id>", "Dependency ID");
|
|
2781
|
+
importing_dependency2.argument("<options>", "JSON options");
|
|
2782
|
+
importing_dependency2.action(async (dep_id, options_json) => {
|
|
2783
|
+
const wiki = await load_wiki();
|
|
2784
|
+
const options = parse_options(options_json, FileRelationOptions, "files importing-dependency");
|
|
2785
|
+
const results = wiki.files.importing_dependency(Number(dep_id), options);
|
|
2786
|
+
env.log(JSON.stringify(results, null, 2));
|
|
2787
|
+
});
|
|
2788
|
+
|
|
2789
|
+
// src/cli/commands/files/index.ts
|
|
2790
|
+
var files3 = new Command10("files");
|
|
2791
|
+
files3.description("Explore files");
|
|
2792
|
+
files3.addCommand(get6);
|
|
2793
|
+
files3.addCommand(search9);
|
|
2794
|
+
files3.addCommand(set_description5);
|
|
2795
|
+
files3.addCommand(imported_by_file2);
|
|
2796
|
+
files3.addCommand(importing_file2);
|
|
2797
|
+
files3.addCommand(importing_dependency2);
|
|
2798
|
+
files3.addHelpText("after", dedent3`
|
|
2799
|
+
|
|
2800
|
+
<search-options> is a JSON string following the type SearchOptions:
|
|
2801
|
+
|
|
2802
|
+
type FileField = "id" | "directory_id" | "path" | "description" | "state" | "error"
|
|
2803
|
+
type SearchOptions = {
|
|
2804
|
+
select?: Array<FileField>
|
|
2805
|
+
limit?: number
|
|
2806
|
+
offset?: number
|
|
2807
|
+
where?: Record<FileField, string | { contains: string } | { starts_with: string } | { ends_with: string }>
|
|
2808
|
+
order_by?: [FileField, 'asc' | 'desc']
|
|
2809
|
+
}
|
|
2810
|
+
|
|
2811
|
+
<relation-options> is a JSON string following the type RelationOptions:
|
|
2812
|
+
|
|
2813
|
+
type RelationOptions = {
|
|
2814
|
+
select?: Array<FileField>
|
|
2815
|
+
limit?: number
|
|
2816
|
+
offset?: number
|
|
2817
|
+
deep?: boolean
|
|
2818
|
+
}
|
|
2819
|
+
|
|
2820
|
+
Examples:
|
|
2821
|
+
codewiki files search '{"limit": 10}'
|
|
2822
|
+
codewiki files search '{"where": {"state": "ready"}, "limit": 5}'
|
|
2823
|
+
codewiki files search '{"where": {"path": {"contains": "test"}}, "limit": 10}'
|
|
2824
|
+
codewiki files imported-by-file 123 '{"limit": 10}'
|
|
2825
|
+
`);
|
|
2826
|
+
|
|
2827
|
+
// src/cli/commands/symbols/index.ts
|
|
2828
|
+
import { Command as Command17 } from "commander";
|
|
2829
|
+
import dedent4 from "dedent";
|
|
2830
|
+
|
|
2831
|
+
// src/cli/commands/symbols/get.ts
|
|
2832
|
+
import { Command as Command11 } from "commander";
|
|
2833
|
+
var get7 = new Command11("get");
|
|
2834
|
+
get7.description("Get a symbol by ID");
|
|
2835
|
+
get7.argument("<id>", "Symbol ID");
|
|
2836
|
+
get7.action(async (id) => {
|
|
2837
|
+
const wiki = await load_wiki();
|
|
2838
|
+
const symbol = wiki.symbols.get(Number(id));
|
|
2839
|
+
env.log(JSON.stringify(symbol, null, 2));
|
|
2840
|
+
});
|
|
2841
|
+
|
|
2842
|
+
// src/cli/commands/symbols/search.ts
|
|
2843
|
+
import { Command as Command12 } from "commander";
|
|
2844
|
+
var search10 = new Command12("search");
|
|
2845
|
+
search10.description("Search symbols with JSON options");
|
|
2846
|
+
search10.argument("<options>", "JSON options");
|
|
2847
|
+
search10.action(async (options_json) => {
|
|
2848
|
+
const wiki = await load_wiki();
|
|
2849
|
+
const options = parse_options(options_json, SymbolSearchOptions, "symbols search");
|
|
2850
|
+
const results = wiki.symbols.search(options);
|
|
2851
|
+
env.log(JSON.stringify(results, null, 2));
|
|
2852
|
+
});
|
|
2853
|
+
|
|
2854
|
+
// src/cli/commands/symbols/set-description.ts
|
|
2855
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
2856
|
+
import { Command as Command13 } from "commander";
|
|
2857
|
+
var set_description6 = new Command13("set-description");
|
|
2858
|
+
set_description6.description("Set description for a symbol");
|
|
2859
|
+
set_description6.argument("<symbol-id>", "Symbol ID");
|
|
2860
|
+
set_description6.argument("<markdown-file>", "Path to markdown file");
|
|
2861
|
+
set_description6.action(async (id, file) => {
|
|
2862
|
+
const wiki = await load_wiki();
|
|
2863
|
+
try {
|
|
2864
|
+
const content = readFileSync3(file, "utf-8");
|
|
2865
|
+
wiki.symbols.set_description(Number(id), content);
|
|
2866
|
+
env.log("Description saved. Run `codewiki describe` to describe the next item.");
|
|
2867
|
+
} catch (err2) {
|
|
2868
|
+
env.error(`Error: ${err2.message}`);
|
|
2869
|
+
env.exit(1);
|
|
2870
|
+
}
|
|
2871
|
+
});
|
|
2872
|
+
|
|
2873
|
+
// src/cli/commands/symbols/referencing-symbol.ts
|
|
2874
|
+
import { Command as Command14 } from "commander";
|
|
2875
|
+
var referencing_symbol2 = new Command14("referencing-symbol");
|
|
2876
|
+
referencing_symbol2.description("Symbols referencing the given symbol");
|
|
2877
|
+
referencing_symbol2.argument("<symbol-id>", "Symbol ID");
|
|
2878
|
+
referencing_symbol2.argument("<options>", "JSON options");
|
|
2879
|
+
referencing_symbol2.action(async (symbol_id, options_json) => {
|
|
2880
|
+
const wiki = await load_wiki();
|
|
2881
|
+
const options = parse_options(options_json, SymbolRelationOptions, "symbols referencing-symbol");
|
|
2882
|
+
const results = wiki.symbols.referencing_symbol(Number(symbol_id), options);
|
|
2883
|
+
env.log(JSON.stringify(results, null, 2));
|
|
2884
|
+
});
|
|
2885
|
+
|
|
2886
|
+
// src/cli/commands/symbols/referenced-by-symbol.ts
|
|
2887
|
+
import { Command as Command15 } from "commander";
|
|
2888
|
+
var referenced_by_symbol2 = new Command15("referenced-by-symbol");
|
|
2889
|
+
referenced_by_symbol2.description("Symbols referenced by the given symbol");
|
|
2890
|
+
referenced_by_symbol2.argument("<symbol-id>", "Symbol ID");
|
|
2891
|
+
referenced_by_symbol2.argument("<options>", "JSON options");
|
|
2892
|
+
referenced_by_symbol2.action(async (symbol_id, options_json) => {
|
|
2893
|
+
const wiki = await load_wiki();
|
|
2894
|
+
const options = parse_options(options_json, SymbolRelationOptions, "symbols referenced-by-symbol");
|
|
2895
|
+
const results = wiki.symbols.referenced_by_symbol(Number(symbol_id), options);
|
|
2896
|
+
env.log(JSON.stringify(results, null, 2));
|
|
2897
|
+
});
|
|
2898
|
+
|
|
2899
|
+
// src/cli/commands/symbols/using-dependency.ts
|
|
2900
|
+
import { Command as Command16 } from "commander";
|
|
2901
|
+
var using_dependency4 = new Command16("using-dependency");
|
|
2902
|
+
using_dependency4.description("Symbols using the given dependency");
|
|
2903
|
+
using_dependency4.argument("<dep-id>", "Dependency ID");
|
|
2904
|
+
using_dependency4.argument("<options>", "JSON options");
|
|
2905
|
+
using_dependency4.action(async (dep_id, options_json) => {
|
|
2906
|
+
const wiki = await load_wiki();
|
|
2907
|
+
const options = parse_options(options_json, SymbolRelationOptions, "symbols using-dependency");
|
|
2908
|
+
const results = wiki.symbols.using_dependency(Number(dep_id), options);
|
|
2909
|
+
env.log(JSON.stringify(results, null, 2));
|
|
2910
|
+
});
|
|
2911
|
+
|
|
2912
|
+
// src/cli/commands/symbols/index.ts
|
|
2913
|
+
var symbols3 = new Command17("symbols");
|
|
2914
|
+
symbols3.description("Explore symbols");
|
|
2915
|
+
symbols3.addCommand(get7);
|
|
2916
|
+
symbols3.addCommand(search10);
|
|
2917
|
+
symbols3.addCommand(set_description6);
|
|
2918
|
+
symbols3.addCommand(referencing_symbol2);
|
|
2919
|
+
symbols3.addCommand(referenced_by_symbol2);
|
|
2920
|
+
symbols3.addCommand(using_dependency4);
|
|
2921
|
+
symbols3.addHelpText("after", dedent4`
|
|
2922
|
+
|
|
2923
|
+
<search-options> is a JSON string following the type SearchOptions:
|
|
2924
|
+
|
|
2925
|
+
type SymbolField = "id" | "file_id" | "type" | "name" | "text" | "meta" | "description" | "is_exported" | "state" | "error"
|
|
2926
|
+
type SearchOptions = {
|
|
2927
|
+
select?: Array<SymbolField>
|
|
2928
|
+
limit?: number
|
|
2929
|
+
offset?: number
|
|
2930
|
+
where?: Record<SymbolField, string | { contains: string } | { starts_with: string } | { ends_with: string }>
|
|
2931
|
+
order_by?: [SymbolField, 'asc' | 'desc']
|
|
2932
|
+
}
|
|
2933
|
+
|
|
2934
|
+
<relation-options> is a JSON string following the type RelationOptions:
|
|
2935
|
+
|
|
2936
|
+
type RelationOptions = {
|
|
2937
|
+
select?: Array<SymbolField>
|
|
2938
|
+
limit?: number
|
|
2939
|
+
offset?: number
|
|
2940
|
+
deep?: boolean
|
|
2941
|
+
}
|
|
2942
|
+
|
|
2943
|
+
Examples:
|
|
2944
|
+
codewiki symbols search '{"limit": 10}'
|
|
2945
|
+
codewiki symbols search '{"where": {"type": "function"}, "limit": 5}'
|
|
2946
|
+
codewiki symbols search '{"where": {"name": {"starts_with": "test"}}, "limit": 10}'
|
|
2947
|
+
codewiki symbols referencing-symbol 123 '{"limit": 10}'
|
|
2948
|
+
`);
|
|
2949
|
+
|
|
2950
|
+
// src/cli/commands/directories/index.ts
|
|
2951
|
+
import { Command as Command23 } from "commander";
|
|
2952
|
+
import dedent5 from "dedent";
|
|
2953
|
+
|
|
2954
|
+
// src/cli/commands/directories/get.ts
|
|
2955
|
+
import { Command as Command18 } from "commander";
|
|
2956
|
+
var get8 = new Command18("get");
|
|
2957
|
+
get8.description("Get a directory by ID");
|
|
2958
|
+
get8.argument("<id>", "Directory ID");
|
|
2959
|
+
get8.action(async (id) => {
|
|
2960
|
+
const wiki = await load_wiki();
|
|
2961
|
+
const directory = wiki.directories.get(Number(id));
|
|
2962
|
+
env.log(JSON.stringify(directory, null, 2));
|
|
2963
|
+
});
|
|
2964
|
+
|
|
2965
|
+
// src/cli/commands/directories/search.ts
|
|
2966
|
+
import { Command as Command19 } from "commander";
|
|
2967
|
+
var search11 = new Command19("search");
|
|
2968
|
+
search11.description("Search directories with JSON options");
|
|
2969
|
+
search11.argument("<options>", "JSON options");
|
|
2970
|
+
search11.action(async (options_json) => {
|
|
2971
|
+
const wiki = await load_wiki();
|
|
2972
|
+
const options = parse_options(options_json, DirectorySearchOptions, "directories search");
|
|
2973
|
+
const results = wiki.directories.search(options);
|
|
2974
|
+
env.log(JSON.stringify(results, null, 2));
|
|
2975
|
+
});
|
|
2976
|
+
|
|
2977
|
+
// src/cli/commands/directories/set-description.ts
|
|
2978
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
2979
|
+
import { Command as Command20 } from "commander";
|
|
2980
|
+
var set_description7 = new Command20("set-description");
|
|
2981
|
+
set_description7.description("Set description for a directory");
|
|
2982
|
+
set_description7.argument("<directory-id>", "Directory ID");
|
|
2983
|
+
set_description7.argument("<markdown-file>", "Path to markdown file");
|
|
2984
|
+
set_description7.action(async (id, file) => {
|
|
2985
|
+
const wiki = await load_wiki();
|
|
2986
|
+
try {
|
|
2987
|
+
const content = readFileSync4(file, "utf-8");
|
|
2988
|
+
wiki.directories.set_description(Number(id), content);
|
|
2989
|
+
env.log("Description saved. Run `codewiki describe` to describe the next item.");
|
|
2990
|
+
} catch (err2) {
|
|
2991
|
+
env.error(`Error: ${err2.message}`);
|
|
2992
|
+
env.exit(1);
|
|
2993
|
+
}
|
|
2994
|
+
});
|
|
2995
|
+
|
|
2996
|
+
// src/cli/commands/directories/children.ts
|
|
2997
|
+
import { Command as Command21 } from "commander";
|
|
2998
|
+
var children2 = new Command21("children");
|
|
2999
|
+
children2.description("Child directories of the given directory");
|
|
3000
|
+
children2.argument("<parent-id>", "Parent directory ID");
|
|
3001
|
+
children2.argument("<options>", "JSON options");
|
|
3002
|
+
children2.action(async (parent_id, options_json) => {
|
|
3003
|
+
const wiki = await load_wiki();
|
|
3004
|
+
const options = parse_options(options_json, DirectoryRelationOptions, "directories children");
|
|
3005
|
+
const results = wiki.directories.children(Number(parent_id), options);
|
|
3006
|
+
env.log(JSON.stringify(results, null, 2));
|
|
3007
|
+
});
|
|
3008
|
+
|
|
3009
|
+
// src/cli/commands/directories/files.ts
|
|
3010
|
+
import { Command as Command22 } from "commander";
|
|
3011
|
+
var files4 = new Command22("files");
|
|
3012
|
+
files4.description("Files in the given directory");
|
|
3013
|
+
files4.argument("<directory-id>", "Directory ID");
|
|
3014
|
+
files4.argument("<options>", "JSON options");
|
|
3015
|
+
files4.action(async (directory_id, options_json) => {
|
|
3016
|
+
const wiki = await load_wiki();
|
|
3017
|
+
const options = parse_options(options_json, FileRelationOptions, "directories files");
|
|
3018
|
+
const results = wiki.directories.files(Number(directory_id), options);
|
|
3019
|
+
env.log(JSON.stringify(results, null, 2));
|
|
3020
|
+
});
|
|
3021
|
+
|
|
3022
|
+
// src/cli/commands/directories/index.ts
|
|
3023
|
+
var directories3 = new Command23("directories");
|
|
3024
|
+
directories3.description("Explore directories");
|
|
3025
|
+
directories3.addCommand(get8);
|
|
3026
|
+
directories3.addCommand(search11);
|
|
3027
|
+
directories3.addCommand(set_description7);
|
|
3028
|
+
directories3.addCommand(children2);
|
|
3029
|
+
directories3.addCommand(files4);
|
|
3030
|
+
directories3.addHelpText("after", dedent5`
|
|
3031
|
+
|
|
3032
|
+
<search-options> is a JSON string following the type SearchOptions:
|
|
3033
|
+
|
|
3034
|
+
type DirectoryField = "id" | "parent_id" | "path" | "description" | "state" | "error"
|
|
3035
|
+
type SearchOptions = {
|
|
3036
|
+
select?: Array<DirectoryField>
|
|
3037
|
+
limit?: number
|
|
3038
|
+
offset?: number
|
|
3039
|
+
where?: Record<DirectoryField, string | { contains: string } | { starts_with: string } | { ends_with: string }>
|
|
3040
|
+
order_by?: [DirectoryField, 'asc' | 'desc']
|
|
3041
|
+
}
|
|
3042
|
+
|
|
3043
|
+
<relation-options> is a JSON string following the type RelationOptions:
|
|
3044
|
+
|
|
3045
|
+
type RelationOptions = {
|
|
3046
|
+
select?: Array<DirectoryField> | Array<FileField>
|
|
3047
|
+
limit?: number
|
|
3048
|
+
offset?: number
|
|
3049
|
+
deep?: boolean
|
|
3050
|
+
}
|
|
3051
|
+
|
|
3052
|
+
Examples:
|
|
3053
|
+
codewiki directories search '{"limit": 10}'
|
|
3054
|
+
codewiki directories search '{"where": {"path": {"contains": "src"}}, "limit": 5}'
|
|
3055
|
+
codewiki directories children 123 '{"limit": 10, "deep": true}'
|
|
3056
|
+
codewiki directories files 123 '{"limit": 20}'
|
|
3057
|
+
`);
|
|
3058
|
+
|
|
3059
|
+
// src/cli/commands/dependencies/index.ts
|
|
3060
|
+
import { Command as Command29 } from "commander";
|
|
3061
|
+
import dedent6 from "dedent";
|
|
3062
|
+
|
|
3063
|
+
// src/cli/commands/dependencies/get.ts
|
|
3064
|
+
import { Command as Command24 } from "commander";
|
|
3065
|
+
var get9 = new Command24("get");
|
|
3066
|
+
get9.description("Get a dependency by ID");
|
|
3067
|
+
get9.argument("<id>", "Dependency ID");
|
|
3068
|
+
get9.action(async (id) => {
|
|
3069
|
+
const wiki = await load_wiki();
|
|
3070
|
+
const dependency = wiki.dependencies.get(Number(id));
|
|
3071
|
+
env.log(JSON.stringify(dependency, null, 2));
|
|
3072
|
+
});
|
|
3073
|
+
|
|
3074
|
+
// src/cli/commands/dependencies/search.ts
|
|
3075
|
+
import { Command as Command25 } from "commander";
|
|
3076
|
+
var search12 = new Command25("search");
|
|
3077
|
+
search12.description("Search dependencies with JSON options");
|
|
3078
|
+
search12.argument("<options>", "JSON options");
|
|
3079
|
+
search12.action(async (options_json) => {
|
|
3080
|
+
const wiki = await load_wiki();
|
|
3081
|
+
const options = parse_options(options_json, DependencySearchOptions, "dependencies search");
|
|
3082
|
+
const results = wiki.dependencies.search(options);
|
|
3083
|
+
env.log(JSON.stringify(results, null, 2));
|
|
3084
|
+
});
|
|
3085
|
+
|
|
3086
|
+
// src/cli/commands/dependencies/set-description.ts
|
|
3087
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
3088
|
+
import { Command as Command26 } from "commander";
|
|
3089
|
+
var set_description8 = new Command26("set-description");
|
|
3090
|
+
set_description8.description("Set description for a dependency");
|
|
3091
|
+
set_description8.argument("<dependency-id>", "Dependency ID");
|
|
3092
|
+
set_description8.argument("<markdown-file>", "Path to markdown file");
|
|
3093
|
+
set_description8.action(async (id, file) => {
|
|
3094
|
+
const wiki = await load_wiki();
|
|
3095
|
+
try {
|
|
3096
|
+
const content = readFileSync5(file, "utf-8");
|
|
3097
|
+
wiki.dependencies.set_description(Number(id), content);
|
|
3098
|
+
env.log("Description saved. Run `codewiki describe` to describe the next item.");
|
|
3099
|
+
} catch (err2) {
|
|
3100
|
+
env.error(`Error: ${err2.message}`);
|
|
3101
|
+
env.exit(1);
|
|
3102
|
+
}
|
|
3103
|
+
});
|
|
3104
|
+
|
|
3105
|
+
// src/cli/commands/dependencies/used-by-file.ts
|
|
3106
|
+
import { Command as Command27 } from "commander";
|
|
3107
|
+
var used_by_file3 = new Command27("used-by-file");
|
|
3108
|
+
used_by_file3.description("Dependencies used by the given file");
|
|
3109
|
+
used_by_file3.argument("<file-id>", "File ID");
|
|
3110
|
+
used_by_file3.argument("<options>", "JSON options");
|
|
3111
|
+
used_by_file3.action(async (file_id, options_json) => {
|
|
3112
|
+
const wiki = await load_wiki();
|
|
3113
|
+
const options = parse_options(options_json, DependencySelectOptions, "dependencies used-by-file");
|
|
3114
|
+
const results = wiki.dependencies.used_by_file(Number(file_id), options);
|
|
3115
|
+
env.log(JSON.stringify(results, null, 2));
|
|
3116
|
+
});
|
|
3117
|
+
|
|
3118
|
+
// src/cli/commands/dependencies/used-by-symbol.ts
|
|
3119
|
+
import { Command as Command28 } from "commander";
|
|
3120
|
+
var used_by_symbol3 = new Command28("used-by-symbol");
|
|
3121
|
+
used_by_symbol3.description("Dependencies used by the given symbol");
|
|
3122
|
+
used_by_symbol3.argument("<symbol-id>", "Symbol ID");
|
|
3123
|
+
used_by_symbol3.argument("<options>", "JSON options");
|
|
3124
|
+
used_by_symbol3.action(async (symbol_id, options_json) => {
|
|
3125
|
+
const wiki = await load_wiki();
|
|
3126
|
+
const options = parse_options(options_json, DependencySelectOptions, "dependencies used-by-symbol");
|
|
3127
|
+
const results = wiki.dependencies.used_by_symbol(Number(symbol_id), options);
|
|
3128
|
+
env.log(JSON.stringify(results, null, 2));
|
|
3129
|
+
});
|
|
3130
|
+
|
|
3131
|
+
// src/cli/commands/dependencies/index.ts
|
|
3132
|
+
var dependencies = new Command29("dependencies");
|
|
3133
|
+
dependencies.description("Explore dependencies");
|
|
3134
|
+
dependencies.addCommand(get9);
|
|
3135
|
+
dependencies.addCommand(search12);
|
|
3136
|
+
dependencies.addCommand(set_description8);
|
|
3137
|
+
dependencies.addCommand(used_by_file3);
|
|
3138
|
+
dependencies.addCommand(used_by_symbol3);
|
|
3139
|
+
dependencies.addHelpText("after", dedent6`
|
|
3140
|
+
|
|
3141
|
+
<search-options> is a JSON string following the type SearchOptions:
|
|
3142
|
+
|
|
3143
|
+
type DependencyField = "id" | "package" | "subpath" | "name" | "version" | "github_repo" | "is_builtin" | "description" | "state" | "error"
|
|
3144
|
+
type SearchOptions = {
|
|
3145
|
+
select?: Array<DependencyField>
|
|
3146
|
+
limit?: number
|
|
3147
|
+
offset?: number
|
|
3148
|
+
where?: Record<DependencyField, string | { contains: string } | { starts_with: string } | { ends_with: string }>
|
|
3149
|
+
order_by?: [DependencyField, 'asc' | 'desc']
|
|
3150
|
+
}
|
|
3151
|
+
|
|
3152
|
+
<select-options> is a JSON string following the type SelectOptions:
|
|
3153
|
+
|
|
3154
|
+
type SelectOptions = {
|
|
3155
|
+
select?: Array<DependencyField>
|
|
3156
|
+
limit?: number
|
|
3157
|
+
offset?: number
|
|
3158
|
+
}
|
|
3159
|
+
|
|
3160
|
+
Examples:
|
|
3161
|
+
codewiki dependencies search '{"limit": 10}'
|
|
3162
|
+
codewiki dependencies search '{"where": {"is_builtin": false}, "limit": 5}'
|
|
3163
|
+
codewiki dependencies search '{"where": {"package": {"starts_with": "@types"}}, "limit": 10}'
|
|
3164
|
+
codewiki dependencies used-by-file 123 '{"limit": 10}'
|
|
3165
|
+
`);
|
|
3166
|
+
|
|
3167
|
+
// src/cli/commands/index.ts
|
|
3168
|
+
var commands = [update7, status, describe, files3, symbols3, directories3, dependencies];
|
|
3169
|
+
|
|
3170
|
+
// src/cli/index.ts
|
|
3171
|
+
async function run(argv) {
|
|
3172
|
+
const program = new Command30();
|
|
3173
|
+
program.name("codewiki").description("Describe and explore TypeScript codebases").version("0.0.1");
|
|
3174
|
+
for (const cmd of commands) program.addCommand(cmd);
|
|
3175
|
+
return program.parseAsync(argv, { from: "user" });
|
|
3176
|
+
}
|
|
3177
|
+
|
|
3178
|
+
// src/cli/bin.ts
|
|
3179
|
+
run(env.argv().slice(2)).catch((error) => {
|
|
3180
|
+
env.error(error.message || String(error));
|
|
3181
|
+
env.exit(1);
|
|
3182
|
+
});
|
|
3183
|
+
//# sourceMappingURL=bin.js.map
|