supabase-strict-check 0.1.0

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.
@@ -0,0 +1,335 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.loc = loc;
7
+ exports.propName = propName;
8
+ exports.unwrapExpr = unwrapExpr;
9
+ exports.evalString = evalString;
10
+ exports.evalStrings = evalStrings;
11
+ exports.stringish = stringish;
12
+ exports.bindingHasIdent = bindingHasIdent;
13
+ exports.enclosingParam = enclosingParam;
14
+ exports.isParameterIdentifier = isParameterIdentifier;
15
+ exports.callReceiver = callReceiver;
16
+ exports.isArrayFrom = isArrayFrom;
17
+ exports.chainProps = chainProps;
18
+ exports.collectChain = collectChain;
19
+ exports.chainRoot = chainRoot;
20
+ exports.isChainTail = isChainTail;
21
+ exports.assignedName = assignedName;
22
+ exports.objectLiteral = objectLiteral;
23
+ exports.objectKeys = objectKeys;
24
+ exports.optionString = optionString;
25
+ exports.literalValue = literalValue;
26
+ const typescript_1 = __importDefault(require("typescript"));
27
+ const program_1 = require("../lib/program");
28
+ const paths_1 = require("./paths");
29
+ function loc(sf, node) {
30
+ const { line, character } = sf.getLineAndCharacterOfPosition(node.getStart(sf));
31
+ return { line: line + 1, column: character + 1 };
32
+ }
33
+ function propName(name) {
34
+ if (typescript_1.default.isIdentifier(name) || typescript_1.default.isStringLiteral(name) || typescript_1.default.isNumericLiteral(name)) {
35
+ return name.text;
36
+ }
37
+ return null;
38
+ }
39
+ function unwrapExpr(expr) {
40
+ let current = expr;
41
+ for (;;) {
42
+ if (typescript_1.default.isParenthesizedExpression(current)) {
43
+ current = current.expression;
44
+ continue;
45
+ }
46
+ if (typescript_1.default.isAsExpression(current) || typescript_1.default.isTypeAssertionExpression(current) || typescript_1.default.isSatisfiesExpression(current)) {
47
+ current = current.expression;
48
+ continue;
49
+ }
50
+ if (typescript_1.default.isNonNullExpression(current)) {
51
+ current = current.expression;
52
+ continue;
53
+ }
54
+ return current;
55
+ }
56
+ }
57
+ function evalString(expr, consts, opts) {
58
+ const node = unwrapExpr(expr);
59
+ if (typescript_1.default.isStringLiteral(node) || typescript_1.default.isNoSubstitutionTemplateLiteral(node)) {
60
+ return node.text;
61
+ }
62
+ if (typescript_1.default.isBinaryExpression(node) && node.operatorToken.kind === typescript_1.default.SyntaxKind.PlusToken) {
63
+ const left = evalString(node.left, consts, opts);
64
+ const right = evalString(node.right, consts, opts);
65
+ if (left != null && right != null)
66
+ return left + right;
67
+ return null;
68
+ }
69
+ if (typescript_1.default.isTemplateExpression(node)) {
70
+ let out = node.head.text;
71
+ for (const span of node.templateSpans) {
72
+ const inner = evalString(span.expression, consts, opts);
73
+ if (inner == null)
74
+ return null;
75
+ out += inner + span.literal.text;
76
+ }
77
+ return out;
78
+ }
79
+ if (typescript_1.default.isIdentifier(node)) {
80
+ if (opts?.subst?.has(node.text))
81
+ return opts.subst.get(node.text) ?? null;
82
+ if (consts.has(node.text))
83
+ return consts.get(node.text) ?? null;
84
+ if (opts?.checker) {
85
+ const lits = (0, program_1.stringLiteralsFromType)(opts.checker.getTypeAtLocation(node));
86
+ if (lits?.length === 1)
87
+ return lits[0];
88
+ }
89
+ return null;
90
+ }
91
+ if (opts?.checker) {
92
+ const lits = (0, program_1.stringLiteralsFromType)(opts.checker.getTypeAtLocation(node));
93
+ if (lits?.length === 1)
94
+ return lits[0];
95
+ }
96
+ return null;
97
+ }
98
+ /** All string-literal possibilities (unions / `a ? "id" : "slug"`). */
99
+ function evalStrings(expr, consts, opts) {
100
+ const one = evalString(expr, consts, opts);
101
+ if (one != null)
102
+ return [one];
103
+ const node = unwrapExpr(expr);
104
+ if (typescript_1.default.isConditionalExpression(node)) {
105
+ const left = evalStrings(node.whenTrue, consts, opts);
106
+ const right = evalStrings(node.whenFalse, consts, opts);
107
+ if (left && right)
108
+ return [...left, ...right];
109
+ }
110
+ if (opts?.checker) {
111
+ return (0, program_1.stringLiteralsFromType)(opts.checker.getTypeAtLocation(node));
112
+ }
113
+ return null;
114
+ }
115
+ function stringish(expr, consts, opts) {
116
+ const complete = evalString(expr, consts, opts);
117
+ if (complete != null)
118
+ return { text: complete, complete: true };
119
+ const node = unwrapExpr(expr);
120
+ if (typescript_1.default.isTemplateExpression(node)) {
121
+ let out = node.head.text;
122
+ for (const span of node.templateSpans) {
123
+ const inner = evalString(span.expression, consts, opts);
124
+ out += (inner ?? "") + span.literal.text;
125
+ }
126
+ return { text: out, complete: false };
127
+ }
128
+ if (typescript_1.default.isBinaryExpression(node) && node.operatorToken.kind === typescript_1.default.SyntaxKind.PlusToken) {
129
+ const left = stringish(node.left, consts, opts);
130
+ const right = stringish(node.right, consts, opts);
131
+ if (!left || !right)
132
+ return null;
133
+ return { text: left.text + right.text, complete: left.complete && right.complete };
134
+ }
135
+ return null;
136
+ }
137
+ function bindingHasIdent(name, ident) {
138
+ if (typescript_1.default.isIdentifier(name))
139
+ return name.text === ident;
140
+ if (typescript_1.default.isObjectBindingPattern(name) || typescript_1.default.isArrayBindingPattern(name)) {
141
+ return name.elements.some((el) => {
142
+ if (typescript_1.default.isOmittedExpression(el))
143
+ return false;
144
+ return bindingHasIdent(el.name, ident);
145
+ });
146
+ }
147
+ return false;
148
+ }
149
+ function enclosingParam(ident) {
150
+ let current = ident.parent;
151
+ while (current) {
152
+ if (typescript_1.default.isFunctionLike(current) && "body" in current) {
153
+ const fn = current;
154
+ const index = fn.parameters.findIndex((p) => bindingHasIdent(p.name, ident.text));
155
+ if (index >= 0)
156
+ return { fn, index };
157
+ }
158
+ current = current.parent;
159
+ }
160
+ return null;
161
+ }
162
+ function isParameterIdentifier(ident) {
163
+ return enclosingParam(ident) != null;
164
+ }
165
+ function callReceiver(call) {
166
+ if (typescript_1.default.isPropertyAccessExpression(call.expression))
167
+ return call.expression.expression;
168
+ if (typescript_1.default.isIdentifier(call.expression))
169
+ return call.expression;
170
+ return undefined;
171
+ }
172
+ function isArrayFrom(fromCall) {
173
+ const receiver = callReceiver(fromCall.node);
174
+ return Boolean(receiver && typescript_1.default.isIdentifier(receiver) && receiver.text === "Array");
175
+ }
176
+ function chainProps(expr) {
177
+ const names = [];
178
+ let current = expr;
179
+ while (current) {
180
+ if (typescript_1.default.isCallExpression(current)) {
181
+ current = current.expression;
182
+ continue;
183
+ }
184
+ if (typescript_1.default.isPropertyAccessExpression(current)) {
185
+ names.push(current.name.text);
186
+ current = current.expression;
187
+ continue;
188
+ }
189
+ if (typescript_1.default.isIdentifier(current)) {
190
+ names.push(current.text);
191
+ break;
192
+ }
193
+ if (typescript_1.default.isParenthesizedExpression(current) || typescript_1.default.isAsExpression(current) || typescript_1.default.isNonNullExpression(current)) {
194
+ current = current.expression;
195
+ continue;
196
+ }
197
+ break;
198
+ }
199
+ return names;
200
+ }
201
+ function collectChain(tail) {
202
+ const methods = [];
203
+ let current = tail;
204
+ while (current && typescript_1.default.isCallExpression(current)) {
205
+ if (typescript_1.default.isPropertyAccessExpression(current.expression)) {
206
+ const name = current.expression.name.text;
207
+ if (!paths_1.QUERY_METHODS.has(name))
208
+ break;
209
+ methods.push({
210
+ name,
211
+ args: [...current.arguments],
212
+ node: current,
213
+ });
214
+ current = current.expression.expression;
215
+ continue;
216
+ }
217
+ break;
218
+ }
219
+ methods.reverse();
220
+ return methods;
221
+ }
222
+ function chainRoot(tail) {
223
+ let current = tail;
224
+ while (current && typescript_1.default.isCallExpression(current)) {
225
+ if (typescript_1.default.isPropertyAccessExpression(current.expression)) {
226
+ const name = current.expression.name.text;
227
+ if (!paths_1.QUERY_METHODS.has(name))
228
+ break;
229
+ current = current.expression.expression;
230
+ continue;
231
+ }
232
+ break;
233
+ }
234
+ return current ? unwrapExpr(current) : undefined;
235
+ }
236
+ function isChainTail(node) {
237
+ const parent = node.parent;
238
+ if (typescript_1.default.isPropertyAccessExpression(parent)
239
+ && typescript_1.default.isCallExpression(parent.parent)
240
+ && parent.parent.expression === parent
241
+ && paths_1.QUERY_METHODS.has(parent.name.text)) {
242
+ return false;
243
+ }
244
+ return true;
245
+ }
246
+ function assignedName(tail) {
247
+ let current = tail;
248
+ while (typescript_1.default.isAsExpression(current.parent)
249
+ || typescript_1.default.isParenthesizedExpression(current.parent)
250
+ || typescript_1.default.isSatisfiesExpression(current.parent)
251
+ || typescript_1.default.isNonNullExpression(current.parent)
252
+ || typescript_1.default.isAwaitExpression(current.parent)) {
253
+ current = current.parent;
254
+ }
255
+ const parent = current.parent;
256
+ if (typescript_1.default.isVariableDeclaration(parent) && typescript_1.default.isIdentifier(parent.name)) {
257
+ return parent.name.text;
258
+ }
259
+ if (typescript_1.default.isBinaryExpression(parent)
260
+ && parent.operatorToken.kind === typescript_1.default.SyntaxKind.EqualsToken
261
+ && typescript_1.default.isIdentifier(parent.left)) {
262
+ return parent.left.text;
263
+ }
264
+ return null;
265
+ }
266
+ function objectLiteral(expr) {
267
+ if (!expr)
268
+ return null;
269
+ const node = unwrapExpr(expr);
270
+ return typescript_1.default.isObjectLiteralExpression(node) ? node : null;
271
+ }
272
+ function objectKeys(expr) {
273
+ const obj = objectLiteral(expr);
274
+ if (!obj) {
275
+ const node = expr ? unwrapExpr(expr) : null;
276
+ if (node && typescript_1.default.isArrayLiteralExpression(node)) {
277
+ const keys = new Set();
278
+ let hasSpread = false;
279
+ let anyObj = false;
280
+ for (const el of node.elements) {
281
+ const parsed = objectKeys(el);
282
+ if (!parsed)
283
+ continue;
284
+ anyObj = true;
285
+ parsed.keys.forEach((k) => keys.add(k));
286
+ hasSpread = hasSpread || parsed.hasSpread;
287
+ }
288
+ return anyObj ? { keys: [...keys], hasSpread } : null;
289
+ }
290
+ return null;
291
+ }
292
+ const keys = [];
293
+ let hasSpread = false;
294
+ for (const prop of obj.properties) {
295
+ if (typescript_1.default.isSpreadAssignment(prop)) {
296
+ hasSpread = true;
297
+ continue;
298
+ }
299
+ if (typescript_1.default.isPropertyAssignment(prop) || typescript_1.default.isShorthandPropertyAssignment(prop)) {
300
+ const name = propName(prop.name);
301
+ if (name)
302
+ keys.push(name);
303
+ }
304
+ }
305
+ return { keys, hasSpread };
306
+ }
307
+ function optionString(args, options, consts, opts) {
308
+ const obj = args.length >= 2 ? objectLiteral(args[1]) : null;
309
+ if (!obj)
310
+ return null;
311
+ for (const prop of obj.properties) {
312
+ if (!typescript_1.default.isPropertyAssignment(prop))
313
+ continue;
314
+ const key = propName(prop.name);
315
+ if (!key || !options.includes(key))
316
+ continue;
317
+ return evalString(prop.initializer, consts, opts);
318
+ }
319
+ return null;
320
+ }
321
+ function literalValue(expr, consts, opts) {
322
+ const node = unwrapExpr(expr);
323
+ const str = evalString(node, consts, opts);
324
+ if (str != null)
325
+ return str;
326
+ if (typescript_1.default.isNumericLiteral(node))
327
+ return Number(node.text);
328
+ if (node.kind === typescript_1.default.SyntaxKind.TrueKeyword)
329
+ return true;
330
+ if (node.kind === typescript_1.default.SyntaxKind.FalseKeyword)
331
+ return false;
332
+ if (node.kind === typescript_1.default.SyntaxKind.NullKeyword)
333
+ return null;
334
+ return undefined;
335
+ }
@@ -0,0 +1,14 @@
1
+ import ts from "typescript";
2
+ export declare function factoryName(expr: ts.Expression): string | null;
3
+ export declare function isClientFactoryCall(expr: ts.Expression): boolean;
4
+ export declare function isSupabaseClientType(checker: ts.TypeChecker, type: ts.Type, seen?: Set<ts.Type>): boolean;
5
+ export declare function exprLooksLikeClient(checker: ts.TypeChecker, expr: ts.Expression): boolean;
6
+ /**
7
+ * Discover identifiers that hold a Supabase client: factory calls
8
+ * (`createClient`, `createBrowserClient`, …) and values typed as `SupabaseClient`.
9
+ */
10
+ export declare function collectClientNames(program: ts.Program, checker: ts.TypeChecker): Set<string>;
11
+ export declare function looksLikeClient(tail: ts.CallExpression, opts?: {
12
+ checker?: ts.TypeChecker;
13
+ names?: Set<string>;
14
+ }): boolean;
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.factoryName = factoryName;
7
+ exports.isClientFactoryCall = isClientFactoryCall;
8
+ exports.isSupabaseClientType = isSupabaseClientType;
9
+ exports.exprLooksLikeClient = exprLooksLikeClient;
10
+ exports.collectClientNames = collectClientNames;
11
+ exports.looksLikeClient = looksLikeClient;
12
+ const typescript_1 = __importDefault(require("typescript"));
13
+ const ast_1 = require("./ast");
14
+ const paths_1 = require("./paths");
15
+ /** Official / common factories that return a Supabase client. */
16
+ const CLIENT_FACTORIES = new Set([
17
+ "createClient",
18
+ "createBrowserClient",
19
+ "createServerClient",
20
+ "createTypedClient",
21
+ "createServerComponentClient",
22
+ "createClientComponentClient",
23
+ "createRouteHandlerClient",
24
+ "createMiddlewareClient",
25
+ "createServiceRoleClient",
26
+ ]);
27
+ const CLIENT_TYPE_NAME = /SupabaseClient/;
28
+ function factoryName(expr) {
29
+ const node = (0, ast_1.unwrapExpr)(expr);
30
+ if (!typescript_1.default.isCallExpression(node))
31
+ return null;
32
+ const callee = (0, ast_1.unwrapExpr)(node.expression);
33
+ if (typescript_1.default.isIdentifier(callee))
34
+ return callee.text;
35
+ if (typescript_1.default.isPropertyAccessExpression(callee))
36
+ return callee.name.text;
37
+ return null;
38
+ }
39
+ function isClientFactoryCall(expr) {
40
+ const name = factoryName(expr);
41
+ return name != null && CLIENT_FACTORIES.has(name);
42
+ }
43
+ function isSupabaseClientType(checker, type, seen = new Set()) {
44
+ if (seen.has(type))
45
+ return false;
46
+ seen.add(type);
47
+ if (type.flags & (typescript_1.default.TypeFlags.Any | typescript_1.default.TypeFlags.Unknown | typescript_1.default.TypeFlags.Never | typescript_1.default.TypeFlags.Null | typescript_1.default.TypeFlags.Undefined)) {
48
+ return false;
49
+ }
50
+ if (type.isUnionOrIntersection()) {
51
+ return type.types.some((t) => isSupabaseClientType(checker, t, seen));
52
+ }
53
+ const apparent = checker.getApparentType(type);
54
+ if (apparent !== type && isSupabaseClientType(checker, apparent, seen))
55
+ return true;
56
+ const symbolName = type.aliasSymbol?.getName() ?? type.getSymbol()?.getName() ?? "";
57
+ if (CLIENT_TYPE_NAME.test(symbolName))
58
+ return true;
59
+ const props = new Set(apparent.getProperties().map((p) => p.getName()));
60
+ return props.has("from") && (props.has("rpc") || (props.has("schema") && props.has("auth")));
61
+ }
62
+ function exprLooksLikeClient(checker, expr) {
63
+ if (isClientFactoryCall(expr))
64
+ return true;
65
+ return isSupabaseClientType(checker, checker.getTypeAtLocation(expr));
66
+ }
67
+ function bindingName(name) {
68
+ if (typescript_1.default.isIdentifier(name) || typescript_1.default.isStringLiteral(name) || typescript_1.default.isNumericLiteral(name))
69
+ return name.text;
70
+ return null;
71
+ }
72
+ function shouldKeepName(name) {
73
+ return !paths_1.QUERY_METHODS.has(name) && !paths_1.SKIP_CHAIN_PROPS.has(name) && name !== "from";
74
+ }
75
+ /**
76
+ * Discover identifiers that hold a Supabase client: factory calls
77
+ * (`createClient`, `createBrowserClient`, …) and values typed as `SupabaseClient`.
78
+ */
79
+ function collectClientNames(program, checker) {
80
+ const names = new Set();
81
+ const add = (name) => {
82
+ if (name && shouldKeepName(name))
83
+ names.add(name);
84
+ };
85
+ const consider = (name, node, init) => {
86
+ if (!name)
87
+ return;
88
+ if (init && isClientFactoryCall(init)) {
89
+ add(name);
90
+ return;
91
+ }
92
+ if (isSupabaseClientType(checker, checker.getTypeAtLocation(node)))
93
+ add(name);
94
+ };
95
+ for (const sf of program.getSourceFiles()) {
96
+ if (sf.isDeclarationFile || sf.fileName.includes("node_modules"))
97
+ continue;
98
+ const visit = (node) => {
99
+ if (typescript_1.default.isVariableDeclaration(node) && typescript_1.default.isIdentifier(node.name)) {
100
+ consider(node.name.text, node.name, node.initializer);
101
+ }
102
+ else if (typescript_1.default.isPropertyAssignment(node)) {
103
+ consider(bindingName(node.name), node.name, node.initializer);
104
+ }
105
+ else if (typescript_1.default.isShorthandPropertyAssignment(node)) {
106
+ consider(node.name.text, node.name);
107
+ }
108
+ else if (typescript_1.default.isImportSpecifier(node)) {
109
+ consider(node.name.text, node.name);
110
+ }
111
+ else if (typescript_1.default.isFunctionDeclaration(node) && node.name) {
112
+ const sig = checker.getTypeAtLocation(node);
113
+ const ret = sig.getCallSignatures()[0]?.getReturnType();
114
+ if (ret && isSupabaseClientType(checker, ret))
115
+ add(node.name.text);
116
+ }
117
+ typescript_1.default.forEachChild(node, visit);
118
+ };
119
+ visit(sf);
120
+ }
121
+ return names;
122
+ }
123
+ function looksLikeClient(tail, opts) {
124
+ const props = (0, ast_1.chainProps)(tail.expression);
125
+ if (props.some((n) => CLIENT_FACTORIES.has(n)))
126
+ return true;
127
+ if (opts?.names && props.some((n) => opts.names.has(n)))
128
+ return true;
129
+ if (opts?.checker) {
130
+ const root = (0, ast_1.chainRoot)(tail);
131
+ if (root && exprLooksLikeClient(opts.checker, root))
132
+ return true;
133
+ }
134
+ return false;
135
+ }
@@ -0,0 +1,6 @@
1
+ import ts from "typescript";
2
+ export declare function collectSourceFiles(root: string, typesFile: string): string[];
3
+ /** Module-level `const X = "..."`, including re-exports via named imports. */
4
+ export declare function loadImportedConsts(files: string[], srcDir: string): Map<string, Map<string, string>>;
5
+ export declare function fileConsts(sf: ts.SourceFile, imported: Map<string, Map<string, string>>): Map<string, string>;
6
+ export declare function relPath(file: string, from?: string): string;
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.collectSourceFiles = collectSourceFiles;
7
+ exports.loadImportedConsts = loadImportedConsts;
8
+ exports.fileConsts = fileConsts;
9
+ exports.relPath = relPath;
10
+ const node_fs_1 = __importDefault(require("node:fs"));
11
+ const node_path_1 = __importDefault(require("node:path"));
12
+ const typescript_1 = __importDefault(require("typescript"));
13
+ const ast_1 = require("./ast");
14
+ function collectSourceFiles(root, typesFile) {
15
+ const files = [];
16
+ const walk = (dir) => {
17
+ if (!node_fs_1.default.existsSync(dir))
18
+ return;
19
+ for (const entry of node_fs_1.default.readdirSync(dir, { withFileTypes: true })) {
20
+ const full = node_path_1.default.join(dir, entry.name);
21
+ if (entry.isDirectory()) {
22
+ if (entry.name === "node_modules" || entry.name === "dist")
23
+ continue;
24
+ walk(full);
25
+ }
26
+ else if (entry.isFile() && entry.name.endsWith(".ts") && !entry.name.endsWith(".d.ts")) {
27
+ files.push(full);
28
+ }
29
+ }
30
+ };
31
+ walk(root);
32
+ return files.filter((f) => node_path_1.default.resolve(f) !== node_path_1.default.resolve(typesFile));
33
+ }
34
+ function moduleStringConsts(sf) {
35
+ const map = new Map();
36
+ for (const stmt of sf.statements) {
37
+ if (!typescript_1.default.isVariableStatement(stmt))
38
+ continue;
39
+ for (const decl of stmt.declarationList.declarations) {
40
+ if (!typescript_1.default.isIdentifier(decl.name) || !decl.initializer)
41
+ continue;
42
+ const node = (0, ast_1.unwrapExpr)(decl.initializer);
43
+ if (typescript_1.default.isStringLiteral(node) || typescript_1.default.isNoSubstitutionTemplateLiteral(node)) {
44
+ map.set(decl.name.text, node.text);
45
+ }
46
+ }
47
+ }
48
+ return map;
49
+ }
50
+ function resolveImport(fromFile, spec, srcDir) {
51
+ if (spec.startsWith("@/")) {
52
+ spec = node_path_1.default.join(srcDir, spec.slice(2));
53
+ }
54
+ else if (spec.startsWith(".")) {
55
+ spec = node_path_1.default.resolve(node_path_1.default.dirname(fromFile), spec);
56
+ }
57
+ else {
58
+ return null;
59
+ }
60
+ const candidates = [
61
+ spec,
62
+ spec + ".ts",
63
+ node_path_1.default.join(spec, "index.ts"),
64
+ ];
65
+ for (const c of candidates) {
66
+ if (node_fs_1.default.existsSync(c) && node_fs_1.default.statSync(c).isFile())
67
+ return c;
68
+ }
69
+ return null;
70
+ }
71
+ /** Module-level `const X = "..."`, including re-exports via named imports. */
72
+ function loadImportedConsts(files, srcDir) {
73
+ const parsed = new Map();
74
+ const local = new Map();
75
+ for (const file of files) {
76
+ const sf = typescript_1.default.createSourceFile(file, node_fs_1.default.readFileSync(file, "utf8"), typescript_1.default.ScriptTarget.Latest, true, typescript_1.default.ScriptKind.TS);
77
+ parsed.set(file, sf);
78
+ local.set(file, moduleStringConsts(sf));
79
+ }
80
+ const resolved = new Map();
81
+ const visiting = new Set();
82
+ const resolveFile = (file) => {
83
+ const hit = resolved.get(file);
84
+ if (hit)
85
+ return hit;
86
+ if (visiting.has(file))
87
+ return local.get(file) ?? new Map();
88
+ visiting.add(file);
89
+ const out = new Map(local.get(file) ?? []);
90
+ const sf = parsed.get(file);
91
+ if (sf) {
92
+ for (const stmt of sf.statements) {
93
+ if (!typescript_1.default.isImportDeclaration(stmt) || !stmt.importClause)
94
+ continue;
95
+ if (!typescript_1.default.isStringLiteral(stmt.moduleSpecifier))
96
+ continue;
97
+ const target = resolveImport(file, stmt.moduleSpecifier.text, srcDir);
98
+ if (!target)
99
+ continue;
100
+ const exported = resolveFile(target);
101
+ const named = stmt.importClause.namedBindings;
102
+ if (named && typescript_1.default.isNamedImports(named)) {
103
+ for (const el of named.elements) {
104
+ const imported = (el.propertyName ?? el.name).text;
105
+ const localName = el.name.text;
106
+ const value = exported.get(imported);
107
+ if (value != null)
108
+ out.set(localName, value);
109
+ }
110
+ }
111
+ }
112
+ }
113
+ resolved.set(file, out);
114
+ visiting.delete(file);
115
+ return out;
116
+ };
117
+ for (const file of files)
118
+ resolveFile(file);
119
+ return resolved;
120
+ }
121
+ function fileConsts(sf, imported) {
122
+ const map = new Map(imported.get(node_path_1.default.resolve(sf.fileName)) ?? []);
123
+ const counts = new Map();
124
+ const visit = (node) => {
125
+ if (typescript_1.default.isVariableDeclaration(node) && typescript_1.default.isIdentifier(node.name) && node.initializer) {
126
+ const init = (0, ast_1.unwrapExpr)(node.initializer);
127
+ if (typescript_1.default.isStringLiteral(init) || typescript_1.default.isNoSubstitutionTemplateLiteral(init)) {
128
+ const name = node.name.text;
129
+ counts.set(name, (counts.get(name) ?? 0) + 1);
130
+ map.set(name, init.text);
131
+ }
132
+ }
133
+ typescript_1.default.forEachChild(node, visit);
134
+ };
135
+ visit(sf);
136
+ for (const [name, count] of counts) {
137
+ if (count > 1)
138
+ map.delete(name);
139
+ }
140
+ return map;
141
+ }
142
+ function relPath(file, from = process.cwd()) {
143
+ return node_path_1.default.relative(from, file);
144
+ }
@@ -0,0 +1,6 @@
1
+ export declare const DEFAULT_SCHEMA = "public";
2
+ export declare const JOIN_HINTS: Set<string>;
3
+ export declare const AGGREGATES: Set<string>;
4
+ export declare const FILTER_COLUMN_METHODS: Set<string>;
5
+ export declare const SKIP_CHAIN_PROPS: Set<string>;
6
+ export declare const QUERY_METHODS: Set<string>;