@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/index.js
ADDED
|
@@ -0,0 +1,2418 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __export = (target, all3) => {
|
|
3
|
+
for (var name in all3)
|
|
4
|
+
__defProp(target, name, { get: all3[name], enumerable: true });
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
// src/internals/context.ts
|
|
8
|
+
import ts from "typescript";
|
|
9
|
+
import { fileURLToPath } from "url";
|
|
10
|
+
import Database from "better-sqlite3";
|
|
11
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
12
|
+
import path, { dirname, join as join2 } from "path";
|
|
13
|
+
import { drizzle } from "drizzle-orm/better-sqlite3";
|
|
14
|
+
|
|
15
|
+
// src/internals/errors.ts
|
|
16
|
+
import create_errors from "@webneat/errors";
|
|
17
|
+
var err = create_errors({
|
|
18
|
+
file_outside_project_path: (data) => `File "${data.file_path}" is outside project path "${data.project_path}"`,
|
|
19
|
+
file_not_found: (data) => `File not found: ${data.path}`,
|
|
20
|
+
db_error: (data) => `Database error in ${data.operation}: ${data.reason}`,
|
|
21
|
+
symbol_meta_parse_error: (data) => `Failed to parse symbol metadata for symbol ${data.symbol_id}: ${data.reason}`,
|
|
22
|
+
exported_symbol_not_found: (data) => `Exported symbol "${data.name}" not found in file with id ${data.file_id}`,
|
|
23
|
+
module_resolution_failed: (data) => `Failed to resolve module "${data.module}" from "${data.from}"`,
|
|
24
|
+
exporter_file_not_found: (data) => `Exporter file not found at "${data.path}" for module "${data.module}"`,
|
|
25
|
+
ast_parse_error: (data) => `AST parsing error in ${data.operation}: ${data.reason}`,
|
|
26
|
+
config_not_found: (data) => `No config found in database at ${data.db_path}`,
|
|
27
|
+
config_invalid_node_modules_paths: (data) => `Invalid node_modules_paths stored in database ${data.db_path}: ${data.reason}`,
|
|
28
|
+
symbol_missing_text: (data) => `Symbol ${data.symbol_id} (${data.name}) has no source text`,
|
|
29
|
+
symbol_node_not_found: (data) => `Symbol node not found for ${data.name} in ${data.file_path}`,
|
|
30
|
+
symbol_not_found: (data) => `Symbol "${data.name}" not found in file "${data.path}"`,
|
|
31
|
+
describe_dependency_failed: (data) => `Failed to describe ${data.package}#${data.name}: ${data.reason}`,
|
|
32
|
+
// CLI errors
|
|
33
|
+
could_not_read_file: (data) => `Could not read file ${data.path}: ${data.reason}`,
|
|
34
|
+
invalid_json: (data) => `Invalid JSON: ${data.reason}`,
|
|
35
|
+
invalid_config: (data) => `Invalid configuration: ${JSON.stringify(data.errors)}`,
|
|
36
|
+
invalid_type: (data) => `Invalid entity type: ${data.type}. Must be one of: dependency, symbol, file, directory`
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// src/db/migrate.ts
|
|
40
|
+
import { readdir, readFile } from "fs/promises";
|
|
41
|
+
import { join } from "path";
|
|
42
|
+
import { sql as sql2 } from "drizzle-orm";
|
|
43
|
+
|
|
44
|
+
// src/db/schema.ts
|
|
45
|
+
var schema_exports = {};
|
|
46
|
+
__export(schema_exports, {
|
|
47
|
+
configs: () => configs,
|
|
48
|
+
directories: () => directories,
|
|
49
|
+
directories_relations: () => directories_relations,
|
|
50
|
+
external_dependencies: () => external_dependencies,
|
|
51
|
+
external_dependencies_relations: () => external_dependencies_relations,
|
|
52
|
+
external_imports: () => external_imports,
|
|
53
|
+
external_imports_relations: () => external_imports_relations,
|
|
54
|
+
files: () => files,
|
|
55
|
+
files_relations: () => files_relations,
|
|
56
|
+
imports: () => imports,
|
|
57
|
+
imports_relations: () => imports_relations,
|
|
58
|
+
migrations: () => migrations,
|
|
59
|
+
symbol_external_links: () => symbol_external_links,
|
|
60
|
+
symbol_external_links_relations: () => symbol_external_links_relations,
|
|
61
|
+
symbol_internal_links: () => symbol_internal_links,
|
|
62
|
+
symbol_internal_links_relations: () => symbol_internal_links_relations,
|
|
63
|
+
symbols: () => symbols,
|
|
64
|
+
symbols_relations: () => symbols_relations
|
|
65
|
+
});
|
|
66
|
+
import { relations, sql } from "drizzle-orm";
|
|
67
|
+
import { sqliteTable, integer, text, index, uniqueIndex } from "drizzle-orm/sqlite-core";
|
|
68
|
+
var timestamps = {
|
|
69
|
+
created_at: integer("created_at", { mode: "timestamp" }).default(sql`(unixepoch())`).notNull(),
|
|
70
|
+
updated_at: integer("updated_at", { mode: "timestamp" }).default(sql`(unixepoch())`).notNull()
|
|
71
|
+
};
|
|
72
|
+
var migrations = sqliteTable("migrations", {
|
|
73
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
74
|
+
name: text("name").notNull().unique(),
|
|
75
|
+
created_at: timestamps.created_at
|
|
76
|
+
});
|
|
77
|
+
var configs = sqliteTable("configs", {
|
|
78
|
+
id: integer("id").primaryKey({ autoIncrement: false }).notNull().default(1),
|
|
79
|
+
project_path: text("project_path").notNull(),
|
|
80
|
+
description: text("description"),
|
|
81
|
+
package_json_path: text("package_json_path"),
|
|
82
|
+
node_modules_paths: text("node_modules_paths"),
|
|
83
|
+
...timestamps
|
|
84
|
+
});
|
|
85
|
+
var directories = sqliteTable(
|
|
86
|
+
"directories",
|
|
87
|
+
{
|
|
88
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
89
|
+
parent_id: integer("parent_id").references(() => directories.id, { onDelete: "cascade" }),
|
|
90
|
+
path: text("path").notNull().unique(),
|
|
91
|
+
description: text("description"),
|
|
92
|
+
state: text("state").$type().notNull().default("to_describe"),
|
|
93
|
+
error: text("error"),
|
|
94
|
+
...timestamps
|
|
95
|
+
},
|
|
96
|
+
(table) => ({
|
|
97
|
+
parent_idx: index("directories_parent_idx").on(table.parent_id),
|
|
98
|
+
path_idx: index("directories_path_idx").on(table.path),
|
|
99
|
+
state_idx: index("directories_state_idx").on(table.state)
|
|
100
|
+
})
|
|
101
|
+
);
|
|
102
|
+
var files = sqliteTable(
|
|
103
|
+
"files",
|
|
104
|
+
{
|
|
105
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
106
|
+
directory_id: integer("directory_id").notNull().references(() => directories.id, { onDelete: "cascade" }),
|
|
107
|
+
path: text("path").notNull().unique(),
|
|
108
|
+
hash: text("hash"),
|
|
109
|
+
description: text("description"),
|
|
110
|
+
state: text("state").$type().notNull().default("to_scan"),
|
|
111
|
+
error: text("error"),
|
|
112
|
+
...timestamps
|
|
113
|
+
},
|
|
114
|
+
(table) => ({
|
|
115
|
+
directory_idx: index("files_directory_idx").on(table.directory_id),
|
|
116
|
+
path_idx: index("files_path_idx").on(table.path),
|
|
117
|
+
hash_idx: index("files_hash_idx").on(table.hash),
|
|
118
|
+
state_idx: index("files_state_idx").on(table.state)
|
|
119
|
+
})
|
|
120
|
+
);
|
|
121
|
+
var external_dependencies = sqliteTable(
|
|
122
|
+
"external_dependencies",
|
|
123
|
+
{
|
|
124
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
125
|
+
package: text("package").notNull(),
|
|
126
|
+
subpath: text("subpath"),
|
|
127
|
+
name: text("name"),
|
|
128
|
+
version: text("version"),
|
|
129
|
+
github_repo: text("github_repo"),
|
|
130
|
+
is_builtin: integer("is_builtin", { mode: "boolean" }).default(false).notNull(),
|
|
131
|
+
description: text("description"),
|
|
132
|
+
state: text("state").$type().notNull().default("to_describe"),
|
|
133
|
+
error: text("error"),
|
|
134
|
+
...timestamps
|
|
135
|
+
},
|
|
136
|
+
(table) => ({
|
|
137
|
+
state_idx: index("external_dependencies_state_idx").on(table.state),
|
|
138
|
+
package_subpath_name_unique: uniqueIndex("external_dependencies_package_subpath_name_unique").on(table.package, table.subpath, table.name)
|
|
139
|
+
})
|
|
140
|
+
);
|
|
141
|
+
var external_imports = sqliteTable(
|
|
142
|
+
"external_imports",
|
|
143
|
+
{
|
|
144
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
145
|
+
file_id: integer("file_id").notNull().references(() => files.id, { onDelete: "cascade" }),
|
|
146
|
+
external_dependency_id: integer("external_dependency_id").notNull().references(() => external_dependencies.id, { onDelete: "cascade" }),
|
|
147
|
+
alias: text("alias").notNull(),
|
|
148
|
+
is_dynamic: integer("is_dynamic", { mode: "boolean" }).default(false).notNull(),
|
|
149
|
+
...timestamps
|
|
150
|
+
},
|
|
151
|
+
(table) => ({
|
|
152
|
+
file_idx: index("external_imports_file_idx").on(table.file_id),
|
|
153
|
+
external_dependency_idx: index("external_imports_external_dependency_idx").on(table.external_dependency_id)
|
|
154
|
+
})
|
|
155
|
+
);
|
|
156
|
+
var imports = sqliteTable(
|
|
157
|
+
"imports",
|
|
158
|
+
{
|
|
159
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
160
|
+
exporter_file_id: integer("exporter_file_id").notNull().references(() => files.id, { onDelete: "cascade" }),
|
|
161
|
+
importer_file_id: integer("importer_file_id").notNull().references(() => files.id, { onDelete: "cascade" }),
|
|
162
|
+
symbol_id: integer("symbol_id").references(() => symbols.id, { onDelete: "set null" }),
|
|
163
|
+
name: text("name").notNull(),
|
|
164
|
+
alias: text("alias").notNull(),
|
|
165
|
+
is_dynamic: integer("is_dynamic", { mode: "boolean" }).default(false).notNull(),
|
|
166
|
+
state: text("state").$type().notNull().default("to_link"),
|
|
167
|
+
error: text("error"),
|
|
168
|
+
...timestamps
|
|
169
|
+
},
|
|
170
|
+
(table) => ({
|
|
171
|
+
exporter_file_idx: index("imports_exporter_file_idx").on(table.exporter_file_id),
|
|
172
|
+
importer_file_idx: index("imports_importer_file_idx").on(table.importer_file_id),
|
|
173
|
+
symbol_idx: index("imports_symbol_idx").on(table.symbol_id),
|
|
174
|
+
state_idx: index("imports_state_idx").on(table.state)
|
|
175
|
+
})
|
|
176
|
+
);
|
|
177
|
+
var symbols = sqliteTable(
|
|
178
|
+
"symbols",
|
|
179
|
+
{
|
|
180
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
181
|
+
file_id: integer("file_id").notNull().references(() => files.id, { onDelete: "cascade" }),
|
|
182
|
+
type: text("type").notNull(),
|
|
183
|
+
// 'function', 'class', 'variable', 'type', 'class_method', 'class_property', 'other'
|
|
184
|
+
name: text("name").notNull(),
|
|
185
|
+
text: text("text"),
|
|
186
|
+
// source code
|
|
187
|
+
meta: text("meta"),
|
|
188
|
+
// JSON details
|
|
189
|
+
description: text("description"),
|
|
190
|
+
is_exported: integer("is_exported", { mode: "boolean" }).default(false).notNull(),
|
|
191
|
+
state: text("state").$type().notNull().default("to_link"),
|
|
192
|
+
error: text("error"),
|
|
193
|
+
...timestamps
|
|
194
|
+
},
|
|
195
|
+
(table) => ({
|
|
196
|
+
file_idx: index("symbols_file_idx").on(table.file_id),
|
|
197
|
+
type_idx: index("symbols_type_idx").on(table.type),
|
|
198
|
+
name_idx: index("symbols_name_idx").on(table.name),
|
|
199
|
+
is_exported_idx: index("symbols_is_exported_idx").on(table.is_exported),
|
|
200
|
+
state_idx: index("symbols_state_idx").on(table.state)
|
|
201
|
+
})
|
|
202
|
+
);
|
|
203
|
+
var symbol_internal_links = sqliteTable(
|
|
204
|
+
"symbol_internal_links",
|
|
205
|
+
{
|
|
206
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
207
|
+
from_file_id: integer("from_file_id").notNull().references(() => files.id, { onDelete: "cascade" }),
|
|
208
|
+
to_file_id: integer("to_file_id").notNull().references(() => files.id, { onDelete: "cascade" }),
|
|
209
|
+
from_symbol_id: integer("from_symbol_id").notNull().references(() => symbols.id, { onDelete: "cascade" }),
|
|
210
|
+
to_symbol_id: integer("to_symbol_id").notNull().references(() => symbols.id, { onDelete: "cascade" }),
|
|
211
|
+
state: text("state").$type().notNull().default("pending"),
|
|
212
|
+
error: text("error"),
|
|
213
|
+
...timestamps
|
|
214
|
+
},
|
|
215
|
+
(table) => ({
|
|
216
|
+
from_file_idx: index("symbol_internal_links_from_file_idx").on(table.from_file_id),
|
|
217
|
+
to_file_idx: index("symbol_internal_links_to_file_idx").on(table.to_file_id),
|
|
218
|
+
from_symbol_idx: index("symbol_internal_links_from_symbol_idx").on(table.from_symbol_id),
|
|
219
|
+
to_symbol_idx: index("symbol_internal_links_to_symbol_idx").on(table.to_symbol_id),
|
|
220
|
+
state_idx: index("symbol_internal_links_state_idx").on(table.state)
|
|
221
|
+
})
|
|
222
|
+
);
|
|
223
|
+
var symbol_external_links = sqliteTable(
|
|
224
|
+
"symbol_external_links",
|
|
225
|
+
{
|
|
226
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
227
|
+
symbol_id: integer("symbol_id").notNull().references(() => symbols.id, { onDelete: "cascade" }),
|
|
228
|
+
external_import_id: integer("external_import_id").notNull().references(() => external_imports.id, { onDelete: "cascade" }),
|
|
229
|
+
...timestamps
|
|
230
|
+
},
|
|
231
|
+
(table) => ({
|
|
232
|
+
symbol_idx: index("symbol_external_links_symbol_idx").on(table.symbol_id),
|
|
233
|
+
external_import_idx: index("symbol_external_links_external_import_idx").on(table.external_import_id)
|
|
234
|
+
})
|
|
235
|
+
);
|
|
236
|
+
var directories_relations = relations(directories, ({ one, many }) => ({
|
|
237
|
+
parent: one(directories, {
|
|
238
|
+
fields: [directories.parent_id],
|
|
239
|
+
references: [directories.id],
|
|
240
|
+
relationName: "subdirectories"
|
|
241
|
+
}),
|
|
242
|
+
subdirectories: many(directories, {
|
|
243
|
+
relationName: "subdirectories"
|
|
244
|
+
}),
|
|
245
|
+
files: many(files)
|
|
246
|
+
}));
|
|
247
|
+
var files_relations = relations(files, ({ one, many }) => ({
|
|
248
|
+
directory: one(directories, {
|
|
249
|
+
fields: [files.directory_id],
|
|
250
|
+
references: [directories.id]
|
|
251
|
+
}),
|
|
252
|
+
external_imports: many(external_imports),
|
|
253
|
+
imports_as_exporter: many(imports, {
|
|
254
|
+
relationName: "imports_as_exporter"
|
|
255
|
+
}),
|
|
256
|
+
imports_as_importer: many(imports, {
|
|
257
|
+
relationName: "imports_as_importer"
|
|
258
|
+
}),
|
|
259
|
+
symbols: many(symbols),
|
|
260
|
+
internal_links_from: many(symbol_internal_links, {
|
|
261
|
+
relationName: "file_internal_links_from"
|
|
262
|
+
}),
|
|
263
|
+
internal_links_to: many(symbol_internal_links, {
|
|
264
|
+
relationName: "file_internal_links_to"
|
|
265
|
+
})
|
|
266
|
+
}));
|
|
267
|
+
var external_dependencies_relations = relations(external_dependencies, ({ many }) => ({
|
|
268
|
+
imports: many(external_imports),
|
|
269
|
+
symbol_external_links: many(symbol_external_links)
|
|
270
|
+
}));
|
|
271
|
+
var external_imports_relations = relations(external_imports, ({ one }) => ({
|
|
272
|
+
file: one(files, {
|
|
273
|
+
fields: [external_imports.file_id],
|
|
274
|
+
references: [files.id]
|
|
275
|
+
}),
|
|
276
|
+
external_dependency: one(external_dependencies, {
|
|
277
|
+
fields: [external_imports.external_dependency_id],
|
|
278
|
+
references: [external_dependencies.id]
|
|
279
|
+
})
|
|
280
|
+
}));
|
|
281
|
+
var imports_relations = relations(imports, ({ one }) => ({
|
|
282
|
+
exporter_file: one(files, {
|
|
283
|
+
fields: [imports.exporter_file_id],
|
|
284
|
+
references: [files.id],
|
|
285
|
+
relationName: "imports_as_exporter"
|
|
286
|
+
}),
|
|
287
|
+
importer_file: one(files, {
|
|
288
|
+
fields: [imports.importer_file_id],
|
|
289
|
+
references: [files.id],
|
|
290
|
+
relationName: "imports_as_importer"
|
|
291
|
+
}),
|
|
292
|
+
symbol: one(symbols, {
|
|
293
|
+
fields: [imports.symbol_id],
|
|
294
|
+
references: [symbols.id]
|
|
295
|
+
})
|
|
296
|
+
}));
|
|
297
|
+
var symbols_relations = relations(symbols, ({ one, many }) => ({
|
|
298
|
+
file: one(files, {
|
|
299
|
+
fields: [symbols.file_id],
|
|
300
|
+
references: [files.id]
|
|
301
|
+
}),
|
|
302
|
+
imports: many(imports),
|
|
303
|
+
internal_links_from: many(symbol_internal_links, {
|
|
304
|
+
relationName: "internal_links_from"
|
|
305
|
+
}),
|
|
306
|
+
internal_links_to: many(symbol_internal_links, {
|
|
307
|
+
relationName: "internal_links_to"
|
|
308
|
+
}),
|
|
309
|
+
external_links: many(symbol_external_links)
|
|
310
|
+
}));
|
|
311
|
+
var symbol_internal_links_relations = relations(symbol_internal_links, ({ one }) => ({
|
|
312
|
+
from_file: one(files, {
|
|
313
|
+
fields: [symbol_internal_links.from_file_id],
|
|
314
|
+
references: [files.id],
|
|
315
|
+
relationName: "file_internal_links_from"
|
|
316
|
+
}),
|
|
317
|
+
to_file: one(files, {
|
|
318
|
+
fields: [symbol_internal_links.to_file_id],
|
|
319
|
+
references: [files.id],
|
|
320
|
+
relationName: "file_internal_links_to"
|
|
321
|
+
}),
|
|
322
|
+
from_symbol: one(symbols, {
|
|
323
|
+
fields: [symbol_internal_links.from_symbol_id],
|
|
324
|
+
references: [symbols.id],
|
|
325
|
+
relationName: "internal_links_from"
|
|
326
|
+
}),
|
|
327
|
+
to_symbol: one(symbols, {
|
|
328
|
+
fields: [symbol_internal_links.to_symbol_id],
|
|
329
|
+
references: [symbols.id],
|
|
330
|
+
relationName: "internal_links_to"
|
|
331
|
+
})
|
|
332
|
+
}));
|
|
333
|
+
var symbol_external_links_relations = relations(symbol_external_links, ({ one }) => ({
|
|
334
|
+
symbol: one(symbols, {
|
|
335
|
+
fields: [symbol_external_links.symbol_id],
|
|
336
|
+
references: [symbols.id]
|
|
337
|
+
}),
|
|
338
|
+
external_import: one(external_imports, {
|
|
339
|
+
fields: [symbol_external_links.external_import_id],
|
|
340
|
+
references: [external_imports.id]
|
|
341
|
+
})
|
|
342
|
+
}));
|
|
343
|
+
|
|
344
|
+
// src/db/migrate.ts
|
|
345
|
+
async function migrate(ctx) {
|
|
346
|
+
const [migration_filenames, applied_migration_names] = await Promise.all([get_migration_filenames(ctx), get_applied_migration_names(ctx)]);
|
|
347
|
+
for (const filename of migration_filenames) {
|
|
348
|
+
if (applied_migration_names.has(filename)) continue;
|
|
349
|
+
await apply_migration(ctx, filename);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
async function get_migration_filenames({ migrations_path }) {
|
|
353
|
+
const filenames = /* @__PURE__ */ new Set();
|
|
354
|
+
for (const entry of await readdir(migrations_path, { withFileTypes: true })) {
|
|
355
|
+
if (!entry.isFile() || !entry.name.endsWith(".sql")) continue;
|
|
356
|
+
filenames.add(entry.name);
|
|
357
|
+
}
|
|
358
|
+
return filenames;
|
|
359
|
+
}
|
|
360
|
+
async function get_applied_migration_names({ db: db6 }) {
|
|
361
|
+
const res = db6.get(sql2`SELECT name FROM sqlite_master WHERE type='table' AND name='migrations'`);
|
|
362
|
+
if (!res) return /* @__PURE__ */ new Set();
|
|
363
|
+
const applied = await db6.select({ name: migrations.name }).from(migrations);
|
|
364
|
+
return new Set(applied.map((x) => x.name));
|
|
365
|
+
}
|
|
366
|
+
async function apply_migration({ sqlite, migrations_path }, filename) {
|
|
367
|
+
const file_path = join(migrations_path, filename);
|
|
368
|
+
const queries = await readFile(file_path, "utf-8");
|
|
369
|
+
sqlite.transaction(() => {
|
|
370
|
+
sqlite.exec(queries);
|
|
371
|
+
sqlite.prepare("INSERT INTO migrations (name) VALUES (?)").run(filename);
|
|
372
|
+
})();
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// src/db/configs.ts
|
|
376
|
+
var configs_exports = {};
|
|
377
|
+
__export(configs_exports, {
|
|
378
|
+
get: () => get,
|
|
379
|
+
upsert: () => upsert
|
|
380
|
+
});
|
|
381
|
+
import { eq as eq2, sql as sql3 } from "drizzle-orm";
|
|
382
|
+
|
|
383
|
+
// src/db/common.ts
|
|
384
|
+
import { eq, like, or, and, asc, desc } from "drizzle-orm";
|
|
385
|
+
function safe_query(operation, fn) {
|
|
386
|
+
return err.safe(fn, (reason, ...args) => err.new("db_error", { operation, args: args.slice(1), reason }));
|
|
387
|
+
}
|
|
388
|
+
function do_search(db6, table, options) {
|
|
389
|
+
if (!options.select.includes("id")) options.select.push("id");
|
|
390
|
+
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();
|
|
391
|
+
}
|
|
392
|
+
function fields(table, fields2) {
|
|
393
|
+
const res = {};
|
|
394
|
+
for (const field of fields2) res[field] = table[field];
|
|
395
|
+
return res;
|
|
396
|
+
}
|
|
397
|
+
function conditions(table, filters) {
|
|
398
|
+
if (!filters || Object.keys(filters).length === 0) return void 0;
|
|
399
|
+
const parts = [];
|
|
400
|
+
for (const [field, value] of Object.entries(filters)) {
|
|
401
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
402
|
+
const field_conditions = value.map((v) => condition(table, field, v));
|
|
403
|
+
parts.push(or(...field_conditions));
|
|
404
|
+
} else {
|
|
405
|
+
parts.push(condition(table, field, value));
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return and(...parts);
|
|
409
|
+
}
|
|
410
|
+
function condition(table, field, value) {
|
|
411
|
+
if (typeof value === "object" && value !== null) {
|
|
412
|
+
if ("contains" in value) return like(table[field], `%${value.contains}%`);
|
|
413
|
+
if ("starts_with" in value) return like(table[field], `${value.starts_with}%`);
|
|
414
|
+
if ("ends_with" in value) return like(table[field], `%${value.ends_with}`);
|
|
415
|
+
return eq(table[field], JSON.stringify(value));
|
|
416
|
+
}
|
|
417
|
+
return eq(table[field], value);
|
|
418
|
+
}
|
|
419
|
+
function order(table, [field, direction]) {
|
|
420
|
+
return direction === "asc" ? asc(table[field]) : desc(table[field]);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// src/db/configs.ts
|
|
424
|
+
var get = safe_query(
|
|
425
|
+
"configs.get",
|
|
426
|
+
(ctx) => ctx.db.select().from(configs).where(eq2(configs.id, 1)).get()
|
|
427
|
+
);
|
|
428
|
+
var upsert = safe_query(
|
|
429
|
+
"configs.upsert",
|
|
430
|
+
(ctx, data) => ctx.db.insert(configs).values({ id: 1, ...data }).onConflictDoUpdate({
|
|
431
|
+
target: configs.id,
|
|
432
|
+
set: { ...data, updated_at: sql3`(unixepoch())` }
|
|
433
|
+
}).run()
|
|
434
|
+
);
|
|
435
|
+
|
|
436
|
+
// src/db/files.ts
|
|
437
|
+
var files_exports = {};
|
|
438
|
+
__export(files_exports, {
|
|
439
|
+
all: () => all,
|
|
440
|
+
by_directory_path: () => by_directory_path,
|
|
441
|
+
by_id: () => by_id,
|
|
442
|
+
by_id_and_state: () => by_id_and_state,
|
|
443
|
+
by_path: () => by_path,
|
|
444
|
+
by_state: () => by_state,
|
|
445
|
+
del: () => del,
|
|
446
|
+
del_by_dir: () => del_by_dir,
|
|
447
|
+
get_directory_ids: () => get_directory_ids,
|
|
448
|
+
imported_by: () => imported_by,
|
|
449
|
+
importing: () => importing,
|
|
450
|
+
insert: () => insert,
|
|
451
|
+
search: () => search,
|
|
452
|
+
update: () => update,
|
|
453
|
+
update_many: () => update_many,
|
|
454
|
+
using_dependency: () => using_dependency
|
|
455
|
+
});
|
|
456
|
+
import { eq as eq3, and as and2, inArray, or as or2, like as like2 } from "drizzle-orm";
|
|
457
|
+
|
|
458
|
+
// src/internals/utils.ts
|
|
459
|
+
import { readFileSync } from "fs";
|
|
460
|
+
var parse_json = err.safe(JSON.parse, (reason, text2) => err.new("invalid_json", { reason, text: text2 }));
|
|
461
|
+
var read_file = err.safe(
|
|
462
|
+
(path6) => readFileSync(path6, "utf-8"),
|
|
463
|
+
(reason, path6) => err.new("could_not_read_file", { path: path6, reason })
|
|
464
|
+
);
|
|
465
|
+
function group_by_unique(items, key) {
|
|
466
|
+
const groups = {};
|
|
467
|
+
for (const item of items) {
|
|
468
|
+
groups[key(item)] = item;
|
|
469
|
+
}
|
|
470
|
+
return groups;
|
|
471
|
+
}
|
|
472
|
+
function expand({ items, get_children, get_key }) {
|
|
473
|
+
const visited = /* @__PURE__ */ new Set();
|
|
474
|
+
const result = [];
|
|
475
|
+
const queue = [...items];
|
|
476
|
+
while (queue.length > 0) {
|
|
477
|
+
const item = queue.shift();
|
|
478
|
+
const key = get_key(item);
|
|
479
|
+
if (err.any(key)) return key;
|
|
480
|
+
if (visited.has(key)) continue;
|
|
481
|
+
visited.add(key);
|
|
482
|
+
result.push(item);
|
|
483
|
+
const children2 = get_children(item);
|
|
484
|
+
if (err.any(children2)) return children2;
|
|
485
|
+
queue.push(...children2);
|
|
486
|
+
}
|
|
487
|
+
return result;
|
|
488
|
+
}
|
|
489
|
+
function uniq(items) {
|
|
490
|
+
return [...new Set(items)];
|
|
491
|
+
}
|
|
492
|
+
function merge(a, b) {
|
|
493
|
+
const res = { ...a };
|
|
494
|
+
for (const key of Object.keys(b)) {
|
|
495
|
+
if (b[key] !== void 0) res[key] = b[key];
|
|
496
|
+
}
|
|
497
|
+
return res;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// src/db/defaults.ts
|
|
501
|
+
var files2 = {
|
|
502
|
+
select: ["id", "directory_id", "path", "state", "error"],
|
|
503
|
+
order_by: ["id", "asc"],
|
|
504
|
+
limit: 20,
|
|
505
|
+
offset: 0,
|
|
506
|
+
where: {}
|
|
507
|
+
};
|
|
508
|
+
var directories2 = {
|
|
509
|
+
select: ["id", "parent_id", "path", "state", "error"],
|
|
510
|
+
order_by: ["id", "asc"],
|
|
511
|
+
limit: 20,
|
|
512
|
+
offset: 0,
|
|
513
|
+
where: {}
|
|
514
|
+
};
|
|
515
|
+
var symbols2 = {
|
|
516
|
+
select: ["id", "file_id", "type", "name", "meta", "is_exported", "state", "error"],
|
|
517
|
+
order_by: ["id", "asc"],
|
|
518
|
+
limit: 20,
|
|
519
|
+
offset: 0,
|
|
520
|
+
where: {}
|
|
521
|
+
};
|
|
522
|
+
var external_dependencies2 = {
|
|
523
|
+
select: ["id", "package", "subpath", "name", "state", "error"],
|
|
524
|
+
order_by: ["id", "asc"],
|
|
525
|
+
limit: 20,
|
|
526
|
+
offset: 0,
|
|
527
|
+
where: {}
|
|
528
|
+
};
|
|
529
|
+
|
|
530
|
+
// src/db/files.ts
|
|
531
|
+
var default_select_fields = ["id", "directory_id", "path", "state", "error"];
|
|
532
|
+
var all = safe_query("files.all", (ctx) => ctx.db.select().from(files).all());
|
|
533
|
+
var search = safe_query("files.search", (ctx, options = {}) => {
|
|
534
|
+
return do_search(ctx.db, files, merge(files2, options));
|
|
535
|
+
});
|
|
536
|
+
var by_id = safe_query("files.by_id", (ctx, id) => ctx.db.select().from(files).where(eq3(files.id, id)).get());
|
|
537
|
+
var by_path = safe_query(
|
|
538
|
+
"files.by_path",
|
|
539
|
+
(ctx, path6) => ctx.db.select().from(files).where(eq3(files.path, path6)).get()
|
|
540
|
+
);
|
|
541
|
+
var by_state = safe_query(
|
|
542
|
+
"files.by_state",
|
|
543
|
+
(ctx, state) => ctx.db.select().from(files).where(eq3(files.state, state)).all()
|
|
544
|
+
);
|
|
545
|
+
var insert = safe_query("files.insert", (ctx, values) => ctx.db.insert(files).values(values).run());
|
|
546
|
+
var update = safe_query(
|
|
547
|
+
"files.update",
|
|
548
|
+
(ctx, file_id, values) => ctx.db.update(files).set(values).where(eq3(files.id, file_id)).run()
|
|
549
|
+
);
|
|
550
|
+
var update_many = safe_query(
|
|
551
|
+
"files.update_many",
|
|
552
|
+
(ctx, file_ids, values) => ctx.db.update(files).set(values).where(inArray(files.id, file_ids)).run()
|
|
553
|
+
);
|
|
554
|
+
var by_id_and_state = safe_query(
|
|
555
|
+
"files.by_id_and_state",
|
|
556
|
+
(ctx, params) => ctx.db.select().from(files).where(and2(eq3(files.id, params.id), eq3(files.state, params.state))).get()
|
|
557
|
+
);
|
|
558
|
+
var del = safe_query("files.delete", (ctx, file_id) => ctx.db.delete(files).where(eq3(files.id, file_id)).run());
|
|
559
|
+
var del_by_dir = safe_query(
|
|
560
|
+
"files.delete_by_dir",
|
|
561
|
+
(ctx, directory_id) => ctx.db.delete(files).where(eq3(files.directory_id, directory_id)).run()
|
|
562
|
+
);
|
|
563
|
+
var get_directory_ids = safe_query(
|
|
564
|
+
"files.get_directory_ids",
|
|
565
|
+
(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)
|
|
566
|
+
);
|
|
567
|
+
var by_directory_path = safe_query("files.by_directory_path", (ctx, dir_path, recursive = false) => {
|
|
568
|
+
let dir_ids;
|
|
569
|
+
if (recursive) {
|
|
570
|
+
if (dir_path === "/") {
|
|
571
|
+
dir_ids = ctx.db.select({ id: directories.id }).from(directories).all().map((d) => d.id);
|
|
572
|
+
} else {
|
|
573
|
+
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);
|
|
574
|
+
}
|
|
575
|
+
} else {
|
|
576
|
+
const dir = ctx.db.select({ id: directories.id }).from(directories).where(eq3(directories.path, dir_path)).get();
|
|
577
|
+
dir_ids = dir ? [dir.id] : [];
|
|
578
|
+
}
|
|
579
|
+
if (dir_ids.length === 0) return [];
|
|
580
|
+
return ctx.db.select().from(files).where(inArray(files.directory_id, dir_ids)).all();
|
|
581
|
+
});
|
|
582
|
+
var using_dependency = safe_query(
|
|
583
|
+
"files.using_dependency",
|
|
584
|
+
(ctx, external_dependency_id, fields_to_select = default_select_fields) => {
|
|
585
|
+
if (!fields_to_select.includes("id")) fields_to_select.push("id");
|
|
586
|
+
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();
|
|
587
|
+
const file_ids = uniq(imports2.map((i) => i.file_id));
|
|
588
|
+
if (file_ids.length === 0) return [];
|
|
589
|
+
return ctx.db.select(fields(files, fields_to_select)).from(files).where(inArray(files.id, file_ids)).all();
|
|
590
|
+
}
|
|
591
|
+
);
|
|
592
|
+
var imported_by = safe_query(
|
|
593
|
+
"files.imported_by",
|
|
594
|
+
(ctx, file_id, fields_to_select = default_select_fields) => {
|
|
595
|
+
if (!fields_to_select.includes("id")) fields_to_select.push("id");
|
|
596
|
+
const import_rows = ctx.db.select({ id: imports.exporter_file_id }).from(imports).where(eq3(imports.importer_file_id, file_id)).all();
|
|
597
|
+
const file_ids = uniq(import_rows.map((i) => i.id));
|
|
598
|
+
if (file_ids.length === 0) return [];
|
|
599
|
+
return ctx.db.select(fields(files, fields_to_select)).from(files).where(inArray(files.id, file_ids)).all();
|
|
600
|
+
}
|
|
601
|
+
);
|
|
602
|
+
var importing = safe_query(
|
|
603
|
+
"files.importing",
|
|
604
|
+
(ctx, file_id, fields_to_select = default_select_fields) => {
|
|
605
|
+
if (!fields_to_select.includes("id")) fields_to_select.push("id");
|
|
606
|
+
const import_records = ctx.db.select({ importer_file_id: imports.importer_file_id }).from(imports).where(eq3(imports.exporter_file_id, file_id)).all();
|
|
607
|
+
const file_ids = uniq(import_records.map((i) => i.importer_file_id));
|
|
608
|
+
if (file_ids.length === 0) return [];
|
|
609
|
+
return ctx.db.select(fields(files, fields_to_select)).from(files).where(inArray(files.id, file_ids)).all();
|
|
610
|
+
}
|
|
611
|
+
);
|
|
612
|
+
|
|
613
|
+
// src/db/directories.ts
|
|
614
|
+
var directories_exports = {};
|
|
615
|
+
__export(directories_exports, {
|
|
616
|
+
by_id: () => by_id2,
|
|
617
|
+
by_id_and_state: () => by_id_and_state2,
|
|
618
|
+
by_path: () => by_path2,
|
|
619
|
+
by_state: () => by_state2,
|
|
620
|
+
insert: () => insert2,
|
|
621
|
+
search: () => search2,
|
|
622
|
+
update: () => update2,
|
|
623
|
+
update_many: () => update_many2
|
|
624
|
+
});
|
|
625
|
+
import { eq as eq4, and as and3, inArray as inArray2 } from "drizzle-orm";
|
|
626
|
+
var by_id2 = safe_query(
|
|
627
|
+
"directories.by_id",
|
|
628
|
+
(ctx, id) => ctx.db.select().from(directories).where(eq4(directories.id, id)).get()
|
|
629
|
+
);
|
|
630
|
+
var by_path2 = safe_query(
|
|
631
|
+
"directories.by_path",
|
|
632
|
+
(ctx, path6) => ctx.db.select().from(directories).where(eq4(directories.path, path6)).get()
|
|
633
|
+
);
|
|
634
|
+
var by_state2 = safe_query(
|
|
635
|
+
"directories.by_state",
|
|
636
|
+
(ctx, state) => ctx.db.select().from(directories).where(eq4(directories.state, state)).all()
|
|
637
|
+
);
|
|
638
|
+
var insert2 = safe_query(
|
|
639
|
+
"directories.insert",
|
|
640
|
+
(ctx, values) => ctx.db.insert(directories).values(values).returning().get()
|
|
641
|
+
);
|
|
642
|
+
var update2 = safe_query(
|
|
643
|
+
"directories.update",
|
|
644
|
+
(ctx, id, values) => ctx.db.update(directories).set(values).where(eq4(directories.id, id)).run()
|
|
645
|
+
);
|
|
646
|
+
var update_many2 = safe_query(
|
|
647
|
+
"directories.update_many",
|
|
648
|
+
(ctx, ids, values) => ctx.db.update(directories).set(values).where(inArray2(directories.id, ids)).run()
|
|
649
|
+
);
|
|
650
|
+
var by_id_and_state2 = safe_query(
|
|
651
|
+
"directories.by_id_and_state",
|
|
652
|
+
(ctx, params) => ctx.db.select().from(directories).where(and3(eq4(directories.id, params.id), eq4(directories.state, params.state))).get()
|
|
653
|
+
);
|
|
654
|
+
var search2 = safe_query("directories.search", (ctx, options = {}) => {
|
|
655
|
+
return do_search(ctx.db, directories, merge(directories2, options));
|
|
656
|
+
});
|
|
657
|
+
|
|
658
|
+
// src/db/imports.ts
|
|
659
|
+
var imports_exports = {};
|
|
660
|
+
__export(imports_exports, {
|
|
661
|
+
by_exporter_file: () => by_exporter_file,
|
|
662
|
+
by_importer_file: () => by_importer_file,
|
|
663
|
+
by_state: () => by_state3,
|
|
664
|
+
del_by_importer_file: () => del_by_importer_file,
|
|
665
|
+
insert_many: () => insert_many,
|
|
666
|
+
update: () => update3
|
|
667
|
+
});
|
|
668
|
+
import { eq as eq5 } from "drizzle-orm";
|
|
669
|
+
var by_exporter_file = safe_query(
|
|
670
|
+
"imports.by_exporter_file",
|
|
671
|
+
(ctx, exporter_file_id) => ctx.db.select().from(imports).where(eq5(imports.exporter_file_id, exporter_file_id)).all()
|
|
672
|
+
);
|
|
673
|
+
var by_importer_file = safe_query(
|
|
674
|
+
"imports.by_importer_file",
|
|
675
|
+
(ctx, importer_file_id) => ctx.db.select().from(imports).where(eq5(imports.importer_file_id, importer_file_id)).all()
|
|
676
|
+
);
|
|
677
|
+
var insert_many = safe_query("imports.insert_many", (ctx, values) => ctx.db.insert(imports).values(values).run());
|
|
678
|
+
var del_by_importer_file = safe_query(
|
|
679
|
+
"imports.del_by_importer_file",
|
|
680
|
+
(ctx, file_id) => ctx.db.delete(imports).where(eq5(imports.importer_file_id, file_id)).run()
|
|
681
|
+
);
|
|
682
|
+
var by_state3 = safe_query(
|
|
683
|
+
"imports.by_state",
|
|
684
|
+
(ctx, state) => ctx.db.select().from(imports).where(eq5(imports.state, state)).all()
|
|
685
|
+
);
|
|
686
|
+
var update3 = safe_query(
|
|
687
|
+
"imports.update",
|
|
688
|
+
(ctx, id, data) => ctx.db.update(imports).set(data).where(eq5(imports.id, id)).run()
|
|
689
|
+
);
|
|
690
|
+
|
|
691
|
+
// src/db/symbols.ts
|
|
692
|
+
var symbols_exports = {};
|
|
693
|
+
__export(symbols_exports, {
|
|
694
|
+
by_file: () => by_file,
|
|
695
|
+
by_file_and_name: () => by_file_and_name,
|
|
696
|
+
by_id: () => by_id3,
|
|
697
|
+
by_id_and_state: () => by_id_and_state3,
|
|
698
|
+
by_state: () => by_state4,
|
|
699
|
+
del_by_file: () => del_by_file,
|
|
700
|
+
insert_many: () => insert_many2,
|
|
701
|
+
meta: () => meta,
|
|
702
|
+
referenced_by: () => referenced_by,
|
|
703
|
+
referencing: () => referencing,
|
|
704
|
+
search: () => search3,
|
|
705
|
+
update: () => update4,
|
|
706
|
+
using_dependency: () => using_dependency2
|
|
707
|
+
});
|
|
708
|
+
import { eq as eq6, and as and4, inArray as inArray3 } from "drizzle-orm";
|
|
709
|
+
var insert_many2 = safe_query("symbols.insert_many", (ctx, values) => ctx.db.insert(symbols).values(values).run());
|
|
710
|
+
var del_by_file = safe_query(
|
|
711
|
+
"symbols.delete_by_file",
|
|
712
|
+
(ctx, file_id) => ctx.db.delete(symbols).where(eq6(symbols.file_id, file_id)).run()
|
|
713
|
+
);
|
|
714
|
+
var by_file_and_name = safe_query(
|
|
715
|
+
"symbols.by_file_and_name",
|
|
716
|
+
(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()
|
|
717
|
+
);
|
|
718
|
+
var by_state4 = safe_query(
|
|
719
|
+
"symbols.by_state",
|
|
720
|
+
(ctx, state) => ctx.db.select().from(symbols).where(eq6(symbols.state, state)).all()
|
|
721
|
+
);
|
|
722
|
+
var by_file = safe_query(
|
|
723
|
+
"symbols.by_file",
|
|
724
|
+
(ctx, file_id) => ctx.db.select().from(symbols).where(eq6(symbols.file_id, file_id)).all()
|
|
725
|
+
);
|
|
726
|
+
var update4 = safe_query(
|
|
727
|
+
"symbols.update",
|
|
728
|
+
(ctx, id, data) => ctx.db.update(symbols).set(data).where(eq6(symbols.id, id)).run()
|
|
729
|
+
);
|
|
730
|
+
var by_id3 = safe_query("symbols.by_id", (ctx, id) => ctx.db.select().from(symbols).where(eq6(symbols.id, id)).get());
|
|
731
|
+
var by_id_and_state3 = safe_query(
|
|
732
|
+
"symbols.by_id_and_state",
|
|
733
|
+
(ctx, params) => ctx.db.select().from(symbols).where(and4(eq6(symbols.id, params.id), eq6(symbols.state, params.state))).get()
|
|
734
|
+
);
|
|
735
|
+
function meta(symbol) {
|
|
736
|
+
return err.catch(
|
|
737
|
+
() => JSON.parse(symbol.meta),
|
|
738
|
+
(reason) => err.new("symbol_meta_parse_error", { reason, symbol_id: symbol.id, meta: symbol.meta })
|
|
739
|
+
);
|
|
740
|
+
}
|
|
741
|
+
var search3 = safe_query("symbols.search", (ctx, options = {}) => {
|
|
742
|
+
return do_search(ctx.db, symbols, merge(symbols2, options));
|
|
743
|
+
});
|
|
744
|
+
var referenced_by = safe_query(
|
|
745
|
+
"symbols.referenced_by",
|
|
746
|
+
(ctx, symbol_id, fields_to_select = symbols2.select) => {
|
|
747
|
+
if (!fields_to_select.includes("id")) fields_to_select.push("id");
|
|
748
|
+
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();
|
|
749
|
+
const symbol_ids = uniq(link_records.map((i) => i.id).filter((id) => id !== null));
|
|
750
|
+
if (symbol_ids.length === 0) return [];
|
|
751
|
+
return ctx.db.select(fields(symbols, fields_to_select)).from(symbols).where(inArray3(symbols.id, symbol_ids)).all();
|
|
752
|
+
}
|
|
753
|
+
);
|
|
754
|
+
var referencing = safe_query(
|
|
755
|
+
"symbols.referencing",
|
|
756
|
+
(ctx, symbol_id, fields_to_select = symbols2.select) => {
|
|
757
|
+
if (!fields_to_select.includes("id")) fields_to_select.push("id");
|
|
758
|
+
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();
|
|
759
|
+
const symbol_ids = uniq(link_records.map((i) => i.id).filter((id) => id !== null));
|
|
760
|
+
if (symbol_ids.length === 0) return [];
|
|
761
|
+
return ctx.db.select(fields(symbols, fields_to_select)).from(symbols).where(inArray3(symbols.id, symbol_ids)).all();
|
|
762
|
+
}
|
|
763
|
+
);
|
|
764
|
+
var using_dependency2 = safe_query(
|
|
765
|
+
"symbols.using_dependency",
|
|
766
|
+
(ctx, dependency_id, fields_to_select = symbols2.select) => {
|
|
767
|
+
if (!fields_to_select.includes("id")) fields_to_select.push("id");
|
|
768
|
+
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();
|
|
769
|
+
const symbol_ids = uniq(link_records.map((i) => i.symbol_id));
|
|
770
|
+
if (symbol_ids.length === 0) return [];
|
|
771
|
+
return ctx.db.select(fields(symbols, fields_to_select)).from(symbols).where(inArray3(symbols.id, symbol_ids)).all();
|
|
772
|
+
}
|
|
773
|
+
);
|
|
774
|
+
|
|
775
|
+
// src/db/external_dependencies.ts
|
|
776
|
+
var external_dependencies_exports = {};
|
|
777
|
+
__export(external_dependencies_exports, {
|
|
778
|
+
all: () => all2,
|
|
779
|
+
by_id: () => by_id4,
|
|
780
|
+
by_package_subpath_and_name: () => by_package_subpath_and_name,
|
|
781
|
+
by_state: () => by_state5,
|
|
782
|
+
get_or_create: () => get_or_create,
|
|
783
|
+
insert: () => insert3,
|
|
784
|
+
search: () => search4,
|
|
785
|
+
update: () => update5,
|
|
786
|
+
used_by_file: () => used_by_file,
|
|
787
|
+
used_by_symbol: () => used_by_symbol
|
|
788
|
+
});
|
|
789
|
+
import { eq as eq7, and as and5, sql as sql4, inArray as inArray4 } from "drizzle-orm";
|
|
790
|
+
var by_id4 = safe_query(
|
|
791
|
+
"external_dependencies.by_id",
|
|
792
|
+
(ctx, id) => ctx.db.select().from(external_dependencies).where(eq7(external_dependencies.id, id)).get()
|
|
793
|
+
);
|
|
794
|
+
var by_state5 = safe_query(
|
|
795
|
+
"external_dependencies.by_state",
|
|
796
|
+
(ctx, state) => ctx.db.select().from(external_dependencies).where(eq7(external_dependencies.state, state)).all()
|
|
797
|
+
);
|
|
798
|
+
var by_package_subpath_and_name = safe_query(
|
|
799
|
+
"external_dependencies.by_package_subpath_and_name",
|
|
800
|
+
(ctx, params) => ctx.db.select().from(external_dependencies).where(
|
|
801
|
+
and5(
|
|
802
|
+
eq7(external_dependencies.package, params.package),
|
|
803
|
+
params.subpath === null ? sql4`${external_dependencies.subpath} IS NULL` : eq7(external_dependencies.subpath, params.subpath),
|
|
804
|
+
params.name === null ? sql4`${external_dependencies.name} IS NULL` : eq7(external_dependencies.name, params.name)
|
|
805
|
+
)
|
|
806
|
+
).get()
|
|
807
|
+
);
|
|
808
|
+
var insert3 = safe_query(
|
|
809
|
+
"external_dependencies.insert",
|
|
810
|
+
(ctx, value) => ctx.db.insert(external_dependencies).values(value).returning().get()
|
|
811
|
+
);
|
|
812
|
+
var update5 = safe_query(
|
|
813
|
+
"external_dependencies.update",
|
|
814
|
+
(ctx, id, data) => ctx.db.update(external_dependencies).set(data).where(eq7(external_dependencies.id, id)).run()
|
|
815
|
+
);
|
|
816
|
+
var all2 = safe_query("external_dependencies.all", (ctx) => ctx.db.select().from(external_dependencies).all());
|
|
817
|
+
function get_or_create(ctx, value) {
|
|
818
|
+
return err.pipe(
|
|
819
|
+
() => by_package_subpath_and_name(ctx, { package: value.package, subpath: value.subpath ?? null, name: value.name ?? null }),
|
|
820
|
+
(existing) => existing || insert3(ctx, value)
|
|
821
|
+
);
|
|
822
|
+
}
|
|
823
|
+
var search4 = safe_query(
|
|
824
|
+
"external_dependencies.search",
|
|
825
|
+
(ctx, options = {}) => {
|
|
826
|
+
return do_search(ctx.db, external_dependencies, merge(external_dependencies2, options));
|
|
827
|
+
}
|
|
828
|
+
);
|
|
829
|
+
var used_by_file = safe_query(
|
|
830
|
+
"external_dependencies.used_by_file",
|
|
831
|
+
(ctx, file_id, fields_to_select = external_dependencies2.select) => {
|
|
832
|
+
if (!fields_to_select.includes("id")) fields_to_select.push("id");
|
|
833
|
+
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();
|
|
834
|
+
const dependency_ids = uniq(imports_records.map((r) => r.external_dependency_id));
|
|
835
|
+
if (dependency_ids.length === 0) return [];
|
|
836
|
+
return ctx.db.select(fields(external_dependencies, fields_to_select)).from(external_dependencies).where(inArray4(external_dependencies.id, dependency_ids)).all();
|
|
837
|
+
}
|
|
838
|
+
);
|
|
839
|
+
var used_by_symbol = safe_query(
|
|
840
|
+
"external_dependencies.used_by_symbol",
|
|
841
|
+
(ctx, symbol_id, fields_to_select = external_dependencies2.select) => {
|
|
842
|
+
if (!fields_to_select.includes("id")) fields_to_select.push("id");
|
|
843
|
+
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();
|
|
844
|
+
if (link_records.length === 0) return [];
|
|
845
|
+
const external_import_ids = uniq(link_records.map((r) => r.external_import_id));
|
|
846
|
+
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();
|
|
847
|
+
const dependency_ids = uniq(imports_records.map((r) => r.external_dependency_id));
|
|
848
|
+
if (dependency_ids.length === 0) return [];
|
|
849
|
+
return ctx.db.select(fields(external_dependencies, fields_to_select)).from(external_dependencies).where(inArray4(external_dependencies.id, dependency_ids)).all();
|
|
850
|
+
}
|
|
851
|
+
);
|
|
852
|
+
|
|
853
|
+
// src/db/external_imports.ts
|
|
854
|
+
var external_imports_exports = {};
|
|
855
|
+
__export(external_imports_exports, {
|
|
856
|
+
by_external_dependency: () => by_external_dependency,
|
|
857
|
+
by_file: () => by_file2,
|
|
858
|
+
by_symbol: () => by_symbol,
|
|
859
|
+
del_by_file: () => del_by_file2,
|
|
860
|
+
insert_many: () => insert_many3
|
|
861
|
+
});
|
|
862
|
+
import { eq as eq8 } from "drizzle-orm";
|
|
863
|
+
var insert_many3 = safe_query(
|
|
864
|
+
"external_imports.insert_many",
|
|
865
|
+
(ctx, values) => ctx.db.insert(external_imports).values(values).run()
|
|
866
|
+
);
|
|
867
|
+
var del_by_file2 = safe_query(
|
|
868
|
+
"external_imports.delete_by_file",
|
|
869
|
+
(ctx, file_id) => ctx.db.delete(external_imports).where(eq8(external_imports.file_id, file_id)).run()
|
|
870
|
+
);
|
|
871
|
+
var by_file2 = safe_query(
|
|
872
|
+
"external_imports.by_file",
|
|
873
|
+
(ctx, file_id) => ctx.db.select().from(external_imports).where(eq8(external_imports.file_id, file_id)).all()
|
|
874
|
+
);
|
|
875
|
+
var by_external_dependency = safe_query(
|
|
876
|
+
"external_imports.by_external_dependency",
|
|
877
|
+
(ctx, external_dependency_id) => ctx.db.select().from(external_imports).where(eq8(external_imports.external_dependency_id, external_dependency_id)).all()
|
|
878
|
+
);
|
|
879
|
+
var by_symbol = safe_query(
|
|
880
|
+
"external_imports.by_symbol",
|
|
881
|
+
(ctx, symbol_id) => ctx.db.query.symbol_external_links.findMany({
|
|
882
|
+
where: eq8(symbol_external_links.symbol_id, symbol_id),
|
|
883
|
+
with: {
|
|
884
|
+
external_import: {
|
|
885
|
+
with: {
|
|
886
|
+
external_dependency: true
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
})
|
|
891
|
+
);
|
|
892
|
+
|
|
893
|
+
// src/db/symbol_internal_links.ts
|
|
894
|
+
var symbol_internal_links_exports = {};
|
|
895
|
+
__export(symbol_internal_links_exports, {
|
|
896
|
+
by_from_symbol: () => by_from_symbol,
|
|
897
|
+
del_by_from_symbol: () => del_by_from_symbol,
|
|
898
|
+
exists: () => exists,
|
|
899
|
+
insert: () => insert4
|
|
900
|
+
});
|
|
901
|
+
import { and as and6, eq as eq9 } from "drizzle-orm";
|
|
902
|
+
var by_from_symbol = safe_query(
|
|
903
|
+
"symbol_internal_links.by_from_symbol",
|
|
904
|
+
(ctx, from_symbol_id) => ctx.db.query.symbol_internal_links.findMany({
|
|
905
|
+
where: eq9(symbol_internal_links.from_symbol_id, from_symbol_id),
|
|
906
|
+
with: {
|
|
907
|
+
to_symbol: {
|
|
908
|
+
with: {
|
|
909
|
+
file: true
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
})
|
|
914
|
+
);
|
|
915
|
+
var insert4 = safe_query(
|
|
916
|
+
"symbol_internal_links.insert",
|
|
917
|
+
(ctx, value) => ctx.db.insert(symbol_internal_links).values(value).run()
|
|
918
|
+
);
|
|
919
|
+
var exists = safe_query(
|
|
920
|
+
"symbol_internal_links.exists",
|
|
921
|
+
(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()
|
|
922
|
+
);
|
|
923
|
+
var del_by_from_symbol = safe_query(
|
|
924
|
+
"symbol_internal_links.del_by_from_symbol",
|
|
925
|
+
(ctx, from_symbol_id) => ctx.db.delete(symbol_internal_links).where(eq9(symbol_internal_links.from_symbol_id, from_symbol_id)).run()
|
|
926
|
+
);
|
|
927
|
+
|
|
928
|
+
// src/db/symbol_external_links.ts
|
|
929
|
+
var symbol_external_links_exports = {};
|
|
930
|
+
__export(symbol_external_links_exports, {
|
|
931
|
+
by_external_import: () => by_external_import,
|
|
932
|
+
by_symbol: () => by_symbol2,
|
|
933
|
+
del_by_symbol: () => del_by_symbol,
|
|
934
|
+
exists: () => exists2,
|
|
935
|
+
insert: () => insert5
|
|
936
|
+
});
|
|
937
|
+
import { and as and7, eq as eq10 } from "drizzle-orm";
|
|
938
|
+
var by_symbol2 = safe_query(
|
|
939
|
+
"symbol_external_links.by_symbol",
|
|
940
|
+
(ctx, symbol_id) => ctx.db.select().from(symbol_external_links).where(eq10(symbol_external_links.symbol_id, symbol_id)).all()
|
|
941
|
+
);
|
|
942
|
+
var insert5 = safe_query(
|
|
943
|
+
"symbol_external_links.insert",
|
|
944
|
+
(ctx, value) => ctx.db.insert(symbol_external_links).values(value).run()
|
|
945
|
+
);
|
|
946
|
+
var by_external_import = safe_query(
|
|
947
|
+
"symbol_external_links.by_external_import",
|
|
948
|
+
(ctx, external_import_id) => ctx.db.select().from(symbol_external_links).where(eq10(symbol_external_links.external_import_id, external_import_id)).all()
|
|
949
|
+
);
|
|
950
|
+
var exists2 = safe_query(
|
|
951
|
+
"symbol_external_links.exists",
|
|
952
|
+
(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()
|
|
953
|
+
);
|
|
954
|
+
var del_by_symbol = safe_query(
|
|
955
|
+
"symbol_external_links.del_by_symbol",
|
|
956
|
+
(ctx, symbol_id) => ctx.db.delete(symbol_external_links).where(eq10(symbol_external_links.symbol_id, symbol_id)).run()
|
|
957
|
+
);
|
|
958
|
+
|
|
959
|
+
// src/internals/context.ts
|
|
960
|
+
async function create_context(sqlite, db6, config) {
|
|
961
|
+
const project_path = path.resolve(config.project_path);
|
|
962
|
+
const currentDir = dirname(fileURLToPath(import.meta.url));
|
|
963
|
+
const migrations_path = currentDir.includes("/dist") ? join2(currentDir, "../migrations") : join2(currentDir, "../../migrations");
|
|
964
|
+
const tsconfig_path = join2(project_path, "tsconfig.json");
|
|
965
|
+
if (!ts.sys.fileExists(tsconfig_path)) {
|
|
966
|
+
throw err.new("file_not_found", { path: tsconfig_path });
|
|
967
|
+
}
|
|
968
|
+
const tsconfig = ts.parseJsonConfigFileContent(ts.readConfigFile(tsconfig_path, ts.sys.readFile).config, ts.sys, project_path);
|
|
969
|
+
const program = ts.createProgram({ rootNames: tsconfig.fileNames, options: tsconfig.options });
|
|
970
|
+
const package_json_path = config.package_json_path ?? path.join(project_path, "package.json");
|
|
971
|
+
const node_modules_paths = config.node_modules_paths ?? [path.join(project_path, "node_modules")];
|
|
972
|
+
const dependencies = await get_dependencies(package_json_path, node_modules_paths);
|
|
973
|
+
const ctx = { db: db6, sqlite, migrations_path, project_path, program, dependencies };
|
|
974
|
+
await migrate(ctx);
|
|
975
|
+
err.or_throw(
|
|
976
|
+
configs_exports.upsert(ctx, {
|
|
977
|
+
project_path,
|
|
978
|
+
description: config.description ?? null,
|
|
979
|
+
package_json_path: config.package_json_path ?? null,
|
|
980
|
+
node_modules_paths: config.node_modules_paths ? JSON.stringify(config.node_modules_paths) : null
|
|
981
|
+
})
|
|
982
|
+
);
|
|
983
|
+
return ctx;
|
|
984
|
+
}
|
|
985
|
+
async function context_from_config(config) {
|
|
986
|
+
const sqlite = new Database(config.db_path);
|
|
987
|
+
sqlite.pragma("foreign_keys = ON");
|
|
988
|
+
const db6 = drizzle(sqlite, { schema: schema_exports });
|
|
989
|
+
return create_context(sqlite, db6, config);
|
|
990
|
+
}
|
|
991
|
+
async function context_from_db(db_path) {
|
|
992
|
+
const sqlite = new Database(db_path);
|
|
993
|
+
sqlite.pragma("foreign_keys = ON");
|
|
994
|
+
const db6 = drizzle(sqlite, { schema: schema_exports });
|
|
995
|
+
const temp_ctx = { db: db6, sqlite };
|
|
996
|
+
const stored = err.or_throw(configs_exports.get(temp_ctx));
|
|
997
|
+
if (!stored) {
|
|
998
|
+
sqlite.close();
|
|
999
|
+
throw err.new("config_not_found", { db_path });
|
|
1000
|
+
}
|
|
1001
|
+
let node_modules_paths;
|
|
1002
|
+
if (stored.node_modules_paths) {
|
|
1003
|
+
try {
|
|
1004
|
+
node_modules_paths = JSON.parse(stored.node_modules_paths);
|
|
1005
|
+
} catch (parse_error) {
|
|
1006
|
+
sqlite.close();
|
|
1007
|
+
throw err.new("config_invalid_node_modules_paths", { db_path, reason: parse_error });
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
return create_context(sqlite, db6, {
|
|
1011
|
+
db_path,
|
|
1012
|
+
project_path: stored.project_path,
|
|
1013
|
+
description: stored.description ?? void 0,
|
|
1014
|
+
package_json_path: stored.package_json_path ?? void 0,
|
|
1015
|
+
node_modules_paths
|
|
1016
|
+
});
|
|
1017
|
+
}
|
|
1018
|
+
async function get_dependencies(package_json_path, node_modules_paths) {
|
|
1019
|
+
const dependencies = {};
|
|
1020
|
+
const package_json = JSON.parse(await readFile2(package_json_path, "utf-8"));
|
|
1021
|
+
const packages = { ...package_json.dependencies ?? {}, ...package_json.devDependencies ?? {} };
|
|
1022
|
+
for (const [name, version] of Object.entries(packages)) {
|
|
1023
|
+
dependencies[name] = { name, version, github_repo: await get_github_repo(node_modules_paths, name) };
|
|
1024
|
+
}
|
|
1025
|
+
return dependencies;
|
|
1026
|
+
}
|
|
1027
|
+
async function get_github_repo(node_modules_paths, package_name) {
|
|
1028
|
+
for (const node_modules_path of node_modules_paths) {
|
|
1029
|
+
try {
|
|
1030
|
+
const package_json_path = path.join(node_modules_path, package_name, "package.json");
|
|
1031
|
+
const package_json = JSON.parse(await readFile2(package_json_path, "utf-8"));
|
|
1032
|
+
const url = package_json.repository?.url || package_json.repository;
|
|
1033
|
+
if (typeof url === "string") {
|
|
1034
|
+
let repo = url.split("/").slice(-2).join("/");
|
|
1035
|
+
if (repo.endsWith(".git")) repo = repo.slice(0, -4);
|
|
1036
|
+
return repo.split(":").pop();
|
|
1037
|
+
}
|
|
1038
|
+
} catch {
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
return void 0;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
// src/update/track_changes.ts
|
|
1045
|
+
import path2 from "path";
|
|
1046
|
+
import "typescript";
|
|
1047
|
+
import { stat } from "fs/promises";
|
|
1048
|
+
|
|
1049
|
+
// src/update/events.ts
|
|
1050
|
+
function file_updated(ctx, file_id) {
|
|
1051
|
+
const impacted_files_ids = err.or_throw(
|
|
1052
|
+
expand({
|
|
1053
|
+
items: [file_id],
|
|
1054
|
+
get_key: (id) => id,
|
|
1055
|
+
get_children: (id) => {
|
|
1056
|
+
const imports2 = imports_exports.by_exporter_file(ctx, id);
|
|
1057
|
+
if (err.any(imports2)) return imports2;
|
|
1058
|
+
return imports2.map((x) => x.importer_file_id);
|
|
1059
|
+
}
|
|
1060
|
+
})
|
|
1061
|
+
);
|
|
1062
|
+
const dir_ids = err.or_throw(files_exports.get_directory_ids(ctx, impacted_files_ids));
|
|
1063
|
+
const impacted_dirs_ids = err.or_throw(
|
|
1064
|
+
expand({
|
|
1065
|
+
items: dir_ids,
|
|
1066
|
+
get_key: (id) => id,
|
|
1067
|
+
get_children: (id) => {
|
|
1068
|
+
const dir = directories_exports.by_id(ctx, id);
|
|
1069
|
+
if (err.any(dir)) return dir;
|
|
1070
|
+
return dir?.parent_id ? [dir.parent_id] : [];
|
|
1071
|
+
}
|
|
1072
|
+
})
|
|
1073
|
+
);
|
|
1074
|
+
err.or_throw(files_exports.update_many(ctx, impacted_files_ids, { state: "to_scan" }));
|
|
1075
|
+
err.or_throw(directories_exports.update_many(ctx, impacted_dirs_ids, { state: "to_describe" }));
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
// src/update/track_changes.ts
|
|
1079
|
+
async function track_changes(ctx) {
|
|
1080
|
+
const db_files = err.or_throw(files_exports.all(ctx));
|
|
1081
|
+
const { created, updated, deleted } = await changes(ctx, get_source_files(ctx), db_files);
|
|
1082
|
+
for (const { source_file, hash } of created) handle_new_source_file(ctx, source_file, hash);
|
|
1083
|
+
for (const { db_file, hash } of updated) handle_changed_source_file(ctx, db_file, hash);
|
|
1084
|
+
for (const { db_file } of deleted) handle_deleted_source_file(ctx, db_file);
|
|
1085
|
+
}
|
|
1086
|
+
function get_source_files(ctx) {
|
|
1087
|
+
const src_files = [];
|
|
1088
|
+
for (const file of ctx.program.getSourceFiles()) {
|
|
1089
|
+
if (ctx.program.isSourceFileDefaultLibrary(file)) continue;
|
|
1090
|
+
if (ctx.program.isSourceFileFromExternalLibrary(file)) continue;
|
|
1091
|
+
if (!path2.resolve(file.fileName).startsWith(ctx.project_path)) continue;
|
|
1092
|
+
src_files.push(file);
|
|
1093
|
+
}
|
|
1094
|
+
return src_files;
|
|
1095
|
+
}
|
|
1096
|
+
function handle_new_source_file(ctx, file, hash) {
|
|
1097
|
+
const file_path = err.or_throw(get_file_path(ctx, file));
|
|
1098
|
+
const dirs_paths = err.or_throw(get_parents_paths(ctx, file));
|
|
1099
|
+
let parent_dir_id = null;
|
|
1100
|
+
for (const dir_path of dirs_paths) {
|
|
1101
|
+
let dir = err.or_throw(directories_exports.by_path(ctx, dir_path));
|
|
1102
|
+
if (dir) {
|
|
1103
|
+
err.or_throw(directories_exports.update(ctx, dir.id, { state: "to_describe" }));
|
|
1104
|
+
} else {
|
|
1105
|
+
dir = err.or_throw(directories_exports.insert(ctx, { path: dir_path, state: "to_describe", parent_id: parent_dir_id }));
|
|
1106
|
+
}
|
|
1107
|
+
parent_dir_id = dir.id;
|
|
1108
|
+
}
|
|
1109
|
+
err.or_throw(files_exports.insert(ctx, { directory_id: parent_dir_id, path: file_path, state: "to_scan", hash }));
|
|
1110
|
+
}
|
|
1111
|
+
function handle_changed_source_file(ctx, db_file, hash) {
|
|
1112
|
+
file_updated(ctx, db_file.id);
|
|
1113
|
+
err.or_throw(files_exports.update(ctx, db_file.id, { hash }));
|
|
1114
|
+
}
|
|
1115
|
+
function handle_deleted_source_file(ctx, db_file) {
|
|
1116
|
+
err.or_throw(handle_changed_source_file(ctx, db_file, ""));
|
|
1117
|
+
err.or_throw(files_exports.del(ctx, db_file.id));
|
|
1118
|
+
}
|
|
1119
|
+
async function changes(ctx, source_files, db_files) {
|
|
1120
|
+
const created = [];
|
|
1121
|
+
const updated = [];
|
|
1122
|
+
const deleted = [];
|
|
1123
|
+
const db_files_index = group_by_unique(db_files, (x) => x.path);
|
|
1124
|
+
const source_files_index = group_by_unique(source_files, (x) => err.or(get_file_path(ctx, x), ""));
|
|
1125
|
+
const filenames = new Set(Object.keys(source_files_index).concat(Object.keys(db_files_index)));
|
|
1126
|
+
for (const filename of filenames) {
|
|
1127
|
+
const db_file = db_files_index[filename];
|
|
1128
|
+
const source_file = source_files_index[filename];
|
|
1129
|
+
if (!db_file && source_file) created.push({ source_file, hash: await file_signature(source_file.fileName) });
|
|
1130
|
+
if (db_file && !source_file) deleted.push({ db_file });
|
|
1131
|
+
if (db_file && source_file) {
|
|
1132
|
+
const hash = await file_signature(source_file.fileName);
|
|
1133
|
+
if (db_file.hash !== hash) updated.push({ db_file, source_file, hash });
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
return { created, updated, deleted };
|
|
1137
|
+
}
|
|
1138
|
+
function get_file_path(ctx, file) {
|
|
1139
|
+
const absolute_path = path2.resolve(file.fileName);
|
|
1140
|
+
if (absolute_path.startsWith(ctx.project_path)) return absolute_path.slice(ctx.project_path.length);
|
|
1141
|
+
return err.new("file_outside_project_path", { file_path: absolute_path, project_path: ctx.project_path });
|
|
1142
|
+
}
|
|
1143
|
+
function get_parents_paths(ctx, file) {
|
|
1144
|
+
const file_path = get_file_path(ctx, file);
|
|
1145
|
+
if (err.any(file_path)) return file_path;
|
|
1146
|
+
const dirs = [];
|
|
1147
|
+
let current = path2.dirname(file_path);
|
|
1148
|
+
while (current !== path2.sep) {
|
|
1149
|
+
dirs.push(current);
|
|
1150
|
+
current = path2.dirname(current);
|
|
1151
|
+
}
|
|
1152
|
+
dirs.push(current);
|
|
1153
|
+
return dirs.reverse();
|
|
1154
|
+
}
|
|
1155
|
+
async function file_signature(file_path) {
|
|
1156
|
+
const stats = await stat(file_path);
|
|
1157
|
+
return `${stats.mtimeMs}:${stats.size}`;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
// src/update/sync_external_dependencies.ts
|
|
1161
|
+
async function sync_external_dependencies(ctx) {
|
|
1162
|
+
const db_deps = err.or_throw(external_dependencies_exports.all(ctx));
|
|
1163
|
+
for (const ctx_dep of Object.values(ctx.dependencies)) {
|
|
1164
|
+
const existing = db_deps.filter((d) => d.package === ctx_dep.name);
|
|
1165
|
+
if (existing.length === 0) continue;
|
|
1166
|
+
const needs_update = existing.some((d) => d.version !== ctx_dep.version || (d.github_repo || "") !== (ctx_dep.github_repo || ""));
|
|
1167
|
+
if (!needs_update) continue;
|
|
1168
|
+
for (const db_dep of existing) {
|
|
1169
|
+
err.or_throw(
|
|
1170
|
+
external_dependencies_exports.update(ctx, db_dep.id, {
|
|
1171
|
+
version: ctx_dep.version,
|
|
1172
|
+
github_repo: ctx_dep.github_repo,
|
|
1173
|
+
state: "to_describe",
|
|
1174
|
+
error: null
|
|
1175
|
+
})
|
|
1176
|
+
);
|
|
1177
|
+
const files3 = err.or_throw(files_exports.using_dependency(ctx, db_dep.id, ["id"]));
|
|
1178
|
+
for (const file of files3) file_updated(ctx, file.id);
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
// src/update/scan_files/scan_files.ts
|
|
1184
|
+
import path4 from "path";
|
|
1185
|
+
import ts10 from "typescript";
|
|
1186
|
+
|
|
1187
|
+
// src/update/scan_files/imports.ts
|
|
1188
|
+
import ts4 from "typescript";
|
|
1189
|
+
|
|
1190
|
+
// src/update/scan_files/common.ts
|
|
1191
|
+
import path3 from "path";
|
|
1192
|
+
import ts3 from "typescript";
|
|
1193
|
+
function is_external_module(ctx, source_file, module_path) {
|
|
1194
|
+
const resolved = ts3.resolveModuleName(module_path, source_file.fileName, ctx.program.getCompilerOptions(), ts3.sys);
|
|
1195
|
+
if (!resolved.resolvedModule) return true;
|
|
1196
|
+
const resolved_path = path3.resolve(resolved.resolvedModule.resolvedFileName);
|
|
1197
|
+
return !resolved_path.startsWith(ctx.project_path);
|
|
1198
|
+
}
|
|
1199
|
+
function has_export_modifier(node) {
|
|
1200
|
+
if (!ts3.canHaveModifiers(node)) return false;
|
|
1201
|
+
const modifiers = ts3.getModifiers(node);
|
|
1202
|
+
if (!modifiers) return false;
|
|
1203
|
+
return modifiers.some((m) => m.kind === ts3.SyntaxKind.ExportKeyword);
|
|
1204
|
+
}
|
|
1205
|
+
function has_default_modifier(node) {
|
|
1206
|
+
if (!ts3.canHaveModifiers(node)) return false;
|
|
1207
|
+
const modifiers = ts3.getModifiers(node);
|
|
1208
|
+
if (!modifiers) return false;
|
|
1209
|
+
return modifiers.some((m) => m.kind === ts3.SyntaxKind.DefaultKeyword);
|
|
1210
|
+
}
|
|
1211
|
+
function extract_parameters(node, source_file) {
|
|
1212
|
+
return node.parameters.map((param) => ({
|
|
1213
|
+
name: ts3.isIdentifier(param.name) ? param.name.text : param.name.getText(source_file),
|
|
1214
|
+
type: param.type ? param.type.getText(source_file) : null,
|
|
1215
|
+
optional: !!param.questionToken,
|
|
1216
|
+
rest: !!param.dotDotDotToken,
|
|
1217
|
+
default: param.initializer ? param.initializer.getText(source_file) : null
|
|
1218
|
+
}));
|
|
1219
|
+
}
|
|
1220
|
+
function extract_type_parameters(node, source_file) {
|
|
1221
|
+
if (!("typeParameters" in node) || !node.typeParameters) return [];
|
|
1222
|
+
return node.typeParameters.map((tp) => tp.getText(source_file));
|
|
1223
|
+
}
|
|
1224
|
+
function extract_jsdoc_comment(node, source_file) {
|
|
1225
|
+
const sf = source_file || node.getSourceFile();
|
|
1226
|
+
if (!sf) return null;
|
|
1227
|
+
const sourceText = sf.getFullText();
|
|
1228
|
+
const ranges = ts3.getLeadingCommentRanges(sourceText, node.getFullStart());
|
|
1229
|
+
if (!ranges || ranges.length === 0) return null;
|
|
1230
|
+
const lastComment = ranges[ranges.length - 1];
|
|
1231
|
+
if (!lastComment) return null;
|
|
1232
|
+
const commentText = sourceText.slice(lastComment.pos, lastComment.end);
|
|
1233
|
+
if (commentText.startsWith("/**")) {
|
|
1234
|
+
return commentText;
|
|
1235
|
+
}
|
|
1236
|
+
return null;
|
|
1237
|
+
}
|
|
1238
|
+
function extract_decorators(node, source_file) {
|
|
1239
|
+
if (!ts3.canHaveDecorators(node)) return [];
|
|
1240
|
+
const decorators = ts3.getDecorators(node);
|
|
1241
|
+
if (!decorators) return [];
|
|
1242
|
+
const sf = source_file || node.getSourceFile();
|
|
1243
|
+
return decorators.map((decorator) => {
|
|
1244
|
+
const expr = decorator.expression;
|
|
1245
|
+
if (ts3.isIdentifier(expr)) {
|
|
1246
|
+
return { name: expr.text };
|
|
1247
|
+
}
|
|
1248
|
+
if (ts3.isCallExpression(expr) && ts3.isIdentifier(expr.expression)) {
|
|
1249
|
+
return {
|
|
1250
|
+
name: expr.expression.text,
|
|
1251
|
+
arguments: expr.arguments.map((arg) => arg.getText(sf))
|
|
1252
|
+
};
|
|
1253
|
+
}
|
|
1254
|
+
return { name: decorator.expression.getText(sf) };
|
|
1255
|
+
});
|
|
1256
|
+
}
|
|
1257
|
+
function is_builtin_module(package_name) {
|
|
1258
|
+
const builtins = [
|
|
1259
|
+
"fs",
|
|
1260
|
+
"path",
|
|
1261
|
+
"http",
|
|
1262
|
+
"https",
|
|
1263
|
+
"url",
|
|
1264
|
+
"crypto",
|
|
1265
|
+
"os",
|
|
1266
|
+
"util",
|
|
1267
|
+
"stream",
|
|
1268
|
+
"events",
|
|
1269
|
+
"buffer",
|
|
1270
|
+
"child_process",
|
|
1271
|
+
"cluster",
|
|
1272
|
+
"dns",
|
|
1273
|
+
"net",
|
|
1274
|
+
"tls",
|
|
1275
|
+
"dgram",
|
|
1276
|
+
"readline",
|
|
1277
|
+
"repl",
|
|
1278
|
+
"vm",
|
|
1279
|
+
"zlib",
|
|
1280
|
+
"assert",
|
|
1281
|
+
"querystring",
|
|
1282
|
+
"string_decoder",
|
|
1283
|
+
"timers",
|
|
1284
|
+
"tty",
|
|
1285
|
+
"v8",
|
|
1286
|
+
"worker_threads"
|
|
1287
|
+
];
|
|
1288
|
+
return builtins.includes(package_name) || package_name.startsWith("node:");
|
|
1289
|
+
}
|
|
1290
|
+
function is_dynamic_import(node) {
|
|
1291
|
+
if (!ts3.isCallExpression(node)) return false;
|
|
1292
|
+
if (node.expression.kind !== ts3.SyntaxKind.ImportKeyword) return false;
|
|
1293
|
+
if (node.arguments.length !== 1) return false;
|
|
1294
|
+
const arg = node.arguments[0];
|
|
1295
|
+
if (!arg) return false;
|
|
1296
|
+
return ts3.isStringLiteral(arg);
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
// src/update/scan_files/imports.ts
|
|
1300
|
+
function is_import(ctx, source_file, node) {
|
|
1301
|
+
if (!ts4.isImportDeclaration(node) || !node.moduleSpecifier || !ts4.isStringLiteral(node.moduleSpecifier)) return false;
|
|
1302
|
+
return !is_external_module(ctx, source_file, node.moduleSpecifier.text);
|
|
1303
|
+
}
|
|
1304
|
+
function extract_import(ctx, source_file, node, file_id) {
|
|
1305
|
+
const imports2 = [];
|
|
1306
|
+
const clause = node.importClause;
|
|
1307
|
+
if (!clause || !node.moduleSpecifier || !ts4.isStringLiteral(node.moduleSpecifier)) return imports2;
|
|
1308
|
+
const exporter_file_id = resolve_exporter_file(ctx, source_file, node.moduleSpecifier.text);
|
|
1309
|
+
if (err.any(exporter_file_id)) return imports2;
|
|
1310
|
+
if (clause.name) {
|
|
1311
|
+
imports2.push({
|
|
1312
|
+
importer_file_id: file_id,
|
|
1313
|
+
exporter_file_id,
|
|
1314
|
+
name: "default",
|
|
1315
|
+
alias: clause.name.text,
|
|
1316
|
+
state: "to_link"
|
|
1317
|
+
});
|
|
1318
|
+
}
|
|
1319
|
+
if (clause.namedBindings && ts4.isNamedImports(clause.namedBindings)) {
|
|
1320
|
+
for (const element of clause.namedBindings.elements) {
|
|
1321
|
+
imports2.push({
|
|
1322
|
+
importer_file_id: file_id,
|
|
1323
|
+
exporter_file_id,
|
|
1324
|
+
name: (element.propertyName || element.name).text,
|
|
1325
|
+
alias: element.name.text,
|
|
1326
|
+
state: "to_link"
|
|
1327
|
+
});
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
if (clause.namedBindings && ts4.isNamespaceImport(clause.namedBindings)) {
|
|
1331
|
+
imports2.push({
|
|
1332
|
+
importer_file_id: file_id,
|
|
1333
|
+
exporter_file_id,
|
|
1334
|
+
name: "*",
|
|
1335
|
+
alias: clause.namedBindings.name.text,
|
|
1336
|
+
state: "to_link"
|
|
1337
|
+
});
|
|
1338
|
+
}
|
|
1339
|
+
return imports2;
|
|
1340
|
+
}
|
|
1341
|
+
function extract_dynamic_import(ctx, source_file, node, file_id) {
|
|
1342
|
+
const arg = node.arguments[0];
|
|
1343
|
+
const module_specifier = arg.text;
|
|
1344
|
+
const exporter_file_id = resolve_exporter_file(ctx, source_file, module_specifier);
|
|
1345
|
+
if (err.any(exporter_file_id)) return null;
|
|
1346
|
+
return {
|
|
1347
|
+
importer_file_id: file_id,
|
|
1348
|
+
exporter_file_id,
|
|
1349
|
+
name: "*",
|
|
1350
|
+
alias: "__dynamic_import__",
|
|
1351
|
+
state: "to_link",
|
|
1352
|
+
is_dynamic: true
|
|
1353
|
+
};
|
|
1354
|
+
}
|
|
1355
|
+
function resolve_exporter_file(ctx, source_file, module_specifier) {
|
|
1356
|
+
const resolution = ts4.resolveModuleName(module_specifier, source_file.fileName, ctx.program.getCompilerOptions(), ts4.sys);
|
|
1357
|
+
if (!resolution.resolvedModule) {
|
|
1358
|
+
return err.new("module_resolution_failed", { module: module_specifier, from: source_file.fileName });
|
|
1359
|
+
}
|
|
1360
|
+
const resolved_path = resolution.resolvedModule.resolvedFileName;
|
|
1361
|
+
const file_path = resolved_path.startsWith(ctx.project_path) ? resolved_path.slice(ctx.project_path.length) : resolved_path;
|
|
1362
|
+
const file = files_exports.by_path(ctx, file_path);
|
|
1363
|
+
if (err.any(file)) return file;
|
|
1364
|
+
if (!file) {
|
|
1365
|
+
return err.new("exporter_file_not_found", { path: file_path, module: module_specifier });
|
|
1366
|
+
}
|
|
1367
|
+
return file.id;
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
// src/update/scan_files/external_imports.ts
|
|
1371
|
+
import ts5 from "typescript";
|
|
1372
|
+
function is_external_import(ctx, source_file, node) {
|
|
1373
|
+
if (!ts5.isImportDeclaration(node) || !node.moduleSpecifier || !ts5.isStringLiteral(node.moduleSpecifier)) return false;
|
|
1374
|
+
return is_external_module(ctx, source_file, node.moduleSpecifier.text);
|
|
1375
|
+
}
|
|
1376
|
+
function parse_module_specifier(spec) {
|
|
1377
|
+
let is_builtin = false;
|
|
1378
|
+
let normalized = spec;
|
|
1379
|
+
if (spec.startsWith("node:")) {
|
|
1380
|
+
normalized = spec.slice(5);
|
|
1381
|
+
is_builtin = true;
|
|
1382
|
+
} else {
|
|
1383
|
+
is_builtin = is_builtin_module(spec);
|
|
1384
|
+
}
|
|
1385
|
+
if (normalized.startsWith("@")) {
|
|
1386
|
+
const parts = normalized.split("/");
|
|
1387
|
+
if (parts.length <= 2) {
|
|
1388
|
+
return { pkg: normalized, subpath: null, is_builtin };
|
|
1389
|
+
}
|
|
1390
|
+
const pkg = `${parts[0]}/${parts[1]}`;
|
|
1391
|
+
const subpath = "/" + parts.slice(2).join("/");
|
|
1392
|
+
return { pkg, subpath, is_builtin };
|
|
1393
|
+
} else {
|
|
1394
|
+
const slash_idx = normalized.indexOf("/");
|
|
1395
|
+
if (slash_idx === -1) {
|
|
1396
|
+
return { pkg: normalized, subpath: null, is_builtin };
|
|
1397
|
+
}
|
|
1398
|
+
const pkg = normalized.slice(0, slash_idx);
|
|
1399
|
+
const subpath = normalized.slice(slash_idx);
|
|
1400
|
+
return { pkg, subpath, is_builtin };
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
function extract_external_import_info(node) {
|
|
1404
|
+
const results = [];
|
|
1405
|
+
const module_specifier = node.moduleSpecifier.text;
|
|
1406
|
+
const { pkg, subpath, is_builtin } = parse_module_specifier(module_specifier);
|
|
1407
|
+
const clause = node.importClause;
|
|
1408
|
+
if (!clause) {
|
|
1409
|
+
results.push({
|
|
1410
|
+
package: pkg,
|
|
1411
|
+
subpath,
|
|
1412
|
+
name: null,
|
|
1413
|
+
alias: "__side_effect__",
|
|
1414
|
+
is_builtin
|
|
1415
|
+
});
|
|
1416
|
+
return results;
|
|
1417
|
+
}
|
|
1418
|
+
if (clause.name) {
|
|
1419
|
+
results.push({
|
|
1420
|
+
package: pkg,
|
|
1421
|
+
subpath,
|
|
1422
|
+
name: "default",
|
|
1423
|
+
alias: clause.name.text,
|
|
1424
|
+
is_builtin
|
|
1425
|
+
});
|
|
1426
|
+
}
|
|
1427
|
+
if (clause.namedBindings && ts5.isNamedImports(clause.namedBindings)) {
|
|
1428
|
+
for (const element of clause.namedBindings.elements) {
|
|
1429
|
+
results.push({
|
|
1430
|
+
package: pkg,
|
|
1431
|
+
subpath,
|
|
1432
|
+
name: (element.propertyName || element.name).text,
|
|
1433
|
+
alias: element.name.text,
|
|
1434
|
+
is_builtin
|
|
1435
|
+
});
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
if (clause.namedBindings && ts5.isNamespaceImport(clause.namedBindings)) {
|
|
1439
|
+
results.push({
|
|
1440
|
+
package: pkg,
|
|
1441
|
+
subpath,
|
|
1442
|
+
name: "*",
|
|
1443
|
+
alias: clause.namedBindings.name.text,
|
|
1444
|
+
is_builtin
|
|
1445
|
+
});
|
|
1446
|
+
}
|
|
1447
|
+
return results;
|
|
1448
|
+
}
|
|
1449
|
+
function extract_external_import(ctx, node, file_id) {
|
|
1450
|
+
const infos = extract_external_import_info(node);
|
|
1451
|
+
const external_imports2 = [];
|
|
1452
|
+
for (const info of infos) {
|
|
1453
|
+
const dep_meta = Object.values(ctx.dependencies).find((dep) => info.package.startsWith(dep.name));
|
|
1454
|
+
const dependency = external_dependencies_exports.get_or_create(ctx, {
|
|
1455
|
+
package: info.package,
|
|
1456
|
+
subpath: info.subpath,
|
|
1457
|
+
name: info.name,
|
|
1458
|
+
version: dep_meta?.version,
|
|
1459
|
+
github_repo: dep_meta?.github_repo,
|
|
1460
|
+
is_builtin: info.is_builtin,
|
|
1461
|
+
state: "to_describe"
|
|
1462
|
+
});
|
|
1463
|
+
if (err.any(dependency)) return dependency;
|
|
1464
|
+
external_imports2.push({ file_id, external_dependency_id: dependency.id, alias: info.alias, is_dynamic: false });
|
|
1465
|
+
}
|
|
1466
|
+
return external_imports2;
|
|
1467
|
+
}
|
|
1468
|
+
function extract_external_dynamic_import(ctx, node, file_id) {
|
|
1469
|
+
const arg = node.arguments[0];
|
|
1470
|
+
const module_specifier = arg.text;
|
|
1471
|
+
const { pkg, subpath, is_builtin } = parse_module_specifier(module_specifier);
|
|
1472
|
+
const dep_meta = Object.values(ctx.dependencies).find((dep) => pkg.startsWith(dep.name));
|
|
1473
|
+
const dependency = external_dependencies_exports.get_or_create(ctx, {
|
|
1474
|
+
package: pkg,
|
|
1475
|
+
subpath,
|
|
1476
|
+
name: "*",
|
|
1477
|
+
version: dep_meta?.version,
|
|
1478
|
+
github_repo: dep_meta?.github_repo,
|
|
1479
|
+
is_builtin,
|
|
1480
|
+
state: "to_describe"
|
|
1481
|
+
});
|
|
1482
|
+
if (err.any(dependency)) return dependency;
|
|
1483
|
+
return { file_id, external_dependency_id: dependency.id, alias: "__dynamic_import__", is_dynamic: true };
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1486
|
+
// src/update/scan_files/types.ts
|
|
1487
|
+
import ts6 from "typescript";
|
|
1488
|
+
function is_type(node) {
|
|
1489
|
+
return ts6.isTypeAliasDeclaration(node) || ts6.isInterfaceDeclaration(node) || ts6.isEnumDeclaration(node);
|
|
1490
|
+
}
|
|
1491
|
+
function extract_type_symbol(node, file_id, source_file) {
|
|
1492
|
+
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);
|
|
1493
|
+
return {
|
|
1494
|
+
file_id,
|
|
1495
|
+
type: "type",
|
|
1496
|
+
name: node.name.text,
|
|
1497
|
+
text: node.getText(source_file),
|
|
1498
|
+
meta: JSON.stringify(meta2),
|
|
1499
|
+
is_exported: has_export_modifier(node),
|
|
1500
|
+
state: "to_link"
|
|
1501
|
+
};
|
|
1502
|
+
}
|
|
1503
|
+
function extract_enum_meta(node, source_file) {
|
|
1504
|
+
const enum_values = {};
|
|
1505
|
+
for (const member of node.members) {
|
|
1506
|
+
if (ts6.isIdentifier(member.name) || ts6.isStringLiteral(member.name)) {
|
|
1507
|
+
const name = member.name.text;
|
|
1508
|
+
const value = member.initializer ? member.initializer.getText(source_file) : "auto";
|
|
1509
|
+
enum_values[name] = value;
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
return {
|
|
1513
|
+
kind: "enum",
|
|
1514
|
+
type_parameters: [],
|
|
1515
|
+
extends: [],
|
|
1516
|
+
members: [],
|
|
1517
|
+
enum_values,
|
|
1518
|
+
decorators: extract_decorators(node, source_file),
|
|
1519
|
+
comment: extract_jsdoc_comment(node, source_file)
|
|
1520
|
+
};
|
|
1521
|
+
}
|
|
1522
|
+
function extract_interface_meta(node, source_file) {
|
|
1523
|
+
const members = [];
|
|
1524
|
+
for (const member of node.members) {
|
|
1525
|
+
if (ts6.isPropertySignature(member) && ts6.isIdentifier(member.name)) {
|
|
1526
|
+
members.push({
|
|
1527
|
+
name: member.name.text,
|
|
1528
|
+
type: member.type ? member.type.getText(source_file) : "any",
|
|
1529
|
+
optional: !!member.questionToken
|
|
1530
|
+
});
|
|
1531
|
+
} else if (ts6.isMethodSignature(member) && ts6.isIdentifier(member.name)) {
|
|
1532
|
+
const params = member.parameters.map((p) => {
|
|
1533
|
+
const param_type = p.type ? p.type.getText(source_file) : "any";
|
|
1534
|
+
return `${p.name.getText(source_file)}: ${param_type}`;
|
|
1535
|
+
}).join(", ");
|
|
1536
|
+
const return_type = member.type ? member.type.getText(source_file) : "void";
|
|
1537
|
+
members.push({
|
|
1538
|
+
name: member.name.text,
|
|
1539
|
+
type: `(${params}) => ${return_type}`,
|
|
1540
|
+
optional: !!member.questionToken
|
|
1541
|
+
});
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
const extends_clauses = node.heritageClauses?.filter((c) => c.token === ts6.SyntaxKind.ExtendsKeyword).flatMap((c) => c.types.map((t) => t.expression.getText(source_file))) || [];
|
|
1545
|
+
return {
|
|
1546
|
+
kind: "interface",
|
|
1547
|
+
type_parameters: extract_type_parameters(node, source_file),
|
|
1548
|
+
extends: extends_clauses,
|
|
1549
|
+
members,
|
|
1550
|
+
enum_values: {},
|
|
1551
|
+
decorators: extract_decorators(node, source_file),
|
|
1552
|
+
comment: extract_jsdoc_comment(node, source_file)
|
|
1553
|
+
};
|
|
1554
|
+
}
|
|
1555
|
+
function extract_type_alias_meta(node, source_file) {
|
|
1556
|
+
return {
|
|
1557
|
+
kind: "type_alias",
|
|
1558
|
+
type_parameters: extract_type_parameters(node, source_file),
|
|
1559
|
+
extends: [],
|
|
1560
|
+
members: [],
|
|
1561
|
+
enum_values: {},
|
|
1562
|
+
decorators: extract_decorators(node, source_file),
|
|
1563
|
+
comment: extract_jsdoc_comment(node, source_file)
|
|
1564
|
+
};
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
// src/update/scan_files/functions.ts
|
|
1568
|
+
import ts7 from "typescript";
|
|
1569
|
+
function is_function(node) {
|
|
1570
|
+
if (!ts7.isFunctionDeclaration(node)) return false;
|
|
1571
|
+
return !!node.name || has_default_modifier(node);
|
|
1572
|
+
}
|
|
1573
|
+
function extract_function_symbol(node, file_id, source_file) {
|
|
1574
|
+
const is_default = has_default_modifier(node);
|
|
1575
|
+
const name = is_default ? "default" : node.name?.text || "default";
|
|
1576
|
+
const meta2 = {
|
|
1577
|
+
kind: "function_declaration",
|
|
1578
|
+
parameters: extract_parameters(node, source_file),
|
|
1579
|
+
return_type: node.type ? node.type.getText(source_file) : null,
|
|
1580
|
+
type_parameters: extract_type_parameters(node, source_file),
|
|
1581
|
+
modifiers: {
|
|
1582
|
+
async: !!node.modifiers?.some((m) => m.kind === ts7.SyntaxKind.AsyncKeyword),
|
|
1583
|
+
generator: !!node.asteriskToken
|
|
1584
|
+
},
|
|
1585
|
+
decorators: extract_decorators(node, source_file),
|
|
1586
|
+
comment: extract_jsdoc_comment(node, source_file)
|
|
1587
|
+
};
|
|
1588
|
+
return {
|
|
1589
|
+
file_id,
|
|
1590
|
+
type: "function",
|
|
1591
|
+
name,
|
|
1592
|
+
text: node.getText(source_file),
|
|
1593
|
+
meta: JSON.stringify(meta2),
|
|
1594
|
+
is_exported: has_export_modifier(node),
|
|
1595
|
+
state: "to_link"
|
|
1596
|
+
};
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
// src/update/scan_files/variables.ts
|
|
1600
|
+
import ts8 from "typescript";
|
|
1601
|
+
function is_function_declaration(declaration) {
|
|
1602
|
+
return !!(declaration.initializer && (ts8.isArrowFunction(declaration.initializer) || ts8.isFunctionExpression(declaration.initializer)));
|
|
1603
|
+
}
|
|
1604
|
+
function extract_variable_symbol(node, file_id, source_file) {
|
|
1605
|
+
const symbols3 = [];
|
|
1606
|
+
const is_exported = has_export_modifier(node);
|
|
1607
|
+
const declaration_kind = node.declarationList.flags & ts8.NodeFlags.Const ? "const" : node.declarationList.flags & ts8.NodeFlags.Let ? "let" : "var";
|
|
1608
|
+
for (const declaration of node.declarationList.declarations) {
|
|
1609
|
+
if (!ts8.isIdentifier(declaration.name)) continue;
|
|
1610
|
+
if (is_function_declaration(declaration)) {
|
|
1611
|
+
const func_node = declaration.initializer;
|
|
1612
|
+
const meta2 = {
|
|
1613
|
+
kind: ts8.isArrowFunction(func_node) ? "arrow_function" : "function_expression",
|
|
1614
|
+
parameters: extract_parameters(func_node, source_file),
|
|
1615
|
+
return_type: func_node.type ? func_node.type.getText(source_file) : null,
|
|
1616
|
+
type_parameters: extract_type_parameters(func_node, source_file),
|
|
1617
|
+
modifiers: {
|
|
1618
|
+
async: !!func_node.modifiers?.some((m) => m.kind === ts8.SyntaxKind.AsyncKeyword),
|
|
1619
|
+
generator: ts8.isFunctionExpression(func_node) && !!func_node.asteriskToken
|
|
1620
|
+
},
|
|
1621
|
+
decorators: extract_decorators(node, source_file),
|
|
1622
|
+
comment: extract_jsdoc_comment(node, source_file)
|
|
1623
|
+
};
|
|
1624
|
+
symbols3.push({
|
|
1625
|
+
file_id,
|
|
1626
|
+
type: "function",
|
|
1627
|
+
name: declaration.name.text,
|
|
1628
|
+
text: node.getText(source_file),
|
|
1629
|
+
meta: JSON.stringify(meta2),
|
|
1630
|
+
is_exported,
|
|
1631
|
+
state: "to_link"
|
|
1632
|
+
});
|
|
1633
|
+
} else {
|
|
1634
|
+
const meta2 = {
|
|
1635
|
+
declaration_kind,
|
|
1636
|
+
type: declaration.type ? declaration.type.getText(source_file) : null,
|
|
1637
|
+
value: declaration.initializer ? declaration.initializer.getText(source_file) : null,
|
|
1638
|
+
decorators: extract_decorators(node, source_file),
|
|
1639
|
+
comment: extract_jsdoc_comment(node, source_file)
|
|
1640
|
+
};
|
|
1641
|
+
symbols3.push({
|
|
1642
|
+
file_id,
|
|
1643
|
+
type: "variable",
|
|
1644
|
+
name: declaration.name.text,
|
|
1645
|
+
text: node.getText(source_file),
|
|
1646
|
+
meta: JSON.stringify(meta2),
|
|
1647
|
+
is_exported,
|
|
1648
|
+
state: "to_link"
|
|
1649
|
+
});
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
return symbols3;
|
|
1653
|
+
}
|
|
1654
|
+
|
|
1655
|
+
// src/update/scan_files/classes.ts
|
|
1656
|
+
import ts9 from "typescript";
|
|
1657
|
+
function is_class(node) {
|
|
1658
|
+
if (!ts9.isClassDeclaration(node)) return false;
|
|
1659
|
+
return !!node.name || has_default_modifier(node);
|
|
1660
|
+
}
|
|
1661
|
+
function extract_class_symbol(node, file_id, source_file) {
|
|
1662
|
+
const is_default = has_default_modifier(node);
|
|
1663
|
+
const name = is_default ? "default" : node.name?.text || "default";
|
|
1664
|
+
const meta2 = {
|
|
1665
|
+
extends: node.heritageClauses?.find((c) => c.token === ts9.SyntaxKind.ExtendsKeyword)?.types[0]?.expression.getText(source_file) || null,
|
|
1666
|
+
implements: node.heritageClauses?.find((c) => c.token === ts9.SyntaxKind.ImplementsKeyword)?.types.map((t) => t.expression.getText(source_file)) || [],
|
|
1667
|
+
type_parameters: extract_type_parameters(node, source_file),
|
|
1668
|
+
modifiers: {
|
|
1669
|
+
abstract: !!node.modifiers?.some((m) => m.kind === ts9.SyntaxKind.AbstractKeyword)
|
|
1670
|
+
},
|
|
1671
|
+
decorators: extract_decorators(node, source_file),
|
|
1672
|
+
comment: extract_jsdoc_comment(node, source_file)
|
|
1673
|
+
};
|
|
1674
|
+
return {
|
|
1675
|
+
file_id,
|
|
1676
|
+
type: "class",
|
|
1677
|
+
name,
|
|
1678
|
+
text: node.getText(source_file),
|
|
1679
|
+
meta: JSON.stringify(meta2),
|
|
1680
|
+
is_exported: has_export_modifier(node),
|
|
1681
|
+
state: "to_link"
|
|
1682
|
+
};
|
|
1683
|
+
}
|
|
1684
|
+
function get_visibility(member) {
|
|
1685
|
+
if (!ts9.canHaveModifiers(member)) return null;
|
|
1686
|
+
const modifiers = ts9.getModifiers(member);
|
|
1687
|
+
if (!modifiers) return null;
|
|
1688
|
+
if (modifiers.some((m) => m.kind === ts9.SyntaxKind.PrivateKeyword)) return "private";
|
|
1689
|
+
if (modifiers.some((m) => m.kind === ts9.SyntaxKind.ProtectedKeyword)) return "protected";
|
|
1690
|
+
if (modifiers.some((m) => m.kind === ts9.SyntaxKind.PublicKeyword)) return "public";
|
|
1691
|
+
return null;
|
|
1692
|
+
}
|
|
1693
|
+
function extract_class_fields(node, file_id, source_file) {
|
|
1694
|
+
const symbols3 = [];
|
|
1695
|
+
if (!node.name) return symbols3;
|
|
1696
|
+
const class_name = node.name.text;
|
|
1697
|
+
node.members.forEach((member) => {
|
|
1698
|
+
if (ts9.isMethodDeclaration(member) && member.name && ts9.isIdentifier(member.name)) {
|
|
1699
|
+
const meta2 = {
|
|
1700
|
+
class_name,
|
|
1701
|
+
visibility: get_visibility(member),
|
|
1702
|
+
parameters: extract_parameters(member, source_file),
|
|
1703
|
+
return_type: member.type ? member.type.getText(source_file) : null,
|
|
1704
|
+
type_parameters: extract_type_parameters(member, source_file),
|
|
1705
|
+
modifiers: {
|
|
1706
|
+
static: !!member.modifiers?.some((m) => m.kind === ts9.SyntaxKind.StaticKeyword),
|
|
1707
|
+
async: !!member.modifiers?.some((m) => m.kind === ts9.SyntaxKind.AsyncKeyword),
|
|
1708
|
+
abstract: !!member.modifiers?.some((m) => m.kind === ts9.SyntaxKind.AbstractKeyword),
|
|
1709
|
+
readonly: !!member.modifiers?.some((m) => m.kind === ts9.SyntaxKind.ReadonlyKeyword)
|
|
1710
|
+
},
|
|
1711
|
+
decorators: extract_decorators(member, source_file),
|
|
1712
|
+
comment: extract_jsdoc_comment(member, source_file)
|
|
1713
|
+
};
|
|
1714
|
+
symbols3.push({
|
|
1715
|
+
file_id,
|
|
1716
|
+
type: "class_method",
|
|
1717
|
+
name: `${class_name}.${member.name.text}`,
|
|
1718
|
+
text: member.getText(source_file),
|
|
1719
|
+
meta: JSON.stringify(meta2),
|
|
1720
|
+
is_exported: false,
|
|
1721
|
+
state: "to_link"
|
|
1722
|
+
});
|
|
1723
|
+
}
|
|
1724
|
+
if (ts9.isPropertyDeclaration(member) && member.name && ts9.isIdentifier(member.name)) {
|
|
1725
|
+
const meta2 = {
|
|
1726
|
+
class_name,
|
|
1727
|
+
visibility: get_visibility(member),
|
|
1728
|
+
type: member.type ? member.type.getText(source_file) : null,
|
|
1729
|
+
optional: !!member.questionToken,
|
|
1730
|
+
modifiers: {
|
|
1731
|
+
static: !!member.modifiers?.some((m) => m.kind === ts9.SyntaxKind.StaticKeyword),
|
|
1732
|
+
readonly: !!member.modifiers?.some((m) => m.kind === ts9.SyntaxKind.ReadonlyKeyword),
|
|
1733
|
+
abstract: !!member.modifiers?.some((m) => m.kind === ts9.SyntaxKind.AbstractKeyword)
|
|
1734
|
+
},
|
|
1735
|
+
decorators: extract_decorators(member, source_file),
|
|
1736
|
+
comment: extract_jsdoc_comment(member, source_file)
|
|
1737
|
+
};
|
|
1738
|
+
symbols3.push({
|
|
1739
|
+
file_id,
|
|
1740
|
+
type: "class_property",
|
|
1741
|
+
name: `${class_name}.${member.name.text}`,
|
|
1742
|
+
text: member.getText(source_file),
|
|
1743
|
+
meta: JSON.stringify(meta2),
|
|
1744
|
+
is_exported: false,
|
|
1745
|
+
state: "to_link"
|
|
1746
|
+
});
|
|
1747
|
+
}
|
|
1748
|
+
});
|
|
1749
|
+
return symbols3;
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
// src/update/scan_files/scan_files.ts
|
|
1753
|
+
async function scan_files(ctx) {
|
|
1754
|
+
const files3 = err.or_throw(files_exports.by_state(ctx, "to_scan"));
|
|
1755
|
+
for (const file of files3) {
|
|
1756
|
+
const res = scan_file(ctx, file);
|
|
1757
|
+
if (err.any(res)) {
|
|
1758
|
+
err.or_throw(files_exports.update(ctx, file.id, { error: String(res) }));
|
|
1759
|
+
} else {
|
|
1760
|
+
err.or_throw(files_exports.update(ctx, file.id, { state: "to_describe", error: null }));
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
function scan_file(ctx, file) {
|
|
1765
|
+
return err.pipe(
|
|
1766
|
+
() => symbols_exports.del_by_file(ctx, file.id),
|
|
1767
|
+
() => imports_exports.del_by_importer_file(ctx, file.id),
|
|
1768
|
+
() => external_imports_exports.del_by_file(ctx, file.id),
|
|
1769
|
+
() => get_source_file(ctx, file.path),
|
|
1770
|
+
(source_file) => parse_file(ctx, source_file, file.id),
|
|
1771
|
+
({ imports: imports2, symbols: symbols3, external_imports: external_imports2 }) => err.pipe(
|
|
1772
|
+
() => external_imports2.length && external_imports_exports.insert_many(ctx, external_imports2),
|
|
1773
|
+
() => imports2.length && imports_exports.insert_many(ctx, imports2),
|
|
1774
|
+
() => symbols3.length && symbols_exports.insert_many(ctx, symbols3)
|
|
1775
|
+
)
|
|
1776
|
+
);
|
|
1777
|
+
}
|
|
1778
|
+
function get_source_file(ctx, file_path) {
|
|
1779
|
+
const source_file = ctx.program.getSourceFile(path4.join(ctx.project_path, file_path));
|
|
1780
|
+
if (!source_file) return err.new("file_not_found", { path: file_path });
|
|
1781
|
+
return source_file;
|
|
1782
|
+
}
|
|
1783
|
+
function parse_file(ctx, source_file, file_id) {
|
|
1784
|
+
const imports2 = [];
|
|
1785
|
+
const symbols3 = [];
|
|
1786
|
+
const external_imports2 = [];
|
|
1787
|
+
function find_dynamic_imports(node) {
|
|
1788
|
+
if (is_dynamic_import(node)) {
|
|
1789
|
+
const arg = node.arguments[0];
|
|
1790
|
+
if (is_external_module(ctx, source_file, arg.text)) {
|
|
1791
|
+
const result = extract_external_dynamic_import(ctx, node, file_id);
|
|
1792
|
+
if (err.any(result)) return result;
|
|
1793
|
+
external_imports2.push(result);
|
|
1794
|
+
} else {
|
|
1795
|
+
const result = extract_dynamic_import(ctx, source_file, node, file_id);
|
|
1796
|
+
if (result) imports2.push(result);
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
ts10.forEachChild(node, find_dynamic_imports);
|
|
1800
|
+
}
|
|
1801
|
+
let error = void 0;
|
|
1802
|
+
ts10.forEachChild(source_file, (statement) => {
|
|
1803
|
+
if (error) return;
|
|
1804
|
+
const res = parse_node(ctx, source_file, statement, file_id);
|
|
1805
|
+
if (err.any(res)) {
|
|
1806
|
+
error = res;
|
|
1807
|
+
return;
|
|
1808
|
+
}
|
|
1809
|
+
imports2.push(...res.imports);
|
|
1810
|
+
symbols3.push(...res.symbols);
|
|
1811
|
+
external_imports2.push(...res.external_imports);
|
|
1812
|
+
error = find_dynamic_imports(statement);
|
|
1813
|
+
});
|
|
1814
|
+
if (error) return error;
|
|
1815
|
+
return { imports: imports2, symbols: symbols3, external_imports: external_imports2 };
|
|
1816
|
+
}
|
|
1817
|
+
function parse_node(ctx, source_file, node, file_id) {
|
|
1818
|
+
const imports2 = [];
|
|
1819
|
+
const symbols3 = [];
|
|
1820
|
+
const external_imports2 = [];
|
|
1821
|
+
if (is_external_import(ctx, source_file, node)) {
|
|
1822
|
+
const result = extract_external_import(ctx, node, file_id);
|
|
1823
|
+
if (err.any(result)) return result;
|
|
1824
|
+
external_imports2.push(...result);
|
|
1825
|
+
} else if (is_import(ctx, source_file, node)) {
|
|
1826
|
+
imports2.push(...extract_import(ctx, source_file, node, file_id));
|
|
1827
|
+
} else if (ts10.isExportAssignment(node) && !node.isExportEquals) {
|
|
1828
|
+
symbols3.push({
|
|
1829
|
+
file_id,
|
|
1830
|
+
type: "variable",
|
|
1831
|
+
name: "default",
|
|
1832
|
+
text: node.getText(source_file),
|
|
1833
|
+
meta: JSON.stringify({
|
|
1834
|
+
declaration_kind: "const",
|
|
1835
|
+
type: null,
|
|
1836
|
+
value: node.expression.getText(source_file),
|
|
1837
|
+
decorators: [],
|
|
1838
|
+
comment: null
|
|
1839
|
+
}),
|
|
1840
|
+
is_exported: true,
|
|
1841
|
+
state: "to_link"
|
|
1842
|
+
});
|
|
1843
|
+
} else if (ts10.isExportDeclaration(node) && node.exportClause && ts10.isNamedExports(node.exportClause) && !node.moduleSpecifier) {
|
|
1844
|
+
for (const element of node.exportClause.elements) {
|
|
1845
|
+
if (element.name.text === "default") {
|
|
1846
|
+
const localName = element.propertyName?.text || element.name.text;
|
|
1847
|
+
symbols3.push({
|
|
1848
|
+
file_id,
|
|
1849
|
+
type: "variable",
|
|
1850
|
+
name: "default",
|
|
1851
|
+
text: node.getText(source_file),
|
|
1852
|
+
meta: JSON.stringify({ declaration_kind: "const", type: null, value: localName, is_reexport: true, decorators: [], comment: null }),
|
|
1853
|
+
is_exported: true,
|
|
1854
|
+
state: "to_link"
|
|
1855
|
+
});
|
|
1856
|
+
}
|
|
1857
|
+
}
|
|
1858
|
+
} else if (is_type(node)) {
|
|
1859
|
+
symbols3.push(extract_type_symbol(node, file_id, source_file));
|
|
1860
|
+
} else if (is_function(node)) {
|
|
1861
|
+
symbols3.push(extract_function_symbol(node, file_id, source_file));
|
|
1862
|
+
} else if (ts10.isVariableStatement(node)) {
|
|
1863
|
+
symbols3.push(...extract_variable_symbol(node, file_id, source_file));
|
|
1864
|
+
} else if (is_class(node)) {
|
|
1865
|
+
symbols3.push(extract_class_symbol(node, file_id, source_file));
|
|
1866
|
+
symbols3.push(...extract_class_fields(node, file_id, source_file));
|
|
1867
|
+
}
|
|
1868
|
+
return { imports: imports2, symbols: symbols3, external_imports: external_imports2 };
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1871
|
+
// src/update/link_imports.ts
|
|
1872
|
+
async function link_imports(ctx) {
|
|
1873
|
+
const imports2 = err.or_throw(imports_exports.by_state(ctx, "to_link"));
|
|
1874
|
+
let i = 0;
|
|
1875
|
+
for (const import_ of imports2) {
|
|
1876
|
+
const res = link_import(ctx, import_);
|
|
1877
|
+
if (err.any(res)) err.or_throw(imports_exports.update(ctx, import_.id, { error: String(res) }));
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
function link_import(ctx, import_) {
|
|
1881
|
+
if (import_.name === "*") {
|
|
1882
|
+
return imports_exports.update(ctx, import_.id, { state: "ready", error: null });
|
|
1883
|
+
}
|
|
1884
|
+
const symbol = symbols_exports.by_file_and_name(ctx, { file_id: import_.exporter_file_id, name: import_.name, is_exported: true });
|
|
1885
|
+
if (err.any(symbol)) return symbol;
|
|
1886
|
+
if (!symbol) return err.new("exported_symbol_not_found", { name: import_.name, file_id: import_.exporter_file_id });
|
|
1887
|
+
return imports_exports.update(ctx, import_.id, { symbol_id: symbol.id, state: "ready", error: null });
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
// src/update/link_symbols.ts
|
|
1891
|
+
import path5 from "path";
|
|
1892
|
+
import ts11 from "typescript";
|
|
1893
|
+
async function link_symbols(ctx) {
|
|
1894
|
+
const symbols3 = err.or_throw(symbols_exports.by_state(ctx, "to_link"));
|
|
1895
|
+
let i = 0;
|
|
1896
|
+
for (const symbol of symbols3) {
|
|
1897
|
+
const res = link_symbol(ctx, symbol);
|
|
1898
|
+
if (err.any(res)) {
|
|
1899
|
+
err.or_throw(symbols_exports.update(ctx, symbol.id, { error: String(res) }));
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
function link_symbol(ctx, symbol) {
|
|
1904
|
+
if (!symbol.text) return err.new("symbol_missing_text", { symbol_id: symbol.id, name: symbol.name });
|
|
1905
|
+
const resolutions = find_symbol_references(ctx, symbol);
|
|
1906
|
+
if (err.any(resolutions)) return resolutions;
|
|
1907
|
+
for (const resolution of resolutions) {
|
|
1908
|
+
if (resolution.type === "internal") create_internal_link(ctx, symbol, resolution);
|
|
1909
|
+
if (resolution.type === "external") create_external_link(ctx, symbol, resolution);
|
|
1910
|
+
}
|
|
1911
|
+
return symbols_exports.update(ctx, symbol.id, { state: "to_describe", error: null });
|
|
1912
|
+
}
|
|
1913
|
+
function find_symbol_references(ctx, symbol) {
|
|
1914
|
+
const file = files_exports.by_id(ctx, symbol.file_id);
|
|
1915
|
+
if (err.any(file)) return file;
|
|
1916
|
+
if (!file) return err.new("file_not_found", { path: `file_id=${symbol.file_id}` });
|
|
1917
|
+
const file_path = path5.join(ctx.project_path, file.path);
|
|
1918
|
+
const source_file = ctx.program.getSourceFile(file_path);
|
|
1919
|
+
if (!source_file) return err.new("file_not_found", { path: file_path });
|
|
1920
|
+
const symbol_node = find_symbol_node(source_file, symbol);
|
|
1921
|
+
if (!symbol_node) return err.new("symbol_node_not_found", { symbol_id: symbol.id, name: symbol.name, file_path: file.path });
|
|
1922
|
+
const type_checker = ctx.program.getTypeChecker();
|
|
1923
|
+
const resolutions = [];
|
|
1924
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1925
|
+
function visit(node) {
|
|
1926
|
+
const ts_symbol = type_checker.getSymbolAtLocation(node);
|
|
1927
|
+
if (!ts11.isIdentifier(node) || is_declaration(node.parent, node) || !ts_symbol) {
|
|
1928
|
+
ts11.forEachChild(node, visit);
|
|
1929
|
+
return;
|
|
1930
|
+
}
|
|
1931
|
+
const resolution = resolve_ts_symbol(ctx, type_checker, ts_symbol, symbol);
|
|
1932
|
+
if (resolution) {
|
|
1933
|
+
const key = `${resolution.type}:${resolution.type === "internal" ? resolution.symbol_id : resolution.external_import_id}`;
|
|
1934
|
+
if (!seen.has(key)) {
|
|
1935
|
+
seen.add(key);
|
|
1936
|
+
resolutions.push(resolution);
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
ts11.forEachChild(node, visit);
|
|
1940
|
+
}
|
|
1941
|
+
visit(symbol_node);
|
|
1942
|
+
return resolutions;
|
|
1943
|
+
}
|
|
1944
|
+
function resolve_ts_symbol(ctx, type_checker, ts_symbol, from_symbol) {
|
|
1945
|
+
let symbol_to_use = ts_symbol;
|
|
1946
|
+
if (ts_symbol.flags & ts11.SymbolFlags.Alias) {
|
|
1947
|
+
symbol_to_use = type_checker.getAliasedSymbol(ts_symbol) || symbol_to_use;
|
|
1948
|
+
}
|
|
1949
|
+
const declarations = symbol_to_use.getDeclarations();
|
|
1950
|
+
if (!declarations || declarations.length === 0 || !declarations[0]) return null;
|
|
1951
|
+
const declaration_source_file = declarations[0].getSourceFile();
|
|
1952
|
+
if (declaration_source_file.fileName.includes("/lib.") && !declaration_source_file.fileName.includes("node_modules")) {
|
|
1953
|
+
return null;
|
|
1954
|
+
}
|
|
1955
|
+
if (!declaration_source_file.fileName.startsWith(ctx.project_path) || declaration_source_file.fileName.includes("node_modules")) {
|
|
1956
|
+
const external_import_links = external_imports_exports.by_file(ctx, from_symbol.file_id);
|
|
1957
|
+
if (err.any(external_import_links)) return null;
|
|
1958
|
+
for (const ext_import of external_import_links) {
|
|
1959
|
+
const ext_dep = external_dependencies_exports.by_id(ctx, ext_import.external_dependency_id);
|
|
1960
|
+
if (err.any(ext_dep) || !ext_dep) continue;
|
|
1961
|
+
if (ext_import.alias === symbol_to_use.name || ext_dep.name === symbol_to_use.name) {
|
|
1962
|
+
return { type: "external", external_import_id: ext_import.id };
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
return null;
|
|
1966
|
+
}
|
|
1967
|
+
let file_path = declaration_source_file.fileName;
|
|
1968
|
+
if (file_path.startsWith(ctx.project_path)) {
|
|
1969
|
+
file_path = file_path.substring(ctx.project_path.length);
|
|
1970
|
+
}
|
|
1971
|
+
const file = files_exports.by_path(ctx, file_path);
|
|
1972
|
+
if (err.any(file) || !file) return null;
|
|
1973
|
+
if (file.id === from_symbol.file_id) {
|
|
1974
|
+
const file_symbols2 = symbols_exports.by_file(ctx, file.id);
|
|
1975
|
+
if (err.any(file_symbols2)) return null;
|
|
1976
|
+
for (const file_symbol of file_symbols2) {
|
|
1977
|
+
if (file_symbol.name === symbol_to_use.name && file_symbol.id !== from_symbol.id) {
|
|
1978
|
+
return { type: "internal", symbol_id: file_symbol.id, file_id: file.id };
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1981
|
+
return null;
|
|
1982
|
+
}
|
|
1983
|
+
const file_symbols = symbols_exports.by_file(ctx, file.id);
|
|
1984
|
+
if (err.any(file_symbols)) return null;
|
|
1985
|
+
for (const file_symbol of file_symbols) {
|
|
1986
|
+
if (file_symbol.name === symbol_to_use.name) {
|
|
1987
|
+
return { type: "internal", symbol_id: file_symbol.id, file_id: file.id };
|
|
1988
|
+
}
|
|
1989
|
+
}
|
|
1990
|
+
return null;
|
|
1991
|
+
}
|
|
1992
|
+
function find_symbol_node(source_file, symbol) {
|
|
1993
|
+
let result;
|
|
1994
|
+
function visit(node) {
|
|
1995
|
+
if (result) return;
|
|
1996
|
+
if (matches_symbol(node, symbol)) {
|
|
1997
|
+
result = node;
|
|
1998
|
+
return;
|
|
1999
|
+
}
|
|
2000
|
+
ts11.forEachChild(node, visit);
|
|
2001
|
+
}
|
|
2002
|
+
visit(source_file);
|
|
2003
|
+
return result;
|
|
2004
|
+
}
|
|
2005
|
+
function matches_symbol(node, symbol) {
|
|
2006
|
+
if (symbol.name === "default") {
|
|
2007
|
+
if (symbol.type === "function" && ts11.isFunctionDeclaration(node)) return has_default_modifier(node);
|
|
2008
|
+
if (symbol.type === "class" && ts11.isClassDeclaration(node)) return has_default_modifier(node);
|
|
2009
|
+
if (symbol.type === "variable") {
|
|
2010
|
+
if (ts11.isExportAssignment(node) && !node.isExportEquals) return true;
|
|
2011
|
+
if (ts11.isExportDeclaration(node) && node.exportClause && ts11.isNamedExports(node.exportClause)) {
|
|
2012
|
+
return node.exportClause.elements.some((element) => element.name.text === "default");
|
|
2013
|
+
}
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
if (symbol.type === "function") {
|
|
2017
|
+
if (ts11.isVariableStatement(node)) {
|
|
2018
|
+
const declarations = node.declarationList.declarations;
|
|
2019
|
+
for (const decl of declarations) {
|
|
2020
|
+
if (ts11.isIdentifier(decl.name) && decl.name.text === symbol.name) {
|
|
2021
|
+
const initializer = decl.initializer;
|
|
2022
|
+
if (initializer && (ts11.isArrowFunction(initializer) || ts11.isFunctionExpression(initializer))) {
|
|
2023
|
+
return true;
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2026
|
+
}
|
|
2027
|
+
return false;
|
|
2028
|
+
}
|
|
2029
|
+
if (ts11.isFunctionDeclaration(node)) {
|
|
2030
|
+
return get_node_name(node) === symbol.name;
|
|
2031
|
+
}
|
|
2032
|
+
return false;
|
|
2033
|
+
}
|
|
2034
|
+
if (symbol.type === "class") {
|
|
2035
|
+
if (!ts11.isClassDeclaration(node)) return false;
|
|
2036
|
+
return get_node_name(node) === symbol.name;
|
|
2037
|
+
}
|
|
2038
|
+
if (symbol.type === "type") {
|
|
2039
|
+
if (!ts11.isTypeAliasDeclaration(node) && !ts11.isInterfaceDeclaration(node) && !ts11.isEnumDeclaration(node)) return false;
|
|
2040
|
+
return get_node_name(node) === symbol.name;
|
|
2041
|
+
}
|
|
2042
|
+
if (symbol.type === "variable") {
|
|
2043
|
+
if (ts11.isVariableStatement(node)) {
|
|
2044
|
+
const declarations = node.declarationList.declarations;
|
|
2045
|
+
for (const decl of declarations) {
|
|
2046
|
+
if (ts11.isIdentifier(decl.name) && decl.name.text === symbol.name) {
|
|
2047
|
+
const initializer = decl.initializer;
|
|
2048
|
+
if (!initializer || !ts11.isArrowFunction(initializer) && !ts11.isFunctionExpression(initializer)) {
|
|
2049
|
+
return true;
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
}
|
|
2054
|
+
return false;
|
|
2055
|
+
}
|
|
2056
|
+
if (symbol.type === "class_method") {
|
|
2057
|
+
if (!ts11.isMethodDeclaration(node)) return false;
|
|
2058
|
+
const method_name = get_node_name(node);
|
|
2059
|
+
if (!method_name) return false;
|
|
2060
|
+
const class_node = node.parent;
|
|
2061
|
+
if (!class_node || !ts11.isClassDeclaration(class_node)) return false;
|
|
2062
|
+
const class_name = get_node_name(class_node);
|
|
2063
|
+
if (!class_name) return false;
|
|
2064
|
+
return `${class_name}.${method_name}` === symbol.name;
|
|
2065
|
+
}
|
|
2066
|
+
if (symbol.type === "class_property") {
|
|
2067
|
+
if (!ts11.isPropertyDeclaration(node)) return false;
|
|
2068
|
+
const prop_name = get_node_name(node);
|
|
2069
|
+
if (!prop_name) return false;
|
|
2070
|
+
const class_node = node.parent;
|
|
2071
|
+
if (!class_node || !ts11.isClassDeclaration(class_node)) return false;
|
|
2072
|
+
const class_name = get_node_name(class_node);
|
|
2073
|
+
if (!class_name) return false;
|
|
2074
|
+
return `${class_name}.${prop_name}` === symbol.name;
|
|
2075
|
+
}
|
|
2076
|
+
return false;
|
|
2077
|
+
}
|
|
2078
|
+
function get_node_name(node) {
|
|
2079
|
+
if (!("name" in node)) return void 0;
|
|
2080
|
+
const nodeWithName = node;
|
|
2081
|
+
if (nodeWithName.name && ts11.isIdentifier(nodeWithName.name)) {
|
|
2082
|
+
return nodeWithName.name.text;
|
|
2083
|
+
}
|
|
2084
|
+
return void 0;
|
|
2085
|
+
}
|
|
2086
|
+
function is_declaration(parent, identifier) {
|
|
2087
|
+
if (!parent) return false;
|
|
2088
|
+
if (ts11.isFunctionDeclaration(parent) && parent.name === identifier) return true;
|
|
2089
|
+
if (ts11.isClassDeclaration(parent) && parent.name === identifier) return true;
|
|
2090
|
+
if (ts11.isInterfaceDeclaration(parent) && parent.name === identifier) return true;
|
|
2091
|
+
if (ts11.isTypeAliasDeclaration(parent) && parent.name === identifier) return true;
|
|
2092
|
+
if (ts11.isEnumDeclaration(parent) && parent.name === identifier) return true;
|
|
2093
|
+
if (ts11.isVariableDeclaration(parent) && parent.name === identifier) return true;
|
|
2094
|
+
if (ts11.isParameter(parent) && parent.name === identifier) return true;
|
|
2095
|
+
if (ts11.isPropertyDeclaration(parent) && parent.name === identifier) return true;
|
|
2096
|
+
if (ts11.isMethodDeclaration(parent) && parent.name === identifier) return true;
|
|
2097
|
+
if (ts11.isTypeParameterDeclaration(parent) && parent.name === identifier) return true;
|
|
2098
|
+
if (ts11.isImportClause(parent) && parent.name === identifier) return true;
|
|
2099
|
+
if (ts11.isImportSpecifier(parent) && (parent.name === identifier || parent.propertyName === identifier)) return true;
|
|
2100
|
+
if (ts11.isNamespaceImport(parent) && parent.name === identifier) return true;
|
|
2101
|
+
return false;
|
|
2102
|
+
}
|
|
2103
|
+
function create_internal_link(ctx, from_symbol, resolution) {
|
|
2104
|
+
const existing = symbol_internal_links_exports.exists(ctx, {
|
|
2105
|
+
from_symbol_id: from_symbol.id,
|
|
2106
|
+
to_symbol_id: resolution.symbol_id
|
|
2107
|
+
});
|
|
2108
|
+
if (err.any(existing)) return existing;
|
|
2109
|
+
if (existing) return;
|
|
2110
|
+
return symbol_internal_links_exports.insert(ctx, {
|
|
2111
|
+
from_file_id: from_symbol.file_id,
|
|
2112
|
+
to_file_id: resolution.file_id,
|
|
2113
|
+
from_symbol_id: from_symbol.id,
|
|
2114
|
+
to_symbol_id: resolution.symbol_id,
|
|
2115
|
+
state: "pending"
|
|
2116
|
+
});
|
|
2117
|
+
}
|
|
2118
|
+
function create_external_link(ctx, from_symbol, resolution) {
|
|
2119
|
+
const existing = symbol_external_links_exports.exists(ctx, {
|
|
2120
|
+
symbol_id: from_symbol.id,
|
|
2121
|
+
external_import_id: resolution.external_import_id
|
|
2122
|
+
});
|
|
2123
|
+
if (err.any(existing)) return existing;
|
|
2124
|
+
if (existing) return;
|
|
2125
|
+
return symbol_external_links_exports.insert(ctx, {
|
|
2126
|
+
symbol_id: from_symbol.id,
|
|
2127
|
+
external_import_id: resolution.external_import_id
|
|
2128
|
+
});
|
|
2129
|
+
}
|
|
2130
|
+
|
|
2131
|
+
// src/update/index.ts
|
|
2132
|
+
async function update6(ctx) {
|
|
2133
|
+
await track_changes(ctx);
|
|
2134
|
+
await sync_external_dependencies(ctx);
|
|
2135
|
+
await scan_files(ctx);
|
|
2136
|
+
await link_imports(ctx);
|
|
2137
|
+
await link_symbols(ctx);
|
|
2138
|
+
}
|
|
2139
|
+
|
|
2140
|
+
// src/counts.ts
|
|
2141
|
+
import { count } from "drizzle-orm";
|
|
2142
|
+
var counts = safe_query("counts", (ctx) => {
|
|
2143
|
+
const symbol_counts = ctx.db.select({ state: symbols.state, count: count() }).from(symbols).groupBy(symbols.state).all();
|
|
2144
|
+
const file_counts = ctx.db.select({ state: files.state, count: count() }).from(files).groupBy(files.state).all();
|
|
2145
|
+
const dir_counts = ctx.db.select({ state: directories.state, count: count() }).from(directories).groupBy(directories.state).all();
|
|
2146
|
+
const dep_counts = ctx.db.select({ state: external_dependencies.state, count: count() }).from(external_dependencies).groupBy(external_dependencies.state).all();
|
|
2147
|
+
return {
|
|
2148
|
+
symbols: get_groups(symbol_counts, ["to_link", "to_describe", "ready"]),
|
|
2149
|
+
files: get_groups(file_counts, ["to_scan", "to_describe", "ready"]),
|
|
2150
|
+
directories: get_groups(dir_counts, ["to_describe", "ready"]),
|
|
2151
|
+
dependencies: get_groups(dep_counts, ["to_describe", "ready"])
|
|
2152
|
+
};
|
|
2153
|
+
});
|
|
2154
|
+
function get_groups(items, states) {
|
|
2155
|
+
const groups = { total: 0 };
|
|
2156
|
+
for (const state of states) groups[state] = 0;
|
|
2157
|
+
for (const item of items) {
|
|
2158
|
+
if (!states.includes(item.state)) continue;
|
|
2159
|
+
groups[item.state] = (groups[item.state] || 0) + item.count;
|
|
2160
|
+
groups.total += item.count;
|
|
2161
|
+
}
|
|
2162
|
+
return groups;
|
|
2163
|
+
}
|
|
2164
|
+
|
|
2165
|
+
// src/files.ts
|
|
2166
|
+
function files_wiki(ctx) {
|
|
2167
|
+
return {
|
|
2168
|
+
get: (id) => get2(ctx, id),
|
|
2169
|
+
search: (options) => search5(ctx, options),
|
|
2170
|
+
set_description: (id, description) => set_description(ctx, id, description),
|
|
2171
|
+
imported_by_file: (file_id, options) => imported_by_file(ctx, file_id, options),
|
|
2172
|
+
importing_file: (file_id, options) => importing_file(ctx, file_id, options),
|
|
2173
|
+
importing_dependency: (dependency_id, options) => importing_dependency(ctx, dependency_id, options)
|
|
2174
|
+
};
|
|
2175
|
+
}
|
|
2176
|
+
function get2(ctx, id) {
|
|
2177
|
+
return err.or_throw(files_exports.by_id(ctx, id)) ?? null;
|
|
2178
|
+
}
|
|
2179
|
+
function search5(ctx, options) {
|
|
2180
|
+
return err.or_throw(files_exports.search(ctx, options));
|
|
2181
|
+
}
|
|
2182
|
+
function set_description(ctx, id, description) {
|
|
2183
|
+
err.or_throw(files_exports.update(ctx, id, { description }));
|
|
2184
|
+
}
|
|
2185
|
+
function imported_by_file(ctx, file_id, options = {}) {
|
|
2186
|
+
let imported_files = err.or_throw(files_exports.imported_by(ctx, file_id, options.select));
|
|
2187
|
+
if (options.deep) {
|
|
2188
|
+
imported_files = err.or_throw(
|
|
2189
|
+
expand({
|
|
2190
|
+
items: imported_files,
|
|
2191
|
+
get_children: (file) => files_exports.imported_by(ctx, file.id, options.select),
|
|
2192
|
+
get_key: (file) => file.id
|
|
2193
|
+
})
|
|
2194
|
+
);
|
|
2195
|
+
}
|
|
2196
|
+
const start = options.offset ?? 0;
|
|
2197
|
+
const end = options.limit ? start + options.limit : imported_files.length;
|
|
2198
|
+
return imported_files.slice(start, end);
|
|
2199
|
+
}
|
|
2200
|
+
function importing_file(ctx, file_id, options = {}) {
|
|
2201
|
+
let importing_files = err.or_throw(files_exports.importing(ctx, file_id, options.select));
|
|
2202
|
+
if (options.deep) {
|
|
2203
|
+
importing_files = err.or_throw(
|
|
2204
|
+
expand({
|
|
2205
|
+
items: importing_files,
|
|
2206
|
+
get_children: (file) => files_exports.importing(ctx, file.id, options.select),
|
|
2207
|
+
get_key: (file) => file.id
|
|
2208
|
+
})
|
|
2209
|
+
);
|
|
2210
|
+
}
|
|
2211
|
+
const start = options.offset ?? 0;
|
|
2212
|
+
const end = options.limit ? start + options.limit : importing_files.length;
|
|
2213
|
+
return importing_files.slice(start, end);
|
|
2214
|
+
}
|
|
2215
|
+
function importing_dependency(ctx, dependency_id, options = {}) {
|
|
2216
|
+
let files_using_dependency = err.or_throw(files_exports.using_dependency(ctx, dependency_id, options.select));
|
|
2217
|
+
if (options.deep) {
|
|
2218
|
+
files_using_dependency = err.or_throw(
|
|
2219
|
+
expand({
|
|
2220
|
+
items: files_using_dependency,
|
|
2221
|
+
get_children: (file) => files_exports.importing(ctx, file.id, options.select),
|
|
2222
|
+
get_key: (file) => file.id
|
|
2223
|
+
})
|
|
2224
|
+
);
|
|
2225
|
+
}
|
|
2226
|
+
const start = options.offset ?? 0;
|
|
2227
|
+
const end = options.limit ? start + options.limit : files_using_dependency.length;
|
|
2228
|
+
return files_using_dependency.slice(start, end);
|
|
2229
|
+
}
|
|
2230
|
+
|
|
2231
|
+
// src/symbols.ts
|
|
2232
|
+
function symbols_wiki(ctx) {
|
|
2233
|
+
return {
|
|
2234
|
+
get: (id) => get3(ctx, id),
|
|
2235
|
+
search: (options) => search6(ctx, options),
|
|
2236
|
+
set_description: (id, description) => set_description2(ctx, id, description),
|
|
2237
|
+
referencing_symbol: (symbol_id, options) => referencing_symbol(ctx, symbol_id, options),
|
|
2238
|
+
referenced_by_symbol: (symbol_id, options) => referenced_by_symbol(ctx, symbol_id, options),
|
|
2239
|
+
using_dependency: (dependency_id, options) => using_dependency3(ctx, dependency_id, options)
|
|
2240
|
+
};
|
|
2241
|
+
}
|
|
2242
|
+
function get3(ctx, id) {
|
|
2243
|
+
return err.or_throw(symbols_exports.by_id(ctx, id)) ?? null;
|
|
2244
|
+
}
|
|
2245
|
+
function search6(ctx, options) {
|
|
2246
|
+
return err.or_throw(symbols_exports.search(ctx, options));
|
|
2247
|
+
}
|
|
2248
|
+
function set_description2(ctx, id, description) {
|
|
2249
|
+
err.or_throw(symbols_exports.update(ctx, id, { description }));
|
|
2250
|
+
}
|
|
2251
|
+
function referenced_by_symbol(ctx, symbol_id, options = {}) {
|
|
2252
|
+
let referenced_symbols = err.or_throw(symbols_exports.referenced_by(ctx, symbol_id, options.select));
|
|
2253
|
+
if (options.deep) {
|
|
2254
|
+
referenced_symbols = err.or_throw(
|
|
2255
|
+
expand({
|
|
2256
|
+
items: referenced_symbols,
|
|
2257
|
+
get_children: (symbol) => symbols_exports.referenced_by(ctx, symbol.id, options.select),
|
|
2258
|
+
get_key: (symbol) => symbol.id
|
|
2259
|
+
})
|
|
2260
|
+
);
|
|
2261
|
+
}
|
|
2262
|
+
const start = options.offset ?? 0;
|
|
2263
|
+
const end = options.limit ? start + options.limit : referenced_symbols.length;
|
|
2264
|
+
return referenced_symbols.slice(start, end);
|
|
2265
|
+
}
|
|
2266
|
+
function referencing_symbol(ctx, symbol_id, options = {}) {
|
|
2267
|
+
let referencing_symbols = err.or_throw(symbols_exports.referencing(ctx, symbol_id, options.select));
|
|
2268
|
+
if (options.deep) {
|
|
2269
|
+
referencing_symbols = err.or_throw(
|
|
2270
|
+
expand({
|
|
2271
|
+
items: referencing_symbols,
|
|
2272
|
+
get_children: (symbol) => symbols_exports.referencing(ctx, symbol.id, options.select),
|
|
2273
|
+
get_key: (symbol) => symbol.id
|
|
2274
|
+
})
|
|
2275
|
+
);
|
|
2276
|
+
}
|
|
2277
|
+
const start = options.offset ?? 0;
|
|
2278
|
+
const end = options.limit ? start + options.limit : referencing_symbols.length;
|
|
2279
|
+
return referencing_symbols.slice(start, end);
|
|
2280
|
+
}
|
|
2281
|
+
function using_dependency3(ctx, dependency_id, options = {}) {
|
|
2282
|
+
let symbols_using_dep = err.or_throw(symbols_exports.using_dependency(ctx, dependency_id, options.select));
|
|
2283
|
+
if (options.deep) {
|
|
2284
|
+
symbols_using_dep = err.or_throw(
|
|
2285
|
+
expand({
|
|
2286
|
+
items: symbols_using_dep,
|
|
2287
|
+
get_children: (symbol) => symbols_exports.referencing(ctx, symbol.id, options.select),
|
|
2288
|
+
get_key: (symbol) => symbol.id
|
|
2289
|
+
})
|
|
2290
|
+
);
|
|
2291
|
+
}
|
|
2292
|
+
const start = options.offset ?? 0;
|
|
2293
|
+
const end = options.limit ? start + options.limit : symbols_using_dep.length;
|
|
2294
|
+
return symbols_using_dep.slice(start, end);
|
|
2295
|
+
}
|
|
2296
|
+
|
|
2297
|
+
// src/directories.ts
|
|
2298
|
+
function directories_wiki(ctx) {
|
|
2299
|
+
return {
|
|
2300
|
+
get: (id) => get4(ctx, id),
|
|
2301
|
+
search: (options) => search7(ctx, options),
|
|
2302
|
+
set_description: (id, description) => set_description3(ctx, id, description),
|
|
2303
|
+
children: (parent_id, options) => children(ctx, parent_id, options),
|
|
2304
|
+
files: (directory_id, options) => directory_files(ctx, directory_id, options)
|
|
2305
|
+
};
|
|
2306
|
+
}
|
|
2307
|
+
function get4(ctx, id) {
|
|
2308
|
+
return err.or_throw(directories_exports.by_id(ctx, id)) ?? null;
|
|
2309
|
+
}
|
|
2310
|
+
function search7(ctx, options) {
|
|
2311
|
+
return err.or_throw(directories_exports.search(ctx, options));
|
|
2312
|
+
}
|
|
2313
|
+
function set_description3(ctx, id, description) {
|
|
2314
|
+
err.or_throw(directories_exports.update(ctx, id, { description }));
|
|
2315
|
+
}
|
|
2316
|
+
function children(ctx, parent_id, options = {}) {
|
|
2317
|
+
let child_directories = err.or_throw(directories_exports.search(ctx, { select: options.select, where: { parent_id }, limit: 1e4 }));
|
|
2318
|
+
if (options.deep) {
|
|
2319
|
+
child_directories = err.or_throw(
|
|
2320
|
+
expand({
|
|
2321
|
+
items: child_directories,
|
|
2322
|
+
get_children: (dir) => directories_exports.search(ctx, { select: options.select, where: { parent_id: dir.id }, limit: 1e4 }),
|
|
2323
|
+
get_key: (dir) => dir.id
|
|
2324
|
+
})
|
|
2325
|
+
);
|
|
2326
|
+
}
|
|
2327
|
+
const start = options.offset ?? 0;
|
|
2328
|
+
const end = options.limit ? start + options.limit : child_directories.length;
|
|
2329
|
+
return child_directories.slice(start, end);
|
|
2330
|
+
}
|
|
2331
|
+
function directory_files(ctx, directory_id, options = {}) {
|
|
2332
|
+
let files_list = err.or_throw(files_exports.search(ctx, { select: options.select, where: { directory_id }, limit: 1e4 }));
|
|
2333
|
+
if (options.deep) {
|
|
2334
|
+
const all_subdirs = err.or_throw(
|
|
2335
|
+
expand({
|
|
2336
|
+
items: err.or_throw(directories_exports.search(ctx, { select: ["id"], where: { parent_id: directory_id }, limit: 1e4 })),
|
|
2337
|
+
get_children: (dir) => directories_exports.search(ctx, { select: ["id"], where: { parent_id: dir.id }, limit: 1e4 }),
|
|
2338
|
+
get_key: (dir) => dir.id
|
|
2339
|
+
})
|
|
2340
|
+
);
|
|
2341
|
+
for (const subdir of all_subdirs) {
|
|
2342
|
+
const subdir_files = err.or_throw(
|
|
2343
|
+
files_exports.search(ctx, { select: options.select, where: { directory_id: subdir.id }, limit: 1e4 })
|
|
2344
|
+
);
|
|
2345
|
+
subdir_files.forEach((x) => files_list.push(x));
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2348
|
+
const start = options.offset ?? 0;
|
|
2349
|
+
const end = options.limit ? start + options.limit : files_list.length;
|
|
2350
|
+
return files_list.slice(start, end);
|
|
2351
|
+
}
|
|
2352
|
+
|
|
2353
|
+
// src/dependencies.ts
|
|
2354
|
+
function dependencies_wiki(ctx) {
|
|
2355
|
+
return {
|
|
2356
|
+
get: (id) => get5(ctx, id),
|
|
2357
|
+
search: (options) => search8(ctx, options),
|
|
2358
|
+
set_description: (id, description) => set_description4(ctx, id, description),
|
|
2359
|
+
used_by_file: (file_id, options) => used_by_file2(ctx, file_id, options),
|
|
2360
|
+
used_by_symbol: (symbol_id, options) => used_by_symbol2(ctx, symbol_id, options)
|
|
2361
|
+
};
|
|
2362
|
+
}
|
|
2363
|
+
function get5(ctx, id) {
|
|
2364
|
+
return err.or_throw(external_dependencies_exports.by_id(ctx, id)) ?? null;
|
|
2365
|
+
}
|
|
2366
|
+
function search8(ctx, options) {
|
|
2367
|
+
return err.or_throw(external_dependencies_exports.search(ctx, options));
|
|
2368
|
+
}
|
|
2369
|
+
function set_description4(ctx, id, description) {
|
|
2370
|
+
err.or_throw(external_dependencies_exports.update(ctx, id, { description, state: "ready", error: null }));
|
|
2371
|
+
}
|
|
2372
|
+
function used_by_file2(ctx, file_id, options) {
|
|
2373
|
+
return err.or_throw(external_dependencies_exports.used_by_file(ctx, file_id, options?.select));
|
|
2374
|
+
}
|
|
2375
|
+
function used_by_symbol2(ctx, symbol_id, options) {
|
|
2376
|
+
return err.or_throw(external_dependencies_exports.used_by_symbol(ctx, symbol_id, options?.select));
|
|
2377
|
+
}
|
|
2378
|
+
|
|
2379
|
+
// src/index.ts
|
|
2380
|
+
async function create(config) {
|
|
2381
|
+
const ctx = await context_from_config(config);
|
|
2382
|
+
return {
|
|
2383
|
+
config,
|
|
2384
|
+
update: () => update6(ctx),
|
|
2385
|
+
counts: () => err.or_throw(counts(ctx)),
|
|
2386
|
+
files: files_wiki(ctx),
|
|
2387
|
+
symbols: symbols_wiki(ctx),
|
|
2388
|
+
directories: directories_wiki(ctx),
|
|
2389
|
+
dependencies: dependencies_wiki(ctx)
|
|
2390
|
+
};
|
|
2391
|
+
}
|
|
2392
|
+
async function load(db_path) {
|
|
2393
|
+
const ctx = await context_from_db(db_path);
|
|
2394
|
+
const stored = ctx.db.select().from(schema_exports.configs).get();
|
|
2395
|
+
const config = {
|
|
2396
|
+
db_path,
|
|
2397
|
+
project_path: stored.project_path,
|
|
2398
|
+
description: stored.description ?? void 0,
|
|
2399
|
+
package_json_path: stored.package_json_path ?? void 0,
|
|
2400
|
+
node_modules_paths: stored.node_modules_paths ? JSON.parse(stored.node_modules_paths) : void 0
|
|
2401
|
+
};
|
|
2402
|
+
return {
|
|
2403
|
+
config,
|
|
2404
|
+
update: () => update6(ctx),
|
|
2405
|
+
counts: () => err.or_throw(counts(ctx)),
|
|
2406
|
+
files: files_wiki(ctx),
|
|
2407
|
+
symbols: symbols_wiki(ctx),
|
|
2408
|
+
directories: directories_wiki(ctx),
|
|
2409
|
+
dependencies: dependencies_wiki(ctx)
|
|
2410
|
+
};
|
|
2411
|
+
}
|
|
2412
|
+
export {
|
|
2413
|
+
context_from_config,
|
|
2414
|
+
context_from_db,
|
|
2415
|
+
create,
|
|
2416
|
+
load
|
|
2417
|
+
};
|
|
2418
|
+
//# sourceMappingURL=index.js.map
|