@snowtop/ent 0.2.6 → 0.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/action/executor.js +4 -4
  2. package/action/operations.js +3 -0
  3. package/action/orchestrator.js +10 -12
  4. package/action/topological_sort.d.ts +9 -0
  5. package/action/topological_sort.js +46 -0
  6. package/core/async_utils.d.ts +1 -0
  7. package/core/async_utils.js +29 -0
  8. package/core/base.d.ts +12 -5
  9. package/core/clause.d.ts +3 -5
  10. package/core/clause.js +32 -0
  11. package/core/config.d.ts +28 -2
  12. package/core/config.js +14 -1
  13. package/core/context.d.ts +3 -1
  14. package/core/context.js +90 -26
  15. package/core/db.d.ts +12 -2
  16. package/core/db.js +102 -7
  17. package/core/dev_schema.d.ts +9 -0
  18. package/core/dev_schema.js +306 -0
  19. package/core/ent.d.ts +5 -7
  20. package/core/ent.js +33 -48
  21. package/core/extensions.d.ts +25 -0
  22. package/core/extensions.js +220 -0
  23. package/core/loaders/assoc_count_loader.js +3 -6
  24. package/core/loaders/assoc_edge_loader.d.ts +3 -0
  25. package/core/loaders/assoc_edge_loader.js +48 -19
  26. package/core/loaders/index.d.ts +2 -1
  27. package/core/loaders/index.js +5 -1
  28. package/core/loaders/loader.d.ts +31 -0
  29. package/core/loaders/loader.js +141 -2
  30. package/core/loaders/object_loader.d.ts +2 -2
  31. package/core/loaders/object_loader.js +39 -57
  32. package/core/loaders/query_loader.d.ts +2 -5
  33. package/core/loaders/query_loader.js +45 -24
  34. package/core/loaders/raw_count_loader.d.ts +2 -2
  35. package/core/loaders/raw_count_loader.js +12 -14
  36. package/core/memoize.d.ts +1 -0
  37. package/core/memoize.js +15 -0
  38. package/core/metrics.d.ts +22 -0
  39. package/core/metrics.js +31 -0
  40. package/core/query/custom_clause_query.js +5 -1
  41. package/core/query/query.d.ts +1 -1
  42. package/core/query/query.js +10 -7
  43. package/core/query_expression.d.ts +6 -0
  44. package/core/query_expression.js +2 -0
  45. package/core/query_impl.d.ts +19 -3
  46. package/core/query_impl.js +148 -35
  47. package/index.d.ts +7 -2
  48. package/index.js +12 -2
  49. package/package.json +1 -7
  50. package/parse_schema/parse.d.ts +2 -12
  51. package/parse_schema/parse.js +22 -41
  52. package/schema/index.d.ts +1 -1
  53. package/schema/schema.d.ts +20 -1
  54. package/scripts/custom_graphql.js +12 -5
  55. package/scripts/fix_action_exports.js +1 -1
  56. package/scripts/migrate_v0.1.js +2 -5
  57. package/scripts/move_types.js +1 -1
  58. package/scripts/read_schema.js +2 -5
  59. package/testutils/builder.js +1 -2
  60. package/testutils/parse_sql.js +1 -1
  61. package/tsc/compilerOptions.d.ts +2 -2
  62. package/tsc/compilerOptions.js +12 -18
  63. package/tsc/move_generated.js +2 -2
  64. package/tsc/transform.d.ts +1 -1
  65. package/tsc/transform.js +16 -2
  66. package/tsc/transform_action.d.ts +1 -1
  67. package/tsc/transform_action.js +1 -1
  68. package/tsc/transform_ent.d.ts +1 -1
  69. package/tsc/transform_ent.js +1 -1
  70. package/tsc/transform_schema.d.ts +1 -1
  71. package/tsc/transform_schema.js +2 -2
  72. /package/core/{loaders/cache_utils.d.ts → cache_utils.d.ts} +0 -0
  73. /package/core/{loaders/cache_utils.js → cache_utils.js} +0 -0
package/core/db.js CHANGED
@@ -39,6 +39,8 @@ const js_yaml_1 = require("js-yaml");
39
39
  const luxon_1 = require("luxon");
40
40
  const pg_1 = __importStar(require("pg"));
41
41
  const logger_1 = require("./logger");
42
+ const dev_schema_1 = require("./dev_schema");
43
+ const extensions_1 = require("./extensions");
42
44
  function isDbDict(v) {
43
45
  return (v["production"] !== undefined ||
44
46
  v["development"] !== undefined ||
@@ -76,15 +78,22 @@ function parseConnectionString(str, args) {
76
78
  // database file in yml file
77
79
  // database/config.yml
78
80
  function getClientConfig(args) {
81
+ const extensions = (0, extensions_1.resolveExtensions)(args?.extensions);
79
82
  // if there's a db connection string, use that first
80
83
  const str = process.env.DB_CONNECTION_STRING;
81
84
  if (str) {
82
- return parseConnectionString(str, args);
85
+ const info = parseConnectionString(str, args);
86
+ info.devSchema = args?.devSchema;
87
+ info.extensions = extensions;
88
+ return info;
83
89
  }
84
90
  let file = "config/database.yml";
85
91
  if (args) {
86
92
  if (args.connectionString) {
87
- return parseConnectionString(args.connectionString, args);
93
+ const info = parseConnectionString(args.connectionString, args);
94
+ info.devSchema = args?.devSchema;
95
+ info.extensions = extensions;
96
+ return info;
88
97
  }
89
98
  if (args.db) {
90
99
  let db;
@@ -100,6 +109,8 @@ function getClientConfig(args) {
100
109
  return {
101
110
  dialect: Dialect.Postgres,
102
111
  config: db,
112
+ devSchema: args?.devSchema,
113
+ extensions,
103
114
  };
104
115
  }
105
116
  if (args.dbFile) {
@@ -128,6 +139,8 @@ function getClientConfig(args) {
128
139
  // max, min, etc
129
140
  ...cfg,
130
141
  },
142
+ devSchema: args?.devSchema,
143
+ extensions,
131
144
  };
132
145
  }
133
146
  throw new Error(`invalid yaml configuration in file`);
@@ -140,9 +153,39 @@ function getClientConfig(args) {
140
153
  class DB {
141
154
  constructor(db) {
142
155
  this.db = db;
156
+ const devSchemaEnabled = (0, dev_schema_1.isDevSchemaEnabled)(db.devSchema);
157
+ if (devSchemaEnabled && db.dialect === Dialect.SQLite) {
158
+ throw new Error("dev branch schemas are only supported for postgres");
159
+ }
160
+ const resolvedDevSchema = devSchemaEnabled
161
+ ? (0, dev_schema_1.resolveDevSchema)(db.devSchema)
162
+ : { enabled: false };
163
+ const extensions = db.extensions || [];
143
164
  if (db.dialect === Dialect.Postgres) {
165
+ const searchPath = (0, extensions_1.buildExtensionSearchPath)(resolvedDevSchema, extensions);
166
+ if (searchPath) {
167
+ const option = `-c search_path=${searchPath}`;
168
+ db.config = {
169
+ ...db.config,
170
+ options: db.config.options
171
+ ? `${db.config.options} ${option}`
172
+ : option,
173
+ };
174
+ }
144
175
  this.pool = new pg_1.Pool(db.config);
145
- this.q = new Postgres(this.pool);
176
+ const schemaName = resolvedDevSchema.schemaName;
177
+ const readyTasks = [];
178
+ if (resolvedDevSchema.enabled && schemaName) {
179
+ readyTasks.push(validateDevSchema(this.pool, schemaName).then(() => touchDevSchemaRegistry(this.pool, schemaName, resolvedDevSchema.branchName).catch(() => { })));
180
+ }
181
+ readyTasks.push((0, extensions_1.initializeExtensions)(this.pool, extensions));
182
+ const ready = readyTasks.length > 0
183
+ ? Promise.all(readyTasks).then(() => undefined)
184
+ : undefined;
185
+ if (ready) {
186
+ ready.catch(() => { });
187
+ }
188
+ this.q = new Postgres(this.pool, ready);
146
189
  this.pool.on("error", (err, client) => {
147
190
  (0, logger_1.log)("error", err);
148
191
  });
@@ -203,6 +246,10 @@ class DB {
203
246
  static initDB(args) {
204
247
  const config = getClientConfig(args);
205
248
  if (config) {
249
+ const existing = DB.instance;
250
+ if (existing) {
251
+ void existing.endPool().catch(() => { });
252
+ }
206
253
  DB.instance = new DB(config);
207
254
  DB.dialect = DB.instance.db.dialect;
208
255
  }
@@ -320,29 +367,39 @@ class Sqlite {
320
367
  }
321
368
  exports.Sqlite = Sqlite;
322
369
  class Postgres {
323
- constructor(pool) {
370
+ constructor(pool, ready) {
324
371
  this.pool = pool;
372
+ this.ready = ready;
373
+ }
374
+ async ensureReady() {
375
+ if (this.ready) {
376
+ await this.ready;
377
+ }
325
378
  }
326
379
  self() {
327
380
  return this;
328
381
  }
329
382
  // returns new Pool client
330
383
  async newClient() {
384
+ await this.ensureReady();
331
385
  const client = await this.pool.connect();
332
386
  if (!client) {
333
387
  throw new Error(`couldn't get new client`);
334
388
  }
335
- return new PostgresClient(client);
389
+ return new PostgresClient(client, this.ready);
336
390
  }
337
391
  async query(query, values) {
392
+ await this.ensureReady();
338
393
  const r = await this.pool.query(query, values);
339
394
  return r;
340
395
  }
341
396
  async queryAll(query, values) {
397
+ await this.ensureReady();
342
398
  const r = await this.pool.query(query, values);
343
399
  return r;
344
400
  }
345
401
  async exec(query, values) {
402
+ await this.ensureReady();
346
403
  const r = await this.pool.query(query, values);
347
404
  return {
348
405
  rowCount: r?.rowCount || 0,
@@ -350,23 +407,35 @@ class Postgres {
350
407
  };
351
408
  }
352
409
  async close() {
353
- return this.pool.end();
410
+ if (!this.closePromise) {
411
+ this.closePromise = this.pool.end();
412
+ }
413
+ return this.closePromise;
354
414
  }
355
415
  }
356
416
  exports.Postgres = Postgres;
357
417
  class PostgresClient {
358
- constructor(client) {
418
+ constructor(client, ready) {
359
419
  this.client = client;
420
+ this.ready = ready;
421
+ }
422
+ async ensureReady() {
423
+ if (this.ready) {
424
+ await this.ready;
425
+ }
360
426
  }
361
427
  async query(query, values) {
428
+ await this.ensureReady();
362
429
  const r = await this.client.query(query, values);
363
430
  return r;
364
431
  }
365
432
  async queryAll(query, values) {
433
+ await this.ensureReady();
366
434
  const r = await this.client.query(query, values);
367
435
  return r;
368
436
  }
369
437
  async exec(query, values) {
438
+ await this.ensureReady();
370
439
  const r = await this.client.query(query, values);
371
440
  return {
372
441
  rowCount: r?.rowCount || 0,
@@ -378,3 +447,29 @@ class PostgresClient {
378
447
  }
379
448
  }
380
449
  exports.PostgresClient = PostgresClient;
450
+ async function validateDevSchema(pool, schemaName) {
451
+ const res = await pool.query("SELECT EXISTS (SELECT 1 FROM pg_namespace WHERE nspname = $1) AS ok", [schemaName]);
452
+ if (!res.rows?.[0]?.ok) {
453
+ throw new Error(`dev branch schema \"${schemaName}\" does not exist. Run auto_schema or migrations to create it.`);
454
+ }
455
+ }
456
+ async function touchDevSchemaRegistry(pool, schemaName, branchName) {
457
+ const branch = branchName ?? null;
458
+ try {
459
+ // Avoid DDL at runtime; registry table should be created by auto_schema/prune.
460
+ await pool.query(`
461
+ INSERT INTO public.ent_dev_schema_registry (schema_name, branch_name, created_at, last_used_at)
462
+ VALUES ($1, $2, now(), now())
463
+ ON CONFLICT (schema_name)
464
+ DO UPDATE SET last_used_at = now(), branch_name = EXCLUDED.branch_name
465
+ `, [schemaName, branch]);
466
+ }
467
+ catch (err) {
468
+ if (err &&
469
+ typeof err.message === "string" &&
470
+ err.message.includes("ent_dev_schema_registry")) {
471
+ return;
472
+ }
473
+ (0, logger_1.log)("debug", err);
474
+ }
475
+ }
@@ -0,0 +1,9 @@
1
+ import type { RuntimeDevSchemaConfig } from "./config";
2
+ export interface ResolvedDevSchema {
3
+ enabled: boolean;
4
+ schemaName?: string;
5
+ branchName?: string;
6
+ includePublic?: boolean;
7
+ }
8
+ export declare function resolveDevSchema(cfg?: RuntimeDevSchemaConfig): ResolvedDevSchema;
9
+ export declare function isDevSchemaEnabled(cfg?: RuntimeDevSchemaConfig): boolean;
@@ -0,0 +1,306 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.resolveDevSchema = resolveDevSchema;
37
+ exports.isDevSchemaEnabled = isDevSchemaEnabled;
38
+ const crypto_1 = require("crypto");
39
+ const fs = __importStar(require("fs"));
40
+ const path = __importStar(require("path"));
41
+ const STATE_DIR = ".ent";
42
+ const STATE_FILE = "dev_schema.json";
43
+ const DEFAULT_SCHEMA_DIR = path.join("src", "schema");
44
+ const DEFAULT_SCHEMA_PREFIX = "ent_dev";
45
+ const MAX_SCHEMA_LEN = 63;
46
+ function resolveDevSchema(cfg) {
47
+ if (!isDevSchemaEnabled(cfg)) {
48
+ return { enabled: false };
49
+ }
50
+ if (cfg?.schemaName) {
51
+ const schemaName = sanitizeIdentifier(cfg.schemaName);
52
+ return {
53
+ enabled: true,
54
+ schemaName,
55
+ includePublic: cfg.includePublic === true,
56
+ };
57
+ }
58
+ if (cfg) {
59
+ const branchName = requireCurrentBranch("dev branch schemas are enabled but the current git branch could not be determined. Set devSchema.schemaName explicitly.");
60
+ return {
61
+ enabled: true,
62
+ schemaName: buildSchemaName(branchName),
63
+ branchName,
64
+ includePublic: cfg.includePublic === true,
65
+ };
66
+ }
67
+ const state = loadDevSchemaState(resolveStatePath());
68
+ if (state?.schemaName) {
69
+ const branchName = state.branchName;
70
+ if (branchName) {
71
+ // State-file mode is tied to the branch that produced the generated
72
+ // schema metadata. Fail closed after branch switches until codegen
73
+ // refreshes the state file.
74
+ const currentBranch = requireCurrentBranch(`dev branch schema state was generated for branch "${branchName}" but the current git branch could not be determined. Run ent codegen to regenerate or set devSchema.schemaName explicitly.`);
75
+ if (currentBranch !== branchName) {
76
+ throw new Error(`dev branch schema state was generated for branch "${branchName}" but current branch is "${currentBranch}". Run ent codegen to regenerate or set devSchema.schemaName explicitly.`);
77
+ }
78
+ }
79
+ return {
80
+ enabled: true,
81
+ schemaName: sanitizeIdentifier(state.schemaName),
82
+ branchName,
83
+ includePublic: state.includePublic === true,
84
+ };
85
+ }
86
+ const branchName = requireCurrentBranch("dev branch schemas are enabled but the current git branch could not be determined. Set devSchema.schemaName explicitly or run ent codegen to regenerate src/schema/.ent/dev_schema.json.");
87
+ return {
88
+ enabled: true,
89
+ schemaName: buildSchemaName(branchName),
90
+ branchName,
91
+ includePublic: false,
92
+ };
93
+ }
94
+ function isDevSchemaEnabled(cfg) {
95
+ const nodeEnv = (process.env.NODE_ENV || "").toLowerCase();
96
+ if (nodeEnv === "production") {
97
+ return false;
98
+ }
99
+ const envEnabled = parseEnvBool("ENT_DEV_SCHEMA_ENABLED");
100
+ if (envEnabled !== undefined) {
101
+ return envEnabled;
102
+ }
103
+ if (cfg) {
104
+ if (cfg.enabled !== true) {
105
+ return false;
106
+ }
107
+ const branch = resolveGitBranch();
108
+ if (isBranchIgnored(cfg.ignoreBranches, branch)) {
109
+ return false;
110
+ }
111
+ return true;
112
+ }
113
+ const state = loadDevSchemaState(resolveStatePath());
114
+ if (!state?.schemaName) {
115
+ return false;
116
+ }
117
+ const branch = resolveGitBranch();
118
+ if (isBranchIgnored(state.ignoreBranches, branch)) {
119
+ return false;
120
+ }
121
+ return true;
122
+ }
123
+ function loadDevSchemaState(statePath) {
124
+ if (!statePath || !fs.existsSync(statePath)) {
125
+ return undefined;
126
+ }
127
+ const raw = fs.readFileSync(statePath, "utf8");
128
+ let data;
129
+ try {
130
+ data = JSON.parse(raw);
131
+ }
132
+ catch (err) {
133
+ throw new Error(`invalid dev schema state file at ${statePath}`);
134
+ }
135
+ if (!data || !data.schemaName) {
136
+ return undefined;
137
+ }
138
+ return data;
139
+ }
140
+ function requireCurrentBranch(message) {
141
+ const branch = resolveGitBranch();
142
+ if (!branch) {
143
+ throw new Error(message);
144
+ }
145
+ return branch;
146
+ }
147
+ function slugify(input) {
148
+ if (!input) {
149
+ return "";
150
+ }
151
+ const lower = input.toLowerCase();
152
+ let out = "";
153
+ let lastUnderscore = false;
154
+ for (const ch of lower) {
155
+ const isAlpha = ch >= "a" && ch <= "z";
156
+ const isDigit = ch >= "0" && ch <= "9";
157
+ if (isAlpha || isDigit) {
158
+ out += ch;
159
+ lastUnderscore = false;
160
+ continue;
161
+ }
162
+ if (!lastUnderscore) {
163
+ out += "_";
164
+ lastUnderscore = true;
165
+ }
166
+ }
167
+ return trimBoundaryUnderscores(out);
168
+ }
169
+ function trimBoundaryUnderscores(input) {
170
+ let start = 0;
171
+ let end = input.length;
172
+ while (start < end && input[start] === "_") {
173
+ start++;
174
+ }
175
+ while (end > start && input[end - 1] === "_") {
176
+ end--;
177
+ }
178
+ return input.slice(start, end);
179
+ }
180
+ function sanitizeIdentifier(input) {
181
+ const slug = slugify(input);
182
+ if (!slug) {
183
+ return "schema";
184
+ }
185
+ let normalized = slug;
186
+ if (normalized[0] >= "0" && normalized[0] <= "9") {
187
+ normalized = `schema_${normalized}`;
188
+ }
189
+ if (normalized.length > MAX_SCHEMA_LEN) {
190
+ return normalized.slice(0, MAX_SCHEMA_LEN);
191
+ }
192
+ return normalized;
193
+ }
194
+ function shortHash(input) {
195
+ return (0, crypto_1.createHash)("sha1").update(input).digest("hex").slice(0, 8);
196
+ }
197
+ function buildSchemaName(branch) {
198
+ const prefix = sanitizeIdentifier(DEFAULT_SCHEMA_PREFIX);
199
+ let branchSlug = slugify(branch);
200
+ if (!branchSlug) {
201
+ branchSlug = "branch";
202
+ }
203
+ const hash = shortHash(branch);
204
+ let name = [prefix, branchSlug, hash].join("_");
205
+ if (name.length <= MAX_SCHEMA_LEN) {
206
+ return name;
207
+ }
208
+ const over = name.length - MAX_SCHEMA_LEN;
209
+ if (over > 0 && branchSlug.length > 1) {
210
+ branchSlug = branchSlug.slice(0, branchSlug.length - Math.min(over, branchSlug.length - 1));
211
+ }
212
+ name = [prefix, branchSlug, hash].join("_");
213
+ if (name.length > MAX_SCHEMA_LEN) {
214
+ return name.slice(0, MAX_SCHEMA_LEN);
215
+ }
216
+ return name;
217
+ }
218
+ function resolveStatePath() {
219
+ const start = process.cwd();
220
+ const root = findGitRoot(start) || start;
221
+ const schemaDir = path.join(root, DEFAULT_SCHEMA_DIR);
222
+ return path.join(schemaDir, STATE_DIR, STATE_FILE);
223
+ }
224
+ function isBranchIgnored(ignoreBranches, branch) {
225
+ if (!branch || !ignoreBranches || ignoreBranches.length === 0) {
226
+ return false;
227
+ }
228
+ for (const name of ignoreBranches) {
229
+ if (!name || !name.trim()) {
230
+ continue;
231
+ }
232
+ if (name === branch) {
233
+ return true;
234
+ }
235
+ }
236
+ return false;
237
+ }
238
+ function parseEnvBool(key) {
239
+ const raw = process.env[key];
240
+ if (!raw) {
241
+ return undefined;
242
+ }
243
+ const val = raw.trim().toLowerCase();
244
+ if (["1", "true", "t", "yes", "y"].includes(val)) {
245
+ return true;
246
+ }
247
+ if (["0", "false", "f", "no", "n"].includes(val)) {
248
+ return false;
249
+ }
250
+ return undefined;
251
+ }
252
+ function resolveGitBranch() {
253
+ const start = process.cwd();
254
+ const root = findGitRoot(start);
255
+ if (!root) {
256
+ return "";
257
+ }
258
+ const gitDir = resolveGitDir(path.join(root, ".git"));
259
+ if (!gitDir) {
260
+ return "";
261
+ }
262
+ const headPath = path.join(gitDir, "HEAD");
263
+ if (!fs.existsSync(headPath)) {
264
+ return "";
265
+ }
266
+ const head = fs.readFileSync(headPath, "utf8").trim();
267
+ if (!head.startsWith("ref:")) {
268
+ return "";
269
+ }
270
+ return head
271
+ .replace("ref:", "")
272
+ .trim()
273
+ .replace(/^refs\/heads\//, "");
274
+ }
275
+ function resolveGitDir(gitPath) {
276
+ if (!fs.existsSync(gitPath)) {
277
+ return undefined;
278
+ }
279
+ const stat = fs.statSync(gitPath);
280
+ if (stat.isDirectory()) {
281
+ return gitPath;
282
+ }
283
+ const contents = fs.readFileSync(gitPath, "utf8").trim();
284
+ if (!contents.startsWith("gitdir:")) {
285
+ return undefined;
286
+ }
287
+ let dir = contents.replace("gitdir:", "").trim();
288
+ if (!path.isAbsolute(dir)) {
289
+ dir = path.join(path.dirname(gitPath), dir);
290
+ }
291
+ return dir;
292
+ }
293
+ function findGitRoot(start) {
294
+ let dir = start;
295
+ while (true) {
296
+ const gitPath = path.join(dir, ".git");
297
+ if (fs.existsSync(gitPath)) {
298
+ return dir;
299
+ }
300
+ const parent = path.dirname(dir);
301
+ if (parent === dir) {
302
+ return undefined;
303
+ }
304
+ dir = parent;
305
+ }
306
+ }
package/core/ent.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { Context, CreateRowOptions, Data, DataOptions, EdgeQueryableDataOptions, EditRowOptions, Ent, ID, LoadCustomEntOptions, LoadEntOptions, LoadRowOptions, LoadRowsOptions, LoaderWithLoadMany, QueryDataOptions, SelectCustomDataOptions, Viewer } from "./base";
1
+ import { Context, CreateRowOptions, Data, DataOptions, EdgeQueryableDataOptions, EditRowOptions, Ent, ID, LoadCustomEntOptions, LoadEntOptions, LoadRowOptions, LoadRowsOptions, LoaderWithLoadMany, QueryDataOptions, SelectBaseDataOptions, SelectCustomDataOptions, Viewer } from "./base";
2
2
  import { Queryer, SyncQueryer } from "./db";
3
- import DataLoader from "dataloader";
4
3
  import * as clause from "./clause";
4
+ import { InstrumentedDataLoader } from "./loaders/loader";
5
5
  import { OrderBy } from "./query_impl";
6
6
  declare class entCacheMap<TViewer extends Viewer, TEnt extends Ent<TViewer>> {
7
7
  private viewer;
@@ -108,10 +108,7 @@ interface GroupQueryOptions<T extends Data, K = keyof T> {
108
108
  tableName: string;
109
109
  clause?: clause.Clause<T, K>;
110
110
  groupColumn: K;
111
- fields: (K | {
112
- alias: string;
113
- column: K;
114
- })[];
111
+ fields: SelectBaseDataOptions["fields"];
115
112
  values: any[];
116
113
  orderby?: OrderBy;
117
114
  limit: number;
@@ -151,6 +148,7 @@ export interface cursorOptions {
151
148
  */
152
149
  rowKeys?: string[];
153
150
  }
151
+ export declare function decodeCursorPayload(encoded: string): string;
154
152
  export declare function getCursor(opts: cursorOptions): string;
155
153
  export declare class AssocEdgeData {
156
154
  edgeType: string;
@@ -160,7 +158,7 @@ export declare class AssocEdgeData {
160
158
  edgeTable: string;
161
159
  constructor(data: Data);
162
160
  }
163
- export declare const assocEdgeLoader: DataLoader<ID, Data | null, ID>;
161
+ export declare const assocEdgeLoader: InstrumentedDataLoader<ID, Data | null>;
164
162
  export declare function loadEdgeData(edgeType: string): Promise<AssocEdgeData | null>;
165
163
  export declare function loadEdgeDatas(...edgeTypes: string[]): Promise<Map<string, AssocEdgeData>>;
166
164
  export interface AssocEdgeConstructor<T extends AssocEdge> {