instant-cli 0.22.96-experimental.drewh-ts-target.20759870126.1 → 0.22.96-experimental.surgical.20765334274.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.
Files changed (41) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/__tests__/__snapshots__/updateSchemaFile.test.ts.snap +248 -0
  3. package/__tests__/updateSchemaFile.test.ts +438 -0
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +1152 -1044
  6. package/dist/index.js.map +1 -1
  7. package/dist/rename.js +69 -58
  8. package/dist/rename.js.map +1 -1
  9. package/dist/renderSchemaPlan.js +22 -10
  10. package/dist/renderSchemaPlan.js.map +1 -1
  11. package/dist/ui/index.js +102 -115
  12. package/dist/ui/index.js.map +1 -1
  13. package/dist/ui/lib.js +30 -29
  14. package/dist/ui/lib.js.map +1 -1
  15. package/dist/util/fs.js +30 -17
  16. package/dist/util/fs.js.map +1 -1
  17. package/dist/util/isHeadlessEnvironment.js +1 -1
  18. package/dist/util/isHeadlessEnvironment.js.map +1 -1
  19. package/dist/util/loadConfig.js +32 -32
  20. package/dist/util/loadConfig.js.map +1 -1
  21. package/dist/util/packageManager.js +37 -26
  22. package/dist/util/packageManager.js.map +1 -1
  23. package/dist/util/projectDir.js +27 -16
  24. package/dist/util/projectDir.js.map +1 -1
  25. package/dist/util/promptOk.js +21 -14
  26. package/dist/util/promptOk.js.map +1 -1
  27. package/dist/util/renamePrompt.js +2 -4
  28. package/dist/util/renamePrompt.js.map +1 -1
  29. package/dist/util/updateSchemaFile.d.ts +3 -0
  30. package/dist/util/updateSchemaFile.d.ts.map +1 -0
  31. package/dist/util/updateSchemaFile.js +610 -0
  32. package/dist/util/updateSchemaFile.js.map +1 -0
  33. package/package.json +4 -4
  34. package/src/index.js +19 -10
  35. package/src/util/updateSchemaFile.ts +760 -0
  36. package/__tests__/mergeSchema.test.ts +0 -197
  37. package/dist/util/mergeSchema.d.ts +0 -2
  38. package/dist/util/mergeSchema.d.ts.map +0 -1
  39. package/dist/util/mergeSchema.js +0 -334
  40. package/dist/util/mergeSchema.js.map +0 -1
  41. package/src/util/mergeSchema.js +0 -364
package/dist/index.js CHANGED
@@ -1,7 +1,15 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
1
10
  // @ts-check
2
11
  import { generatePermsTypescriptFile, apiSchemaToInstantSchemaDef, generateSchemaTypescriptFile, diffSchemas, convertTxSteps, validateSchema, SchemaValidationError, PlatformApi, } from '@instantdb/platform';
3
12
  import version from './version.js';
4
- import { existsSync } from 'fs';
5
13
  import { mkdir, writeFile, readFile, unlink } from 'fs/promises';
6
14
  import path, { join } from 'path';
7
15
  import { randomUUID } from 'crypto';
@@ -29,7 +37,7 @@ import { buildAutoRenameSelector } from './rename.js';
29
37
  import { loadEnv } from './util/loadEnv.js';
30
38
  import { isHeadlessEnvironment } from './util/isHeadlessEnvironment.js';
31
39
  import { getSchemaReadCandidates, getPermsReadCandidates, getSchemaPathToWrite, getPermsPathToWrite, } from './util/findConfigCandidates.js';
32
- import { mergeSchema } from './util/mergeSchema.js';
40
+ import { updateSchemaFile } from './util/updateSchemaFile.js';
33
41
  const execAsync = promisify(exec);
34
42
  loadEnv();
35
43
  const dev = Boolean(process.env.INSTANT_CLI_DEV);
@@ -56,27 +64,30 @@ const potentialAdminTokenEnvs = {
56
64
  default: 'INSTANT_APP_ADMIN_TOKEN',
57
65
  short: 'INSTANT_ADMIN_TOKEN',
58
66
  };
59
- async function detectEnvType({ pkgDir }) {
60
- const packageJSON = await getPackageJson(pkgDir);
61
- if (!packageJSON) {
67
+ function detectEnvType(_a) {
68
+ return __awaiter(this, arguments, void 0, function* ({ pkgDir }) {
69
+ var _b, _c, _d, _e, _f;
70
+ const packageJSON = yield getPackageJson(pkgDir);
71
+ if (!packageJSON) {
72
+ return 'catchall';
73
+ }
74
+ if ((_b = packageJSON.dependencies) === null || _b === void 0 ? void 0 : _b.next) {
75
+ return 'next';
76
+ }
77
+ if ((_c = packageJSON.devDependencies) === null || _c === void 0 ? void 0 : _c.svelte) {
78
+ return 'svelte';
79
+ }
80
+ if ((_d = packageJSON.devDependencies) === null || _d === void 0 ? void 0 : _d.vite) {
81
+ return 'vite';
82
+ }
83
+ if ((_e = packageJSON.dependencies) === null || _e === void 0 ? void 0 : _e.expo) {
84
+ return 'expo';
85
+ }
86
+ if ((_f = packageJSON.dependencies) === null || _f === void 0 ? void 0 : _f.nuxt) {
87
+ return 'nuxt';
88
+ }
62
89
  return 'catchall';
63
- }
64
- if (packageJSON.dependencies?.next) {
65
- return 'next';
66
- }
67
- if (packageJSON.devDependencies?.svelte) {
68
- return 'svelte';
69
- }
70
- if (packageJSON.devDependencies?.vite) {
71
- return 'vite';
72
- }
73
- if (packageJSON.dependencies?.expo) {
74
- return 'expo';
75
- }
76
- if (packageJSON.dependencies?.nuxt) {
77
- return 'nuxt';
78
- }
79
- return 'catchall';
90
+ });
80
91
  }
81
92
  const instantDashOrigin = dev
82
93
  ? 'http://localhost:3000'
@@ -102,13 +113,15 @@ function convertPushPullToCurrentFormat(arg, opts) {
102
113
  return { ok: false };
103
114
  return { ok: true, bag, opts };
104
115
  }
105
- async function packageDirectoryWithErrorLogging() {
106
- const projectInfo = await findProjectDir();
107
- if (!projectInfo) {
108
- error("Couldn't find your root directory. Is there a package.json or deno.json file?");
109
- return;
110
- }
111
- return projectInfo;
116
+ function packageDirectoryWithErrorLogging() {
117
+ return __awaiter(this, void 0, void 0, function* () {
118
+ const projectInfo = yield findProjectDir();
119
+ if (!projectInfo) {
120
+ error("Couldn't find your root directory. Is there a package.json or deno.json file?");
121
+ return;
122
+ }
123
+ return projectInfo;
124
+ });
112
125
  }
113
126
  // cli
114
127
  // Header -- this shows up in every command
@@ -244,16 +257,16 @@ program
244
257
  .description('Log into your account')
245
258
  .option('-p --print', 'Prints the auth token into the console.')
246
259
  .option('--headless', 'Print the login URL instead of trying to open the browser')
247
- .action(async (opts) => {
260
+ .action((opts) => __awaiter(void 0, void 0, void 0, function* () {
248
261
  console.log("Let's log you in!");
249
- await login(opts);
250
- });
262
+ yield login(opts);
263
+ }));
251
264
  program
252
265
  .command('logout')
253
266
  .description('Log out of your Instant account')
254
- .action(async () => {
255
- await logout();
256
- });
267
+ .action(() => __awaiter(void 0, void 0, void 0, function* () {
268
+ yield logout();
269
+ }));
257
270
  program
258
271
  .command('init')
259
272
  .description('Set up a new project.')
@@ -276,10 +289,10 @@ program
276
289
  .argument('[app-id]')
277
290
  .description('Push schema to production.')
278
291
  .option('--skip-check-types', "Don't check types on the server when pushing schema")
279
- .action(async (appIdOrName, opts) => {
292
+ .action((appIdOrName, opts) => __awaiter(void 0, void 0, void 0, function* () {
280
293
  warnDeprecation('push-schema', 'push schema');
281
- await handlePush('schema', { app: appIdOrName, ...opts });
282
- });
294
+ yield handlePush('schema', Object.assign({ app: appIdOrName }, opts));
295
+ }));
283
296
  // Note: Nov 20, 2024
284
297
  // We can eventually delete this,
285
298
  // once we know most people use the new pull and push commands
@@ -287,10 +300,10 @@ program
287
300
  .command('push-perms', { hidden: true })
288
301
  .argument('[app-id]')
289
302
  .description('Push perms to production.')
290
- .action(async (appIdOrName) => {
303
+ .action((appIdOrName) => __awaiter(void 0, void 0, void 0, function* () {
291
304
  warnDeprecation('push-perms', 'push perms');
292
- await handlePush('perms', { app: appIdOrName });
293
- });
305
+ yield handlePush('perms', { app: appIdOrName });
306
+ }));
294
307
  program
295
308
  .command('push')
296
309
  .argument('[schema|perms|all]', 'Which configuration to push. Defaults to `all`')
@@ -304,12 +317,14 @@ Environment Variables:
304
317
  INSTANT_SCHEMA_FILE_PATH Override schema file location (default: instant.schema.ts)
305
318
  INSTANT_PERMS_FILE_PATH Override perms file location (default: instant.perms.ts)
306
319
  `)
307
- .action(async function (arg, inputOpts) {
308
- const ret = convertPushPullToCurrentFormat(arg, inputOpts);
309
- if (!ret.ok)
310
- return process.exit(1);
311
- const { bag, opts } = ret;
312
- await handlePush(bag, opts);
320
+ .action(function (arg, inputOpts) {
321
+ return __awaiter(this, void 0, void 0, function* () {
322
+ const ret = convertPushPullToCurrentFormat(arg, inputOpts);
323
+ if (!ret.ok)
324
+ return process.exit(1);
325
+ const { bag, opts } = ret;
326
+ yield handlePush(bag, opts);
327
+ });
313
328
  });
314
329
  // Note: Nov 20, 2024
315
330
  // We can eventually delete this,
@@ -318,10 +333,10 @@ program
318
333
  .command('pull-schema', { hidden: true })
319
334
  .argument('[app-id]')
320
335
  .description('Generate instant.schema.ts from production')
321
- .action(async (appIdOrName) => {
336
+ .action((appIdOrName) => __awaiter(void 0, void 0, void 0, function* () {
322
337
  warnDeprecation('pull-schema', 'pull schema');
323
- await handlePull('schema', { app: appIdOrName });
324
- });
338
+ yield handlePull('schema', { app: appIdOrName });
339
+ }));
325
340
  // Note: Nov 20, 2024
326
341
  // We can eventually delete this,
327
342
  // once we know most people use the new pull and push commands
@@ -329,175 +344,189 @@ program
329
344
  .command('pull-perms', { hidden: true })
330
345
  .argument('[app-id]')
331
346
  .description('Generate instant.perms.ts from production.')
332
- .action(async (appIdOrName) => {
347
+ .action((appIdOrName) => __awaiter(void 0, void 0, void 0, function* () {
333
348
  warnDeprecation('pull-perms', 'pull perms');
334
- await handlePull('perms', { app: appIdOrName });
335
- });
349
+ yield handlePull('perms', { app: appIdOrName });
350
+ }));
336
351
  program
337
352
  .command('pull')
338
353
  .argument('[schema|perms|all]', 'Which configuration to push. Defaults to `all`')
339
354
  .option('-a --app <app-id>', 'App ID to push to. Defaults to *_INSTANT_APP_ID in .env')
340
355
  .option('-p --package <react|react-native|core|admin>', 'Which package to automatically install if there is not one installed already.')
341
- .option('--experimental-type-preservation', "[Experimental] Preserve manual type changes like `status: i.json<'online' | 'offline'>()` when doing `instant-cli pull schema`")
356
+ .option('--experimental-type-preservation', '[Experimental] Preserve manual type changes and schema edits when pulling schema')
342
357
  .description('Pull schema and perm files from production.')
343
358
  .addHelpText('after', `
344
359
  Environment Variables:
345
360
  INSTANT_SCHEMA_FILE_PATH Override schema file location (default: instant.schema.ts)
346
361
  INSTANT_PERMS_FILE_PATH Override perms file location (default: instant.perms.ts)
347
362
  `)
348
- .action(async function (arg, inputOpts) {
349
- const ret = convertPushPullToCurrentFormat(arg, inputOpts);
350
- if (!ret.ok)
351
- return process.exit(1);
352
- const { bag, opts } = ret;
353
- await handlePull(bag, opts);
363
+ .action(function (arg, inputOpts) {
364
+ return __awaiter(this, void 0, void 0, function* () {
365
+ const ret = convertPushPullToCurrentFormat(arg, inputOpts);
366
+ if (!ret.ok)
367
+ return process.exit(1);
368
+ const { bag, opts } = ret;
369
+ yield handlePull(bag, opts);
370
+ });
354
371
  });
355
372
  program
356
373
  .command('claim')
357
374
  .description('Transfer a tempoary app into your Instant account')
358
- .action(async function () {
359
- const token = await readConfigAuthToken(false);
360
- if (!token) {
361
- console.error(`Please log in first with ${chalk.bgGray.white('instant-cli login')} to claim an app`);
362
- process.exit(1);
363
- }
364
- const envResult = detectAppIdAndAdminTokenFromEnvWithErrorLogging();
365
- if (!envResult.ok)
366
- return process.exit(1);
367
- if (!envResult.appId) {
368
- error('No app ID found in environment variables.');
369
- return process.exit(1);
370
- }
371
- if (!envResult.adminToken) {
372
- error('No admin token found in environment variables.');
373
- return process.exit(1);
374
- }
375
- const appId = envResult.appId.value;
376
- const adminToken = envResult.adminToken.value;
377
- console.log(`Found ${chalk.green(envResult.appId.envName)}: ${appId}`);
378
- await claimEphemeralApp(appId, adminToken);
379
- });
380
- program.parse(process.argv);
381
- async function handleInit(opts) {
382
- const pkgAndAuthInfo = await getOrPromptPackageAndAuthInfoWithErrorLogging(opts);
383
- if (!pkgAndAuthInfo)
384
- return process.exit(1);
385
- const { ok, appId } = await getOrCreateAppAndWriteToEnv(pkgAndAuthInfo, opts);
386
- if (!ok) {
387
- return process.exit(1);
388
- }
389
- // Create schema file if it doesn't exist
390
- // or ask to push if local schema exists
391
- const localSchemaExists = await readLocalSchemaFile();
392
- if (!localSchemaExists) {
393
- await pull('schema', appId, pkgAndAuthInfo);
394
- }
395
- else {
396
- const doSchemaPush = await promptOk({
397
- promptText: 'Found local schema. Push it to the new app?',
398
- inline: true,
399
- }, program.opts());
400
- if (doSchemaPush) {
401
- await push('schema', appId, opts);
375
+ .action(function () {
376
+ return __awaiter(this, void 0, void 0, function* () {
377
+ const token = yield readConfigAuthToken(false);
378
+ if (!token) {
379
+ console.error(`Please log in first with ${chalk.bgGray.white('instant-cli login')} to claim an app`);
380
+ process.exit(1);
402
381
  }
403
- }
404
- // Create perms file if it doesn't exist
405
- // or ask to push if local perms exists
406
- const localPermsExists = await readLocalPermsFile();
407
- if (!localPermsExists) {
408
- await pull('perms', appId, pkgAndAuthInfo);
409
- }
410
- else {
411
- const doPermsPush = await promptOk({
412
- promptText: 'Found local perms. Push it to the new app?',
413
- inline: true,
414
- }, program.opts());
415
- if (doPermsPush) {
416
- await push('perms', appId, opts);
382
+ const envResult = detectAppIdAndAdminTokenFromEnvWithErrorLogging();
383
+ if (!envResult.ok)
384
+ return process.exit(1);
385
+ if (!envResult.appId) {
386
+ error('No app ID found in environment variables.');
387
+ return process.exit(1);
417
388
  }
418
- }
419
- }
420
- async function handleInitWithoutFiles(opts) {
421
- try {
422
- const authToken = await readConfigAuthToken(false);
423
- if (!authToken) {
424
- throw new Error(`Please log in first with 'instant-cli login' before running this command.`);
389
+ if (!envResult.adminToken) {
390
+ error('No admin token found in environment variables.');
391
+ return process.exit(1);
425
392
  }
426
- if (!opts?.title) {
427
- throw new Error('Title is required for creating a new app without local files.');
393
+ const appId = envResult.appId.value;
394
+ const adminToken = envResult.adminToken.value;
395
+ console.log(`Found ${chalk.green(envResult.appId.envName)}: ${appId}`);
396
+ yield claimEphemeralApp(appId, adminToken);
397
+ });
398
+ });
399
+ program.parse(process.argv);
400
+ function handleInit(opts) {
401
+ return __awaiter(this, void 0, void 0, function* () {
402
+ const pkgAndAuthInfo = yield getOrPromptPackageAndAuthInfoWithErrorLogging(opts);
403
+ if (!pkgAndAuthInfo)
404
+ return process.exit(1);
405
+ const { ok, appId } = yield getOrCreateAppAndWriteToEnv(pkgAndAuthInfo, opts);
406
+ if (!ok) {
407
+ return process.exit(1);
428
408
  }
429
- if (opts.title.startsWith('-')) {
430
- throw new Error(`Invalid title: "${opts.title}". Title cannot be a flag.`);
409
+ // Create schema file if it doesn't exist
410
+ // or ask to push if local schema exists
411
+ const localSchemaExists = yield readLocalSchemaFile();
412
+ if (!localSchemaExists) {
413
+ yield pull('schema', appId, pkgAndAuthInfo);
431
414
  }
432
- if (opts?.temp && opts?.orgId) {
433
- throw new Error('Cannot use --temp and --org-id flags together.');
415
+ else {
416
+ const doSchemaPush = yield promptOk({
417
+ promptText: 'Found local schema. Push it to the new app?',
418
+ inline: true,
419
+ }, program.opts());
420
+ if (doSchemaPush) {
421
+ yield push('schema', appId, opts);
422
+ }
434
423
  }
435
- let result;
436
- if (opts?.temp) {
437
- result = await createEphemeralApp(opts.title);
424
+ // Create perms file if it doesn't exist
425
+ // or ask to push if local perms exists
426
+ const localPermsExists = yield readLocalPermsFile();
427
+ if (!localPermsExists) {
428
+ yield pull('perms', appId, pkgAndAuthInfo);
438
429
  }
439
430
  else {
440
- result = await createApp(opts.title, opts.orgId);
431
+ const doPermsPush = yield promptOk({
432
+ promptText: 'Found local perms. Push it to the new app?',
433
+ inline: true,
434
+ }, program.opts());
435
+ if (doPermsPush) {
436
+ yield push('perms', appId, opts);
437
+ }
441
438
  }
442
- console.error(`${chalk.green('Successfully created new app!')}\n`);
443
- console.log(toJson({
444
- app: result,
445
- error: null,
446
- }));
447
- }
448
- catch (error) {
449
- console.error(`${chalk.red('Failed to create app.')}\n`);
450
- console.log(toJson({
451
- app: null,
452
- error: { message: error.message },
453
- }));
454
- process.exit(1);
455
- }
439
+ });
456
440
  }
457
- async function handlePush(bag, opts) {
458
- const pkgAndAuthInfo = await enforcePackageAndAuthInfoWithErrorLogging(opts);
459
- if (!pkgAndAuthInfo)
460
- return process.exit(1);
461
- const { ok, appId } = await detectAppWithErrorLogging(opts);
462
- if (!ok)
463
- return process.exit(1);
464
- if (!appId) {
465
- error('No app ID detected. Please specify one with --app or set up with `instant-cli init`');
466
- return;
467
- }
468
- await push(bag, appId, opts);
469
- }
470
- async function handlePull(bag, opts) {
471
- const pkgAndAuthInfo = await enforcePackageAndAuthInfoWithErrorLogging(opts);
472
- if (!pkgAndAuthInfo)
473
- return process.exit(1);
474
- const { ok, appId } = await detectAppWithErrorLogging(opts);
475
- if (!ok) {
476
- return process.exit(1);
477
- }
478
- if (!appId) {
479
- error('No app ID detected. Please specify one with --app or set up with `instant-cli init`');
480
- return;
481
- }
482
- await pull(bag, appId, { ...pkgAndAuthInfo, ...opts });
441
+ function handleInitWithoutFiles(opts) {
442
+ return __awaiter(this, void 0, void 0, function* () {
443
+ try {
444
+ const authToken = yield readConfigAuthToken(false);
445
+ if (!authToken) {
446
+ throw new Error(`Please log in first with 'instant-cli login' before running this command.`);
447
+ }
448
+ if (!(opts === null || opts === void 0 ? void 0 : opts.title)) {
449
+ throw new Error('Title is required for creating a new app without local files.');
450
+ }
451
+ if (opts.title.startsWith('-')) {
452
+ throw new Error(`Invalid title: "${opts.title}". Title cannot be a flag.`);
453
+ }
454
+ if ((opts === null || opts === void 0 ? void 0 : opts.temp) && (opts === null || opts === void 0 ? void 0 : opts.orgId)) {
455
+ throw new Error('Cannot use --temp and --org-id flags together.');
456
+ }
457
+ let result;
458
+ if (opts === null || opts === void 0 ? void 0 : opts.temp) {
459
+ result = yield createEphemeralApp(opts.title);
460
+ }
461
+ else {
462
+ result = yield createApp(opts.title, opts.orgId);
463
+ }
464
+ console.error(`${chalk.green('Successfully created new app!')}\n`);
465
+ console.log(toJson({
466
+ app: result,
467
+ error: null,
468
+ }));
469
+ }
470
+ catch (error) {
471
+ console.error(`${chalk.red('Failed to create app.')}\n`);
472
+ console.log(toJson({
473
+ app: null,
474
+ error: { message: error.message },
475
+ }));
476
+ process.exit(1);
477
+ }
478
+ });
483
479
  }
484
- async function push(bag, appId, opts) {
485
- if (bag === 'schema' || bag === 'all') {
486
- const { ok } = await pushSchema(appId, opts);
487
- if (!ok)
480
+ function handlePush(bag, opts) {
481
+ return __awaiter(this, void 0, void 0, function* () {
482
+ const pkgAndAuthInfo = yield enforcePackageAndAuthInfoWithErrorLogging(opts);
483
+ if (!pkgAndAuthInfo)
488
484
  return process.exit(1);
489
- }
490
- if (bag === 'perms' || bag === 'all') {
491
- const { ok } = await pushPerms(appId);
485
+ const { ok, appId } = yield detectAppWithErrorLogging(opts);
492
486
  if (!ok)
493
487
  return process.exit(1);
494
- }
488
+ if (!appId) {
489
+ error('No app ID detected. Please specify one with --app or set up with `instant-cli init`');
490
+ return;
491
+ }
492
+ yield push(bag, appId, opts);
493
+ });
494
+ }
495
+ function handlePull(bag, opts) {
496
+ return __awaiter(this, void 0, void 0, function* () {
497
+ const pkgAndAuthInfo = yield enforcePackageAndAuthInfoWithErrorLogging(opts);
498
+ if (!pkgAndAuthInfo)
499
+ return process.exit(1);
500
+ const { ok, appId } = yield detectAppWithErrorLogging(opts);
501
+ if (!ok) {
502
+ return process.exit(1);
503
+ }
504
+ if (!appId) {
505
+ error('No app ID detected. Please specify one with --app or set up with `instant-cli init`');
506
+ return;
507
+ }
508
+ yield pull(bag, appId, Object.assign(Object.assign({}, pkgAndAuthInfo), opts));
509
+ });
510
+ }
511
+ function push(bag, appId, opts) {
512
+ return __awaiter(this, void 0, void 0, function* () {
513
+ if (bag === 'schema' || bag === 'all') {
514
+ const { ok } = yield pushSchema(appId, opts);
515
+ if (!ok)
516
+ return process.exit(1);
517
+ }
518
+ if (bag === 'perms' || bag === 'all') {
519
+ const { ok } = yield pushPerms(appId);
520
+ if (!ok)
521
+ return process.exit(1);
522
+ }
523
+ });
495
524
  }
496
525
  function printDotEnvInfo(envType, appId) {
497
526
  console.log(`\nPicked app ${chalk.green(appId)}!\n`);
498
527
  console.log(`To use this app automatically from now on, update your ${chalk.green('`.env`')} file:`);
499
528
  const picked = potentialEnvs[envType];
500
- const rest = { ...potentialEnvs };
529
+ const rest = Object.assign({}, potentialEnvs);
501
530
  delete rest[envType];
502
531
  console.log(` ${chalk.green(picked)}=${appId}`);
503
532
  const otherEnvs = Object.values(rest);
@@ -506,121 +535,132 @@ function printDotEnvInfo(envType, appId) {
506
535
  console.log(`Alternative names: \n${otherEnvStr} \n`);
507
536
  console.log(terminalLink('Dashboard:', appDashUrl(appId)) + '\n');
508
537
  }
509
- async function handleEnvFile(pkgAndAuthInfo, { appId, appToken }) {
510
- const { pkgDir } = pkgAndAuthInfo;
511
- const envType = await detectEnvType(pkgAndAuthInfo);
512
- const envName = potentialEnvs[envType];
513
- const envFile = program.optsWithGlobals().env ?? '.env';
514
- const hasEnvFile = await pathExists(join(pkgDir, envFile));
515
- if (hasEnvFile) {
516
- printDotEnvInfo(envType, appId);
517
- return;
518
- }
519
- console.log(`\nLooks like you don't have a ${chalk.green(`\`${envFile}\``)} file yet.`);
520
- console.log(`If we set ${chalk.green(envName)} & ${chalk.green('INSTANT_APP_ADMIN_TOKEN')}, we can remember the app that you chose for all future commands.`);
521
- const saveExtraInfo = envFile !== '.env' ? chalk.green(' (will create `' + envFile + '`)') : '';
522
- const ok = await promptOk({
523
- inline: true,
524
- promptText: 'Want us to create this env file for you?' + saveExtraInfo,
525
- modifyOutput: (a) => a,
526
- }, program.opts(), true);
527
- if (!ok) {
528
- console.log(`No .env file created. You can always set ${chalk.green('`' + envName + '`')} later. \n`);
529
- return;
530
- }
531
- const content = [
532
- [envName, appId],
533
- ['INSTANT_APP_ADMIN_TOKEN', appToken],
534
- ]
535
- .map(([k, v]) => `${k}=${v}`)
536
- .join('\n') + '\n';
537
- await writeFile(join(pkgDir, envFile), content, 'utf-8');
538
- if (envFile !== '.env') {
539
- console.log(`Created ${chalk.green(envFile)}!`);
540
- }
541
- else {
542
- console.log(`Created ${chalk.green('.env')} file!`);
543
- }
538
+ function handleEnvFile(pkgAndAuthInfo_1, _a) {
539
+ return __awaiter(this, arguments, void 0, function* (pkgAndAuthInfo, { appId, appToken }) {
540
+ var _b;
541
+ const { pkgDir } = pkgAndAuthInfo;
542
+ const envType = yield detectEnvType(pkgAndAuthInfo);
543
+ const envName = potentialEnvs[envType];
544
+ const envFile = (_b = program.optsWithGlobals().env) !== null && _b !== void 0 ? _b : '.env';
545
+ const hasEnvFile = yield pathExists(join(pkgDir, envFile));
546
+ if (hasEnvFile) {
547
+ printDotEnvInfo(envType, appId);
548
+ return;
549
+ }
550
+ console.log(`\nLooks like you don't have a ${chalk.green(`\`${envFile}\``)} file yet.`);
551
+ console.log(`If we set ${chalk.green(envName)} & ${chalk.green('INSTANT_APP_ADMIN_TOKEN')}, we can remember the app that you chose for all future commands.`);
552
+ const saveExtraInfo = envFile !== '.env' ? chalk.green(' (will create `' + envFile + '`)') : '';
553
+ const ok = yield promptOk({
554
+ inline: true,
555
+ promptText: 'Want us to create this env file for you?' + saveExtraInfo,
556
+ modifyOutput: (a) => a,
557
+ }, program.opts(), true);
558
+ if (!ok) {
559
+ console.log(`No .env file created. You can always set ${chalk.green('`' + envName + '`')} later. \n`);
560
+ return;
561
+ }
562
+ const content = [
563
+ [envName, appId],
564
+ ['INSTANT_APP_ADMIN_TOKEN', appToken],
565
+ ]
566
+ .map(([k, v]) => `${k}=${v}`)
567
+ .join('\n') + '\n';
568
+ yield writeFile(join(pkgDir, envFile), content, 'utf-8');
569
+ if (envFile !== '.env') {
570
+ console.log(`Created ${chalk.green(envFile)}!`);
571
+ }
572
+ else {
573
+ console.log(`Created ${chalk.green('.env')} file!`);
574
+ }
575
+ });
544
576
  }
545
- async function getOrCreateAppAndWriteToEnv(pkgAndAuthInfo, opts) {
546
- const ret = await detectOrCreateAppWithErrorLogging(opts);
547
- if (!ret.ok)
577
+ function getOrCreateAppAndWriteToEnv(pkgAndAuthInfo, opts) {
578
+ return __awaiter(this, void 0, void 0, function* () {
579
+ const ret = yield detectOrCreateAppWithErrorLogging(opts);
580
+ if (!ret.ok)
581
+ return ret;
582
+ const { appId, appToken, source } = ret;
583
+ if (source === 'created' || source === 'imported') {
584
+ yield handleEnvFile(pkgAndAuthInfo, { appId, appToken });
585
+ }
548
586
  return ret;
549
- const { appId, appToken, source } = ret;
550
- if (source === 'created' || source === 'imported') {
551
- await handleEnvFile(pkgAndAuthInfo, { appId, appToken });
552
- }
553
- return ret;
587
+ });
554
588
  }
555
- async function pull(bag, appId, pkgAndAuthInfo) {
556
- if (bag === 'schema' || bag === 'all') {
557
- const { ok } = await pullSchema(appId, pkgAndAuthInfo);
558
- if (!ok)
589
+ function pull(bag, appId, pkgAndAuthInfo) {
590
+ return __awaiter(this, void 0, void 0, function* () {
591
+ if (bag === 'schema' || bag === 'all') {
592
+ const { ok } = yield pullSchema(appId, pkgAndAuthInfo);
593
+ if (!ok)
594
+ return process.exit(1);
595
+ }
596
+ if (bag === 'perms' || bag === 'all') {
597
+ const { ok } = yield pullPerms(appId, pkgAndAuthInfo);
598
+ if (!ok)
599
+ return process.exit(1);
600
+ }
601
+ });
602
+ }
603
+ function login(options) {
604
+ return __awaiter(this, void 0, void 0, function* () {
605
+ const registerRes = yield fetchJson({
606
+ method: 'POST',
607
+ path: '/dash/cli/auth/register',
608
+ debugName: 'Login register',
609
+ errorMessage: 'Failed to register login.',
610
+ noAuth: true,
611
+ command: 'login',
612
+ });
613
+ if (!registerRes.ok) {
559
614
  return process.exit(1);
560
- }
561
- if (bag === 'perms' || bag === 'all') {
562
- const { ok } = await pullPerms(appId, pkgAndAuthInfo);
563
- if (!ok)
615
+ }
616
+ const { secret, ticket } = registerRes.data;
617
+ console.log();
618
+ if (isHeadlessEnvironment(options)) {
619
+ console.log(`Open this URL in a browser to log in:\n ${instantDashOrigin}/dash?ticket=${ticket}\n`);
620
+ }
621
+ else {
622
+ const ok = yield promptOk({
623
+ promptText: `This will open instantdb.com in your browser, OK to proceed?`,
624
+ }, program.opts(),
625
+ /*defaultAnswer=*/ true);
626
+ if (!ok)
627
+ return;
628
+ openInBrowser(`${instantDashOrigin}/dash?ticket=${ticket}`);
629
+ }
630
+ console.log('Waiting for authentication...');
631
+ const authTokenRes = yield waitForAuthToken({ secret });
632
+ if (!authTokenRes) {
564
633
  return process.exit(1);
565
- }
566
- }
567
- async function login(options) {
568
- const registerRes = await fetchJson({
569
- method: 'POST',
570
- path: '/dash/cli/auth/register',
571
- debugName: 'Login register',
572
- errorMessage: 'Failed to register login.',
573
- noAuth: true,
574
- command: 'login',
575
- });
576
- if (!registerRes.ok) {
577
- return process.exit(1);
578
- }
579
- const { secret, ticket } = registerRes.data;
580
- console.log();
581
- if (isHeadlessEnvironment(options)) {
582
- console.log(`Open this URL in a browser to log in:\n ${instantDashOrigin}/dash?ticket=${ticket}\n`);
583
- }
584
- else {
585
- const ok = await promptOk({
586
- promptText: `This will open instantdb.com in your browser, OK to proceed?`,
587
- }, program.opts(),
588
- /*defaultAnswer=*/ true);
589
- if (!ok)
590
- return;
591
- openInBrowser(`${instantDashOrigin}/dash?ticket=${ticket}`);
592
- }
593
- console.log('Waiting for authentication...');
594
- const authTokenRes = await waitForAuthToken({ secret });
595
- if (!authTokenRes) {
596
- return process.exit(1);
597
- }
598
- const { token, email } = authTokenRes;
599
- if (options.print) {
600
- console.log(chalk.red('[Do not share] Your Instant auth token:', token));
601
- }
602
- else {
603
- await saveConfigAuthToken(token);
604
- console.log(chalk.green(`Successfully logged in as ${email}!`));
605
- }
606
- return token;
607
- }
608
- async function logout() {
609
- const { authConfigFilePath } = getAuthPaths();
610
- try {
611
- await unlink(authConfigFilePath);
612
- console.log(chalk.green('Successfully logged out from Instant!'));
613
- return true;
614
- }
615
- catch (error) {
616
- if (error.code === 'ENOENT') {
617
- console.log(chalk.green('You were already logged out!'));
634
+ }
635
+ const { token, email } = authTokenRes;
636
+ if (options.print) {
637
+ console.log(chalk.red('[Do not share] Your Instant auth token:', token));
618
638
  }
619
639
  else {
620
- error('Failed to logout: ' + error.message);
640
+ yield saveConfigAuthToken(token);
641
+ console.log(chalk.green(`Successfully logged in as ${email}!`));
621
642
  }
622
- return false;
623
- }
643
+ return token;
644
+ });
645
+ }
646
+ function logout() {
647
+ return __awaiter(this, void 0, void 0, function* () {
648
+ const { authConfigFilePath } = getAuthPaths();
649
+ try {
650
+ yield unlink(authConfigFilePath);
651
+ console.log(chalk.green('Successfully logged out from Instant!'));
652
+ return true;
653
+ }
654
+ catch (error) {
655
+ if (error.code === 'ENOENT') {
656
+ console.log(chalk.green('You were already logged out!'));
657
+ }
658
+ else {
659
+ error('Failed to logout: ' + error.message);
660
+ }
661
+ return false;
662
+ }
663
+ });
624
664
  }
625
665
  const packageAliasAndFullNames = {
626
666
  react: '@instantdb/react',
@@ -628,376 +668,408 @@ const packageAliasAndFullNames = {
628
668
  core: '@instantdb/core',
629
669
  admin: '@instantdb/admin',
630
670
  };
631
- async function getOrInstallInstantModuleWithErrorLogging(pkgDir, opts) {
632
- const pkgJson = await getPackageJSONWithErrorLogging(pkgDir);
633
- if (!pkgJson) {
634
- return;
635
- }
636
- console.log('Checking for an Instant SDK...');
637
- const instantModuleName = await getInstantModuleName(pkgJson);
638
- if (instantModuleName) {
639
- console.log(`Found ${chalk.green(instantModuleName)} in your package.json.`);
640
- return instantModuleName;
641
- }
642
- console.log("Couldn't find an Instant SDK in your package.json, let's install one!");
643
- let moduleName;
644
- if (opts.package) {
645
- moduleName = packageAliasAndFullNames[opts.package];
646
- }
647
- else {
648
- if (program.optsWithGlobals()?.yes) {
649
- console.error('--yes was provided without a package specificaion and no Instant SDK was found');
650
- process.exit(1);
671
+ function getOrInstallInstantModuleWithErrorLogging(pkgDir, opts) {
672
+ return __awaiter(this, void 0, void 0, function* () {
673
+ var _a;
674
+ const pkgJson = yield getPackageJSONWithErrorLogging(pkgDir);
675
+ if (!pkgJson) {
676
+ return;
651
677
  }
652
- moduleName = await renderUnwrap(new UI.Select({
653
- promptText: 'Which package would you like to use?',
654
- options: [
655
- { label: '@instantdb/react', value: '@instantdb/react' },
656
- {
657
- label: '@instantdb/react-native',
658
- value: '@instantdb/react-native',
659
- },
660
- { label: '@instantdb/core', value: '@instantdb/core' },
661
- { label: '@instantdb/admin', value: '@instantdb/admin' },
662
- ],
678
+ console.log('Checking for an Instant SDK...');
679
+ const instantModuleName = yield getInstantModuleName(pkgJson);
680
+ if (instantModuleName) {
681
+ console.log(`Found ${chalk.green(instantModuleName)} in your package.json.`);
682
+ return instantModuleName;
683
+ }
684
+ console.log("Couldn't find an Instant SDK in your package.json, let's install one!");
685
+ let moduleName;
686
+ if (opts.package) {
687
+ moduleName = packageAliasAndFullNames[opts.package];
688
+ }
689
+ else {
690
+ if ((_a = program.optsWithGlobals()) === null || _a === void 0 ? void 0 : _a.yes) {
691
+ console.error('--yes was provided without a package specificaion and no Instant SDK was found');
692
+ process.exit(1);
693
+ }
694
+ moduleName = yield renderUnwrap(new UI.Select({
695
+ promptText: 'Which package would you like to use?',
696
+ options: [
697
+ { label: '@instantdb/react', value: '@instantdb/react' },
698
+ {
699
+ label: '@instantdb/react-native',
700
+ value: '@instantdb/react-native',
701
+ },
702
+ { label: '@instantdb/core', value: '@instantdb/core' },
703
+ { label: '@instantdb/admin', value: '@instantdb/admin' },
704
+ ],
705
+ }));
706
+ }
707
+ const packageManager = yield detectPackageManager(pkgDir);
708
+ const packagesToInstall = [moduleName];
709
+ if (moduleName === '@instantdb/react-native') {
710
+ packagesToInstall.push('react-native-get-random-values', '@react-native-async-storage/async-storage');
711
+ }
712
+ const installCommand = getInstallCommand(packageManager, packagesToInstall.join(' '));
713
+ yield renderUnwrap(new UI.Spinner({
714
+ promise: execAsync(installCommand, pkgDir),
715
+ workingText: `Installing ${packagesToInstall.join(', ')} using ${packageManager}...`,
716
+ doneText: `Installed ${packagesToInstall.join(', ')} using ${packageManager}.`,
663
717
  }));
664
- }
665
- const packageManager = await detectPackageManager(pkgDir);
666
- const packagesToInstall = [moduleName];
667
- if (moduleName === '@instantdb/react-native') {
668
- packagesToInstall.push('react-native-get-random-values', '@react-native-async-storage/async-storage');
669
- }
670
- const installCommand = getInstallCommand(packageManager, packagesToInstall.join(' '));
671
- await renderUnwrap(new UI.Spinner({
672
- promise: execAsync(installCommand, pkgDir),
673
- workingText: `Installing ${packagesToInstall.join(', ')} using ${packageManager}...`,
674
- doneText: `Installed ${packagesToInstall.join(', ')} using ${packageManager}.`,
675
- }));
676
- return moduleName;
677
- }
678
- async function promptCreateApp(opts) {
679
- const id = randomUUID();
680
- const token = randomUUID();
681
- let _title;
682
- if (opts?.title) {
683
- _title = opts.title;
684
- }
685
- else {
686
- _title = await renderUnwrap(new UI.TextInput({
687
- prompt: 'What would you like to call it?',
688
- placeholder: 'My cool app',
689
- })).catch(() => null);
690
- }
691
- const title = _title?.trim();
692
- if (!title) {
693
- error('No name provided.');
694
- return { ok: false };
695
- }
696
- const res = await fetchJson({
697
- debugName: 'Fetching orgs',
698
- method: 'GET',
699
- path: '/dash',
700
- errorMessage: 'Failed to fetch apps.',
701
- command: 'init',
718
+ return moduleName;
702
719
  });
703
- if (!res.ok) {
704
- return { ok: false };
705
- }
706
- const allowedOrgs = res.data.orgs.filter((org) => org.role !== 'app-member');
707
- let org_id = opts.org;
708
- if (!org_id && allowedOrgs.length) {
709
- const choices = [{ label: '(No organization)', value: null }];
710
- for (const org of allowedOrgs) {
711
- choices.push({ label: org.title, value: org.id });
712
- }
713
- const choice = await renderUnwrap(new UI.Select({
714
- promptText: 'Would you like to create the app in an organization?',
715
- options: choices,
716
- }));
717
- if (choice) {
718
- org_id = choice;
720
+ }
721
+ function promptCreateApp(opts) {
722
+ return __awaiter(this, void 0, void 0, function* () {
723
+ const id = randomUUID();
724
+ const token = randomUUID();
725
+ let _title;
726
+ if (opts === null || opts === void 0 ? void 0 : opts.title) {
727
+ _title = opts.title;
719
728
  }
720
- }
721
- const app = { id, title, admin_token: token, org_id };
722
- const appRes = await fetchJson({
723
- method: 'POST',
724
- path: '/dash/apps',
725
- debugName: 'App create',
726
- errorMessage: 'Failed to create app.',
727
- body: app,
728
- command: 'init',
729
+ else {
730
+ _title = yield renderUnwrap(new UI.TextInput({
731
+ prompt: 'What would you like to call it?',
732
+ placeholder: 'My cool app',
733
+ })).catch(() => null);
734
+ }
735
+ const title = _title === null || _title === void 0 ? void 0 : _title.trim();
736
+ if (!title) {
737
+ error('No name provided.');
738
+ return { ok: false };
739
+ }
740
+ const res = yield fetchJson({
741
+ debugName: 'Fetching orgs',
742
+ method: 'GET',
743
+ path: '/dash',
744
+ errorMessage: 'Failed to fetch apps.',
745
+ command: 'init',
746
+ });
747
+ if (!res.ok) {
748
+ return { ok: false };
749
+ }
750
+ const allowedOrgs = res.data.orgs.filter((org) => org.role !== 'app-member');
751
+ let org_id = opts.org;
752
+ if (!org_id && allowedOrgs.length) {
753
+ const choices = [{ label: '(No organization)', value: null }];
754
+ for (const org of allowedOrgs) {
755
+ choices.push({ label: org.title, value: org.id });
756
+ }
757
+ const choice = yield renderUnwrap(new UI.Select({
758
+ promptText: 'Would you like to create the app in an organization?',
759
+ options: choices,
760
+ }));
761
+ if (choice) {
762
+ org_id = choice;
763
+ }
764
+ }
765
+ const app = { id, title, admin_token: token, org_id };
766
+ const appRes = yield fetchJson({
767
+ method: 'POST',
768
+ path: '/dash/apps',
769
+ debugName: 'App create',
770
+ errorMessage: 'Failed to create app.',
771
+ body: app,
772
+ command: 'init',
773
+ });
774
+ if (!appRes.ok)
775
+ return { ok: false };
776
+ return {
777
+ ok: true,
778
+ appId: id,
779
+ appTitle: title,
780
+ appToken: token,
781
+ source: 'created',
782
+ };
729
783
  });
730
- if (!appRes.ok)
731
- return { ok: false };
732
- return {
733
- ok: true,
734
- appId: id,
735
- appTitle: title,
736
- appToken: token,
737
- source: 'created',
738
- };
739
784
  }
740
- async function promptImportAppOrCreateApp() {
741
- const res = await fetchJson({
742
- debugName: 'Fetching apps',
743
- method: 'GET',
744
- path: '/dash',
745
- errorMessage: 'Failed to fetch apps.',
746
- command: 'init',
747
- });
748
- if (!res.ok) {
749
- return { ok: false };
750
- }
751
- const result = await renderUnwrap(new UI.AppSelector({
752
- allowEphemeral: true,
753
- allowCreate: true,
754
- startingMenuIndex: 2,
755
- api: {
756
- getDash: () => res.data,
757
- createEphemeralApp,
758
- getAppsForOrg: async (orgId) => {
759
- const orgsRes = await fetchJson({
760
- debugName: 'Fetching org apps',
761
- method: 'GET',
762
- path: `/dash/orgs/${orgId}`,
763
- errorMessage: 'Failed to fetch apps.',
764
- command: 'init',
765
- });
766
- if (!orgsRes.ok) {
767
- throw new Error('Failed to fetch org apps');
768
- }
769
- return { apps: orgsRes.data.apps };
785
+ function promptImportAppOrCreateApp() {
786
+ return __awaiter(this, void 0, void 0, function* () {
787
+ const res = yield fetchJson({
788
+ debugName: 'Fetching apps',
789
+ method: 'GET',
790
+ path: '/dash',
791
+ errorMessage: 'Failed to fetch apps.',
792
+ command: 'init',
793
+ });
794
+ if (!res.ok) {
795
+ return { ok: false };
796
+ }
797
+ const result = yield renderUnwrap(new UI.AppSelector({
798
+ allowEphemeral: true,
799
+ allowCreate: true,
800
+ startingMenuIndex: 2,
801
+ api: {
802
+ getDash: () => res.data,
803
+ createEphemeralApp,
804
+ getAppsForOrg: (orgId) => __awaiter(this, void 0, void 0, function* () {
805
+ const orgsRes = yield fetchJson({
806
+ debugName: 'Fetching org apps',
807
+ method: 'GET',
808
+ path: `/dash/orgs/${orgId}`,
809
+ errorMessage: 'Failed to fetch apps.',
810
+ command: 'init',
811
+ });
812
+ if (!orgsRes.ok) {
813
+ throw new Error('Failed to fetch org apps');
814
+ }
815
+ return { apps: orgsRes.data.apps };
816
+ }),
817
+ createApp,
770
818
  },
771
- createApp,
772
- },
773
- }));
774
- return {
775
- ok: true,
776
- appId: result.appId,
777
- appToken: result.adminToken,
778
- source: result.approach === 'import' ? 'imported' : 'created',
779
- };
819
+ }));
820
+ return {
821
+ ok: true,
822
+ appId: result.appId,
823
+ appToken: result.adminToken,
824
+ source: result.approach === 'import' ? 'imported' : 'created',
825
+ };
826
+ });
780
827
  }
781
- async function createApp(title, orgId) {
782
- const id = randomUUID();
783
- const token = randomUUID();
784
- const app = { id, title, admin_token: token, org_id: orgId };
785
- const appRes = await fetchJson({
786
- method: 'POST',
787
- path: '/dash/apps',
788
- debugName: 'App create',
789
- errorMessage: 'Failed to create app.',
790
- body: app,
791
- command: 'init',
828
+ function createApp(title, orgId) {
829
+ return __awaiter(this, void 0, void 0, function* () {
830
+ const id = randomUUID();
831
+ const token = randomUUID();
832
+ const app = { id, title, admin_token: token, org_id: orgId };
833
+ const appRes = yield fetchJson({
834
+ method: 'POST',
835
+ path: '/dash/apps',
836
+ debugName: 'App create',
837
+ errorMessage: 'Failed to create app.',
838
+ body: app,
839
+ command: 'init',
840
+ });
841
+ if (!appRes.ok)
842
+ throw new Error('Failed to create app');
843
+ return { appId: id, adminToken: token };
792
844
  });
793
- if (!appRes.ok)
794
- throw new Error('Failed to create app');
795
- return { appId: id, adminToken: token };
796
- }
797
- async function createEphemeralApp(title) {
798
- const api = new PlatformApi({ apiURI: instantBackendOrigin });
799
- const { app } = await api.createTemporaryApp({ title });
800
- return { appId: app.id, adminToken: app.adminToken };
801
- }
802
- async function detectAppWithErrorLogging(opts) {
803
- const fromOpts = await detectAppIdFromOptsWithErrorLogging(opts);
804
- if (!fromOpts.ok)
805
- return fromOpts;
806
- if (fromOpts.appId) {
807
- return { ok: true, appId: fromOpts.appId, source: 'opts' };
808
- }
809
- const fromEnv = detectAppIdFromEnvWithErrorLogging();
810
- if (!fromEnv.ok)
811
- return fromEnv;
812
- if (fromEnv.found) {
813
- const { envName, value } = fromEnv.found;
814
- console.log(`Found ${chalk.green(envName)}: ${value}`);
815
- return { ok: true, appId: value, source: 'env' };
816
- }
817
- return { ok: true };
818
- }
819
- async function detectOrCreateAppWithErrorLogging(opts) {
820
- const detected = await detectAppWithErrorLogging(opts);
821
- if (!detected.ok)
822
- return detected;
823
- if (detected.appId) {
824
- return detected;
825
- }
826
- let action;
827
- if (program.optsWithGlobals().yes) {
828
- action = 'create';
829
- if (!opts?.title) {
830
- console.error(chalk.red(`Title is required when using --yes and no app is linked`));
831
- process.exit(1);
845
+ }
846
+ function createEphemeralApp(title) {
847
+ return __awaiter(this, void 0, void 0, function* () {
848
+ const api = new PlatformApi({ apiURI: instantBackendOrigin });
849
+ const { app } = yield api.createTemporaryApp({ title });
850
+ return { appId: app.id, adminToken: app.adminToken };
851
+ });
852
+ }
853
+ function detectAppWithErrorLogging(opts) {
854
+ return __awaiter(this, void 0, void 0, function* () {
855
+ const fromOpts = yield detectAppIdFromOptsWithErrorLogging(opts);
856
+ if (!fromOpts.ok)
857
+ return fromOpts;
858
+ if (fromOpts.appId) {
859
+ return { ok: true, appId: fromOpts.appId, source: 'opts' };
832
860
  }
833
- const app = await createApp(opts.title);
834
- return { ok: true, appId: app.appId, source: 'created' };
835
- }
836
- else {
837
- console.log();
838
- return await promptImportAppOrCreateApp();
839
- }
861
+ const fromEnv = detectAppIdFromEnvWithErrorLogging();
862
+ if (!fromEnv.ok)
863
+ return fromEnv;
864
+ if (fromEnv.found) {
865
+ const { envName, value } = fromEnv.found;
866
+ console.log(`Found ${chalk.green(envName)}: ${value}`);
867
+ return { ok: true, appId: value, source: 'env' };
868
+ }
869
+ return { ok: true };
870
+ });
840
871
  }
841
- async function writeTypescript(path, content, encoding) {
842
- const prettierConfig = await prettier.resolveConfig(path);
843
- const formattedCode = await prettier.format(content, {
844
- ...prettierConfig,
845
- parser: 'typescript',
872
+ function detectOrCreateAppWithErrorLogging(opts) {
873
+ return __awaiter(this, void 0, void 0, function* () {
874
+ const detected = yield detectAppWithErrorLogging(opts);
875
+ if (!detected.ok)
876
+ return detected;
877
+ if (detected.appId) {
878
+ return detected;
879
+ }
880
+ let action;
881
+ if (program.optsWithGlobals().yes) {
882
+ action = 'create';
883
+ if (!(opts === null || opts === void 0 ? void 0 : opts.title)) {
884
+ console.error(chalk.red(`Title is required when using --yes and no app is linked`));
885
+ process.exit(1);
886
+ }
887
+ const app = yield createApp(opts.title);
888
+ return { ok: true, appId: app.appId, source: 'created' };
889
+ }
890
+ else {
891
+ console.log();
892
+ return yield promptImportAppOrCreateApp();
893
+ }
846
894
  });
847
- return await writeFile(path, formattedCode, encoding);
848
- }
849
- async function getInstantModuleName(pkgJson) {
850
- const deps = pkgJson.dependencies || {};
851
- const devDeps = pkgJson.devDependencies || {};
852
- const instantModuleName = [
853
- '@instantdb/react',
854
- '@instantdb/react-native',
855
- '@instantdb/core',
856
- '@instantdb/admin',
857
- ].find((name) => deps[name] || devDeps[name]);
858
- return instantModuleName;
859
- }
860
- async function getPackageJson(pkgDir) {
861
- return await readJsonFile(join(pkgDir, 'package.json'));
862
- }
863
- async function getPackageJSONWithErrorLogging(pkgDir) {
864
- const pkgJson = await getPackageJson(pkgDir);
865
- if (!pkgJson) {
866
- error(`Couldn't find a packge.json file in: ${pkgDir}. Please add one.`);
867
- return;
868
- }
869
- return pkgJson;
870
895
  }
871
- async function enforcePackageAndAuthInfoWithErrorLogging(_opts) {
872
- const projectInfo = await packageDirectoryWithErrorLogging();
873
- if (!projectInfo) {
874
- return;
875
- }
876
- const { dir: pkgDir, type: projectType } = projectInfo;
877
- // Deno projects don't have package.json or node_modules
878
- if (projectType === 'deno') {
879
- const authToken = await readConfigAuthTokenWithErrorLogging();
896
+ function writeTypescript(path, content, encoding) {
897
+ return __awaiter(this, void 0, void 0, function* () {
898
+ const prettierConfig = yield prettier.resolveConfig(path);
899
+ const formattedCode = yield prettier.format(content, Object.assign(Object.assign({}, prettierConfig), { parser: 'typescript' }));
900
+ return yield writeFile(path, formattedCode, encoding);
901
+ });
902
+ }
903
+ function getInstantModuleName(pkgJson) {
904
+ return __awaiter(this, void 0, void 0, function* () {
905
+ const deps = pkgJson.dependencies || {};
906
+ const devDeps = pkgJson.devDependencies || {};
907
+ const instantModuleName = [
908
+ '@instantdb/react',
909
+ '@instantdb/react-native',
910
+ '@instantdb/core',
911
+ '@instantdb/admin',
912
+ ].find((name) => deps[name] || devDeps[name]);
913
+ return instantModuleName;
914
+ });
915
+ }
916
+ function getPackageJson(pkgDir) {
917
+ return __awaiter(this, void 0, void 0, function* () {
918
+ return yield readJsonFile(join(pkgDir, 'package.json'));
919
+ });
920
+ }
921
+ function getPackageJSONWithErrorLogging(pkgDir) {
922
+ return __awaiter(this, void 0, void 0, function* () {
923
+ const pkgJson = yield getPackageJson(pkgDir);
924
+ if (!pkgJson) {
925
+ error(`Couldn't find a packge.json file in: ${pkgDir}. Please add one.`);
926
+ return;
927
+ }
928
+ return pkgJson;
929
+ });
930
+ }
931
+ function enforcePackageAndAuthInfoWithErrorLogging(_opts) {
932
+ return __awaiter(this, void 0, void 0, function* () {
933
+ const projectInfo = yield packageDirectoryWithErrorLogging();
934
+ if (!projectInfo) {
935
+ return;
936
+ }
937
+ const { dir: pkgDir, type: projectType } = projectInfo;
938
+ // Deno projects don't have package.json or node_modules
939
+ if (projectType === 'deno') {
940
+ const authToken = yield readConfigAuthTokenWithErrorLogging();
941
+ if (!authToken) {
942
+ return;
943
+ }
944
+ return {
945
+ pkgDir,
946
+ projectType,
947
+ instantModuleName: '@instantdb/core',
948
+ authToken,
949
+ };
950
+ }
951
+ const pkgJson = yield getPackageJSONWithErrorLogging(pkgDir);
952
+ if (!pkgJson) {
953
+ return;
954
+ }
955
+ const instantModuleName = yield getInstantModuleName(pkgJson);
956
+ if (!instantModuleName) {
957
+ error("We couldn't find an Instant SDK. Install one, or run `init`");
958
+ }
959
+ const authToken = yield readConfigAuthTokenWithErrorLogging();
880
960
  if (!authToken) {
881
961
  return;
882
962
  }
883
- return {
884
- pkgDir,
885
- projectType,
886
- instantModuleName: '@instantdb/core',
887
- authToken,
888
- };
889
- }
890
- const pkgJson = await getPackageJSONWithErrorLogging(pkgDir);
891
- if (!pkgJson) {
892
- return;
893
- }
894
- const instantModuleName = await getInstantModuleName(pkgJson);
895
- if (!instantModuleName) {
896
- error("We couldn't find an Instant SDK. Install one, or run `init`");
897
- }
898
- const authToken = await readConfigAuthTokenWithErrorLogging();
899
- if (!authToken) {
900
- return;
901
- }
902
- return { pkgDir, projectType, instantModuleName, authToken };
963
+ return { pkgDir, projectType, instantModuleName, authToken };
964
+ });
903
965
  }
904
- async function getOrPromptPackageAndAuthInfoWithErrorLogging(opts) {
905
- const projectInfo = await packageDirectoryWithErrorLogging();
906
- if (!projectInfo) {
907
- return;
908
- }
909
- const { dir: pkgDir, type: projectType } = projectInfo;
910
- // Deno projects don't have package.json or node_modules
911
- if (projectType === 'deno') {
912
- const authToken = await readAuthTokenOrLoginWithErrorLogging();
966
+ function getOrPromptPackageAndAuthInfoWithErrorLogging(opts) {
967
+ return __awaiter(this, void 0, void 0, function* () {
968
+ const projectInfo = yield packageDirectoryWithErrorLogging();
969
+ if (!projectInfo) {
970
+ return;
971
+ }
972
+ const { dir: pkgDir, type: projectType } = projectInfo;
973
+ // Deno projects don't have package.json or node_modules
974
+ if (projectType === 'deno') {
975
+ const authToken = yield readAuthTokenOrLoginWithErrorLogging();
976
+ if (!authToken) {
977
+ return;
978
+ }
979
+ return {
980
+ pkgDir,
981
+ projectType,
982
+ instantModuleName: '@instantdb/core',
983
+ authToken,
984
+ };
985
+ }
986
+ const instantModuleName = yield getOrInstallInstantModuleWithErrorLogging(pkgDir, opts);
987
+ if (!instantModuleName) {
988
+ return;
989
+ }
990
+ const authToken = yield readAuthTokenOrLoginWithErrorLogging();
913
991
  if (!authToken) {
914
992
  return;
915
993
  }
916
- return {
917
- pkgDir,
918
- projectType,
919
- instantModuleName: '@instantdb/core',
920
- authToken,
921
- };
922
- }
923
- const instantModuleName = await getOrInstallInstantModuleWithErrorLogging(pkgDir, opts);
924
- if (!instantModuleName) {
925
- return;
926
- }
927
- const authToken = await readAuthTokenOrLoginWithErrorLogging();
928
- if (!authToken) {
929
- return;
930
- }
931
- return { pkgDir, projectType, instantModuleName, authToken };
932
- }
933
- async function pullSchema(appId, { pkgDir, instantModuleName, experimentalTypePreservation }) {
934
- console.log('Pulling schema...');
935
- const pullRes = await fetchJson({
936
- path: `/dash/apps/${appId}/schema/pull`,
937
- debugName: 'Schema pull',
938
- errorMessage: 'Failed to pull schema.',
939
- command: 'pull',
994
+ return { pkgDir, projectType, instantModuleName, authToken };
940
995
  });
941
- if (!pullRes.ok)
942
- return pullRes;
943
- if (!countEntities(pullRes.data.schema.refs) &&
944
- !countEntities(pullRes.data.schema.blobs)) {
945
- console.log('Schema is empty. Skipping.');
946
- return { ok: true };
947
- }
948
- const prev = await readLocalSchemaFile();
949
- if (prev) {
950
- const shouldContinue = await promptOk({
951
- promptText: 'This will overwrite your local instant.schema.ts file, OK to proceed?',
952
- modifyOutput: UI.modifiers.yPadding,
953
- inline: true,
954
- }, program.opts());
955
- console.log();
956
- if (!shouldContinue)
996
+ }
997
+ function pullSchema(appId_1, _a) {
998
+ return __awaiter(this, arguments, void 0, function* (appId, { pkgDir, instantModuleName, experimentalTypePreservation }) {
999
+ console.log('Pulling schema...');
1000
+ const pullRes = yield fetchJson({
1001
+ path: `/dash/apps/${appId}/schema/pull`,
1002
+ debugName: 'Schema pull',
1003
+ errorMessage: 'Failed to pull schema.',
1004
+ command: 'pull',
1005
+ });
1006
+ if (!pullRes.ok)
1007
+ return pullRes;
1008
+ if (!countEntities(pullRes.data.schema.refs) &&
1009
+ !countEntities(pullRes.data.schema.blobs)) {
1010
+ console.log('Schema is empty. Skipping.');
957
1011
  return { ok: true };
958
- }
959
- const shortSchemaPath = getSchemaPathToWrite(prev?.path);
960
- const schemaPath = join(pkgDir, shortSchemaPath);
961
- let newSchemaContent = generateSchemaTypescriptFile(prev?.schema, apiSchemaToInstantSchemaDef(pullRes.data.schema), instantModuleName);
962
- if (prev && experimentalTypePreservation) {
963
- try {
964
- const oldSchemaContent = await readFile(prev.path, 'utf-8');
965
- newSchemaContent = mergeSchema(oldSchemaContent, newSchemaContent);
966
1012
  }
967
- catch (e) {
968
- warn('Failed to merge schema with existing file. Overwriting instead.', e);
1013
+ const prev = yield readLocalSchemaFile();
1014
+ if (prev) {
1015
+ const shouldContinue = yield promptOk({
1016
+ promptText: 'This will overwrite your local instant.schema.ts file, OK to proceed?',
1017
+ modifyOutput: UI.modifiers.yPadding,
1018
+ inline: true,
1019
+ }, program.opts());
1020
+ console.log();
1021
+ if (!shouldContinue)
1022
+ return { ok: true };
969
1023
  }
970
- }
971
- await writeTypescript(schemaPath, newSchemaContent, 'utf-8');
972
- console.log('✅ Wrote schema to ' + shortSchemaPath);
973
- return { ok: true };
974
- }
975
- async function pullPerms(appId, { pkgDir, instantModuleName }) {
976
- console.log('Pulling perms...');
977
- const pullRes = await fetchJson({
978
- path: `/dash/apps/${appId}/perms/pull`,
979
- debugName: 'Perms pull',
980
- errorMessage: 'Failed to pull perms.',
981
- command: 'pull',
1024
+ const shortSchemaPath = getSchemaPathToWrite(prev === null || prev === void 0 ? void 0 : prev.path);
1025
+ const schemaPath = join(pkgDir, shortSchemaPath);
1026
+ const serverSchema = apiSchemaToInstantSchemaDef(pullRes.data.schema);
1027
+ let newSchemaContent;
1028
+ if (prev && experimentalTypePreservation) {
1029
+ try {
1030
+ const oldSchemaContent = yield readFile(prev.path, 'utf-8');
1031
+ newSchemaContent = yield updateSchemaFile(oldSchemaContent, prev.schema, serverSchema);
1032
+ }
1033
+ catch (e) {
1034
+ warn('Failed to update schema with existing file. Overwriting instead.', e);
1035
+ }
1036
+ }
1037
+ if (!newSchemaContent) {
1038
+ newSchemaContent = generateSchemaTypescriptFile(prev === null || prev === void 0 ? void 0 : prev.schema, serverSchema, instantModuleName);
1039
+ }
1040
+ yield writeTypescript(schemaPath, newSchemaContent, 'utf-8');
1041
+ console.log('✅ Wrote schema to ' + shortSchemaPath);
1042
+ return { ok: true };
1043
+ });
1044
+ }
1045
+ function pullPerms(appId_1, _a) {
1046
+ return __awaiter(this, arguments, void 0, function* (appId, { pkgDir, instantModuleName }) {
1047
+ console.log('Pulling perms...');
1048
+ const pullRes = yield fetchJson({
1049
+ path: `/dash/apps/${appId}/perms/pull`,
1050
+ debugName: 'Perms pull',
1051
+ errorMessage: 'Failed to pull perms.',
1052
+ command: 'pull',
1053
+ });
1054
+ if (!pullRes.ok)
1055
+ return pullRes;
1056
+ const prev = yield readLocalPermsFile();
1057
+ if (prev) {
1058
+ const shouldContinue = yield promptOk({
1059
+ promptText: 'This will overwrite your local instant.perms.ts file, OK to proceed?',
1060
+ modifyOutput: UI.modifiers.yPadding,
1061
+ inline: true,
1062
+ }, program.opts());
1063
+ console.log();
1064
+ if (!shouldContinue)
1065
+ return { ok: true };
1066
+ }
1067
+ const shortPermsPath = getPermsPathToWrite(prev === null || prev === void 0 ? void 0 : prev.path);
1068
+ const permsPath = join(pkgDir, shortPermsPath);
1069
+ yield writeTypescript(permsPath, generatePermsTypescriptFile(pullRes.data.perms || {}, instantModuleName), 'utf-8');
1070
+ console.log('✅ Wrote permissions to ' + shortPermsPath);
1071
+ return { ok: true };
982
1072
  });
983
- if (!pullRes.ok)
984
- return pullRes;
985
- const prev = await readLocalPermsFile();
986
- if (prev) {
987
- const shouldContinue = await promptOk({
988
- promptText: 'This will overwrite your local instant.perms.ts file, OK to proceed?',
989
- modifyOutput: UI.modifiers.yPadding,
990
- inline: true,
991
- }, program.opts());
992
- console.log();
993
- if (!shouldContinue)
994
- return { ok: true };
995
- }
996
- const shortPermsPath = getPermsPathToWrite(prev?.path);
997
- const permsPath = join(pkgDir, shortPermsPath);
998
- await writeTypescript(permsPath, generatePermsTypescriptFile(pullRes.data.perms || {}, instantModuleName), 'utf-8');
999
- console.log('✅ Wrote permissions to ' + shortPermsPath);
1000
- return { ok: true };
1001
1073
  }
1002
1074
  function indexingJobCompletedActionMessage(job) {
1003
1075
  if (job.job_type === 'check-data-type') {
@@ -1034,7 +1106,7 @@ function truncate(s, maxLen) {
1034
1106
  }
1035
1107
  function formatSamples(triples_samples) {
1036
1108
  return triples_samples.slice(0, 3).map((t) => {
1037
- return { ...t, value: truncate(JSON.stringify(t.value), 32) };
1109
+ return Object.assign(Object.assign({}, t), { value: truncate(JSON.stringify(t.value), 32) });
1038
1110
  });
1039
1111
  }
1040
1112
  function createUrl(triple, job) {
@@ -1055,6 +1127,7 @@ function padCell(value, width) {
1055
1127
  return trimmed + ' '.repeat(width - trimmed.length);
1056
1128
  }
1057
1129
  function indexingJobCompletedMessage(job) {
1130
+ var _a;
1058
1131
  const actionMessage = indexingJobCompletedActionMessage(job);
1059
1132
  if (job.job_status === 'canceled') {
1060
1133
  return `Canceled ${actionMessage} before it could finish.`;
@@ -1063,7 +1136,7 @@ function indexingJobCompletedMessage(job) {
1063
1136
  return `Finished ${actionMessage}.`;
1064
1137
  }
1065
1138
  if (job.job_status === 'errored') {
1066
- if (job.invalid_triples_sample?.length) {
1139
+ if ((_a = job.invalid_triples_sample) === null || _a === void 0 ? void 0 : _a.length) {
1067
1140
  const [etype, label] = job.attr_name.split('.');
1068
1141
  const samples = formatSamples(job.invalid_triples_sample);
1069
1142
  const longestValue = samples.reduce((acc, { value }) => Math.max(acc, value.length), label.length);
@@ -1131,85 +1204,88 @@ function jobGroupDescription(jobs) {
1131
1204
  }
1132
1205
  return joinInSentence([...actions].sort()) || 'updating schema';
1133
1206
  }
1134
- async function waitForIndexingJobsToFinish(appId, data) {
1135
- const spinnerDefferedPromise = deferred();
1136
- const spinner = new UI.Spinner({
1137
- promise: spinnerDefferedPromise.promise,
1138
- });
1139
- const spinnerRenderPromise = renderUnwrap(spinner);
1140
- const groupId = data['group-id'];
1141
- let jobs = data.jobs;
1142
- let waitMs = 20;
1143
- let lastUpdatedAt = new Date(0);
1144
- const completedIds = new Set();
1145
- const errorMessages = [];
1146
- while (true) {
1147
- let stillRunning = false;
1148
- let updated = false;
1149
- let workEstimateTotal = 0;
1150
- let workCompletedTotal = 0;
1151
- for (const job of jobs) {
1152
- const updatedAt = new Date(job.updated_at);
1153
- if (updatedAt > lastUpdatedAt) {
1154
- updated = true;
1155
- lastUpdatedAt = updatedAt;
1156
- }
1157
- if (job.job_status === 'waiting' || job.job_status === 'processing') {
1158
- stillRunning = true;
1159
- // Default estimate to high value to prevent % from jumping around
1160
- workEstimateTotal += job.work_estimate ?? 50000;
1161
- workCompletedTotal += job.work_completed ?? 0;
1162
- }
1163
- else {
1164
- if (!completedIds.has(job.id)) {
1165
- completedIds.add(job.id);
1166
- const msg = indexingJobCompletedMessage(job);
1167
- if (msg) {
1168
- if (job.job_status === 'errored') {
1169
- spinner.addMessage(msg);
1170
- errorMessages.push(msg);
1171
- }
1172
- else {
1173
- spinner.addMessage(msg);
1207
+ function waitForIndexingJobsToFinish(appId, data) {
1208
+ return __awaiter(this, void 0, void 0, function* () {
1209
+ var _a, _b;
1210
+ const spinnerDefferedPromise = deferred();
1211
+ const spinner = new UI.Spinner({
1212
+ promise: spinnerDefferedPromise.promise,
1213
+ });
1214
+ const spinnerRenderPromise = renderUnwrap(spinner);
1215
+ const groupId = data['group-id'];
1216
+ let jobs = data.jobs;
1217
+ let waitMs = 20;
1218
+ let lastUpdatedAt = new Date(0);
1219
+ const completedIds = new Set();
1220
+ const errorMessages = [];
1221
+ while (true) {
1222
+ let stillRunning = false;
1223
+ let updated = false;
1224
+ let workEstimateTotal = 0;
1225
+ let workCompletedTotal = 0;
1226
+ for (const job of jobs) {
1227
+ const updatedAt = new Date(job.updated_at);
1228
+ if (updatedAt > lastUpdatedAt) {
1229
+ updated = true;
1230
+ lastUpdatedAt = updatedAt;
1231
+ }
1232
+ if (job.job_status === 'waiting' || job.job_status === 'processing') {
1233
+ stillRunning = true;
1234
+ // Default estimate to high value to prevent % from jumping around
1235
+ workEstimateTotal += (_a = job.work_estimate) !== null && _a !== void 0 ? _a : 50000;
1236
+ workCompletedTotal += (_b = job.work_completed) !== null && _b !== void 0 ? _b : 0;
1237
+ }
1238
+ else {
1239
+ if (!completedIds.has(job.id)) {
1240
+ completedIds.add(job.id);
1241
+ const msg = indexingJobCompletedMessage(job);
1242
+ if (msg) {
1243
+ if (job.job_status === 'errored') {
1244
+ spinner.addMessage(msg);
1245
+ errorMessages.push(msg);
1246
+ }
1247
+ else {
1248
+ spinner.addMessage(msg);
1249
+ }
1174
1250
  }
1175
1251
  }
1176
1252
  }
1177
1253
  }
1254
+ if (!stillRunning) {
1255
+ break;
1256
+ }
1257
+ if (workEstimateTotal) {
1258
+ const percent = Math.floor((workCompletedTotal / workEstimateTotal) * 100);
1259
+ spinner.updateText(`${jobGroupDescription(jobs)} ${percent}%`);
1260
+ }
1261
+ waitMs = updated ? 1 : Math.min(10000, waitMs * 2);
1262
+ yield sleep(waitMs);
1263
+ const res = yield fetchJson({
1264
+ debugName: 'Check indexing status',
1265
+ method: 'GET',
1266
+ path: `/dash/apps/${appId}/indexing-jobs/group/${groupId}`,
1267
+ errorMessage: 'Failed to check indexing status.',
1268
+ command: 'push',
1269
+ });
1270
+ if (!res.ok) {
1271
+ break;
1272
+ }
1273
+ jobs = res.data.jobs;
1178
1274
  }
1179
- if (!stillRunning) {
1180
- break;
1181
- }
1182
- if (workEstimateTotal) {
1183
- const percent = Math.floor((workCompletedTotal / workEstimateTotal) * 100);
1184
- spinner.updateText(`${jobGroupDescription(jobs)} ${percent}%`);
1185
- }
1186
- waitMs = updated ? 1 : Math.min(10000, waitMs * 2);
1187
- await sleep(waitMs);
1188
- const res = await fetchJson({
1189
- debugName: 'Check indexing status',
1190
- method: 'GET',
1191
- path: `/dash/apps/${appId}/indexing-jobs/group/${groupId}`,
1192
- errorMessage: 'Failed to check indexing status.',
1193
- command: 'push',
1194
- });
1195
- if (!res.ok) {
1196
- break;
1275
+ spinnerDefferedPromise.resolve(null);
1276
+ yield spinnerRenderPromise;
1277
+ // Log errors at the end so that they're easier to see.
1278
+ if (errorMessages.length) {
1279
+ for (const msg of errorMessages) {
1280
+ console.log(msg);
1281
+ }
1282
+ console.log(chalk.red('Some steps failed while updating schema.'));
1283
+ process.exit(1);
1197
1284
  }
1198
- jobs = res.data.jobs;
1199
- }
1200
- spinnerDefferedPromise.resolve(null);
1201
- await spinnerRenderPromise;
1202
- // Log errors at the end so that they're easier to see.
1203
- if (errorMessages.length) {
1204
- for (const msg of errorMessages) {
1205
- console.log(msg);
1206
- }
1207
- console.log(chalk.red('Some steps failed while updating schema.'));
1208
- process.exit(1);
1209
- }
1285
+ });
1210
1286
  }
1211
- const resolveRenames = async (created, promptData, extraInfo) => {
1212
- const answer = await renderUnwrap(new ResolveRenamePrompt(created, promptData, extraInfo, UI.modifiers.piped([
1287
+ const resolveRenames = (created, promptData, extraInfo) => __awaiter(void 0, void 0, void 0, function* () {
1288
+ const answer = yield renderUnwrap(new ResolveRenamePrompt(created, promptData, extraInfo, UI.modifiers.piped([
1213
1289
  (out) => boxen(out, {
1214
1290
  dimBorder: true,
1215
1291
  padding: {
@@ -1220,7 +1296,7 @@ const resolveRenames = async (created, promptData, extraInfo) => {
1220
1296
  UI.modifiers.vanishOnComplete,
1221
1297
  ])));
1222
1298
  return answer;
1223
- };
1299
+ });
1224
1300
  function collectSystemCatalogIdentNames(currentAttrs) {
1225
1301
  const allSystemIdents = currentAttrs
1226
1302
  .filter((attr) => attr.catalog === 'system')
@@ -1233,64 +1309,151 @@ function collectSystemCatalogIdentNames(currentAttrs) {
1233
1309
  }
1234
1310
  return res;
1235
1311
  }
1236
- async function pushSchema(appId, opts) {
1237
- const res = await readLocalSchemaFileWithErrorLogging();
1238
- if (!res)
1239
- return { ok: false };
1240
- const { schema } = res;
1241
- const pulledSchemaResponse = await fetchJson({
1242
- method: 'GET',
1243
- path: `/dash/apps/${appId}/schema/pull`,
1244
- debugName: 'Schema plan',
1245
- errorMessage: 'Failed to get old schema.',
1246
- command: 'push',
1247
- });
1248
- if (!pulledSchemaResponse.ok)
1249
- return pulledSchemaResponse;
1250
- const currentAttrs = pulledSchemaResponse.data['attrs'];
1251
- const currentApiSchema = pulledSchemaResponse.data['schema'];
1252
- const oldSchema = apiSchemaToInstantSchemaDef(currentApiSchema, {
1253
- disableTypeInference: true,
1254
- });
1255
- const systemCatalogIdentNames = collectSystemCatalogIdentNames(currentAttrs);
1256
- try {
1257
- validateSchema(schema, systemCatalogIdentNames);
1258
- }
1259
- catch (error) {
1260
- if (error instanceof SchemaValidationError) {
1261
- console.error(chalk.red('Invalid schema:', error.message));
1312
+ function pushSchema(appId, opts) {
1313
+ return __awaiter(this, void 0, void 0, function* () {
1314
+ const res = yield readLocalSchemaFileWithErrorLogging();
1315
+ if (!res)
1316
+ return { ok: false };
1317
+ const { schema } = res;
1318
+ const pulledSchemaResponse = yield fetchJson({
1319
+ method: 'GET',
1320
+ path: `/dash/apps/${appId}/schema/pull`,
1321
+ debugName: 'Schema plan',
1322
+ errorMessage: 'Failed to get old schema.',
1323
+ command: 'push',
1324
+ });
1325
+ if (!pulledSchemaResponse.ok)
1326
+ return pulledSchemaResponse;
1327
+ const currentAttrs = pulledSchemaResponse.data['attrs'];
1328
+ const currentApiSchema = pulledSchemaResponse.data['schema'];
1329
+ const oldSchema = apiSchemaToInstantSchemaDef(currentApiSchema, {
1330
+ disableTypeInference: true,
1331
+ });
1332
+ const systemCatalogIdentNames = collectSystemCatalogIdentNames(currentAttrs);
1333
+ try {
1334
+ validateSchema(schema, systemCatalogIdentNames);
1335
+ }
1336
+ catch (error) {
1337
+ if (error instanceof SchemaValidationError) {
1338
+ console.error(chalk.red('Invalid schema:', error.message));
1339
+ }
1340
+ else {
1341
+ console.error('Unexpected error:', error);
1342
+ }
1343
+ return { ok: false };
1344
+ }
1345
+ const renameSelector = program.optsWithGlobals().yes
1346
+ ? buildAutoRenameSelector(opts)
1347
+ : resolveRenames;
1348
+ const diffResult = yield diffSchemas(oldSchema, schema, renameSelector, systemCatalogIdentNames);
1349
+ if (currentAttrs === undefined) {
1350
+ throw new Error("Couldn't get current schema from server");
1351
+ }
1352
+ const txSteps = convertTxSteps(diffResult, currentAttrs);
1353
+ if (txSteps.length === 0) {
1354
+ console.log(chalk.bgGray('No schema changes to apply!'));
1355
+ return { ok: true };
1356
+ }
1357
+ let wantsToPush = false;
1358
+ try {
1359
+ const groupedSteps = groupSteps(diffResult);
1360
+ const lines = renderSchemaPlan(groupedSteps, currentAttrs);
1361
+ if (program.optsWithGlobals().yes) {
1362
+ console.log('Applying schema changes...');
1363
+ console.log(lines.join('\n'));
1364
+ }
1365
+ wantsToPush = yield promptOk({
1366
+ promptText: 'Push these changes?',
1367
+ yesText: 'Push',
1368
+ noText: 'Cancel',
1369
+ modifyOutput: (output) => {
1370
+ let both = lines.join('\n') + '\n\n' + output;
1371
+ return boxen(both, {
1372
+ dimBorder: true,
1373
+ padding: {
1374
+ left: 1,
1375
+ right: 1,
1376
+ },
1377
+ });
1378
+ },
1379
+ }, program.opts());
1380
+ }
1381
+ catch (error) {
1382
+ if (error instanceof CancelSchemaError) {
1383
+ console.info('Schema migration cancelled!');
1384
+ }
1385
+ return { ok: false };
1386
+ }
1387
+ if (verbose) {
1388
+ console.log(txSteps);
1389
+ }
1390
+ if (wantsToPush) {
1391
+ const applyRes = yield fetchJson({
1392
+ method: 'POST',
1393
+ path: `/dash/apps/${appId}/schema/steps/apply`,
1394
+ debugName: 'Schema apply',
1395
+ errorMessage: 'Failed to update schema.',
1396
+ body: {
1397
+ steps: txSteps,
1398
+ },
1399
+ command: 'push',
1400
+ });
1401
+ console.log(chalk.green('Schema updated!'));
1402
+ if (!applyRes.ok)
1403
+ return applyRes;
1404
+ if (applyRes.data['indexing-jobs']) {
1405
+ yield waitForIndexingJobsToFinish(appId, applyRes.data['indexing-jobs']);
1406
+ }
1262
1407
  }
1263
1408
  else {
1264
- console.error('Unexpected error:', error);
1409
+ console.info('Schema migration cancelled!');
1265
1410
  }
1266
- return { ok: false };
1267
- }
1268
- const renameSelector = program.optsWithGlobals().yes
1269
- ? buildAutoRenameSelector(opts)
1270
- : resolveRenames;
1271
- const diffResult = await diffSchemas(oldSchema, schema, renameSelector, systemCatalogIdentNames);
1272
- if (currentAttrs === undefined) {
1273
- throw new Error("Couldn't get current schema from server");
1274
- }
1275
- const txSteps = convertTxSteps(diffResult, currentAttrs);
1276
- if (txSteps.length === 0) {
1277
- console.log(chalk.bgGray('No schema changes to apply!'));
1278
1411
  return { ok: true };
1279
- }
1280
- let wantsToPush = false;
1281
- try {
1282
- const groupedSteps = groupSteps(diffResult);
1283
- const lines = renderSchemaPlan(groupedSteps, currentAttrs);
1284
- if (program.optsWithGlobals().yes) {
1285
- console.log('Applying schema changes...');
1286
- console.log(lines.join('\n'));
1412
+ });
1413
+ }
1414
+ function claimEphemeralApp(appId, adminToken) {
1415
+ return __awaiter(this, void 0, void 0, function* () {
1416
+ const res = yield fetchJson({
1417
+ method: 'POST',
1418
+ body: {
1419
+ app_id: appId,
1420
+ token: adminToken,
1421
+ },
1422
+ path: `/dash/apps/ephemeral/${appId}/claim`,
1423
+ debugName: 'Claim ephemeral app',
1424
+ errorMessage: 'Failed to claim ephemeral app.',
1425
+ command: 'claim',
1426
+ });
1427
+ if (!res.ok)
1428
+ return res;
1429
+ console.log(chalk.green('App claimed!'));
1430
+ return { ok: true };
1431
+ });
1432
+ }
1433
+ function pushPerms(appId) {
1434
+ return __awaiter(this, void 0, void 0, function* () {
1435
+ const res = yield readLocalPermsFileWithErrorLogging();
1436
+ if (!res) {
1437
+ return { ok: true };
1287
1438
  }
1288
- wantsToPush = await promptOk({
1289
- promptText: 'Push these changes?',
1290
- yesText: 'Push',
1291
- noText: 'Cancel',
1439
+ console.log('Planning perms...');
1440
+ const prodPerms = yield fetchJson({
1441
+ path: `/dash/apps/${appId}/perms/pull`,
1442
+ debugName: 'Perms pull',
1443
+ errorMessage: 'Failed to pull perms.',
1444
+ command: 'push',
1445
+ });
1446
+ if (!prodPerms.ok)
1447
+ return prodPerms;
1448
+ const diffedStr = jsonDiff.diffString(prodPerms.data.perms || {}, res.perms || {});
1449
+ if (!diffedStr.length) {
1450
+ console.log('No perms changes detected. Skipping.');
1451
+ return { ok: true };
1452
+ }
1453
+ const okPush = yield promptOk({
1454
+ promptText: 'Push these changes to your perms?',
1292
1455
  modifyOutput: (output) => {
1293
- let both = lines.join('\n') + '\n\n' + output;
1456
+ let both = diffedStr + '\n' + output;
1294
1457
  return boxen(both, {
1295
1458
  dimBorder: true,
1296
1459
  padding: {
@@ -1300,130 +1463,52 @@ async function pushSchema(appId, opts) {
1300
1463
  });
1301
1464
  },
1302
1465
  }, program.opts());
1303
- }
1304
- catch (error) {
1305
- if (error instanceof CancelSchemaError) {
1306
- console.info('Schema migration cancelled!');
1307
- }
1308
- return { ok: false };
1309
- }
1310
- if (verbose) {
1311
- console.log(txSteps);
1312
- }
1313
- if (wantsToPush) {
1314
- const applyRes = await fetchJson({
1466
+ if (!okPush)
1467
+ return { ok: true };
1468
+ const permsRes = yield fetchJson({
1315
1469
  method: 'POST',
1316
- path: `/dash/apps/${appId}/schema/steps/apply`,
1470
+ path: `/dash/apps/${appId}/rules`,
1317
1471
  debugName: 'Schema apply',
1318
1472
  errorMessage: 'Failed to update schema.',
1319
1473
  body: {
1320
- steps: txSteps,
1474
+ code: res.perms,
1321
1475
  },
1322
1476
  command: 'push',
1323
1477
  });
1324
- console.log(chalk.green('Schema updated!'));
1325
- if (!applyRes.ok)
1326
- return applyRes;
1327
- if (applyRes.data['indexing-jobs']) {
1328
- await waitForIndexingJobsToFinish(appId, applyRes.data['indexing-jobs']);
1329
- }
1330
- }
1331
- else {
1332
- console.info('Schema migration cancelled!');
1333
- }
1334
- return { ok: true };
1335
- }
1336
- async function claimEphemeralApp(appId, adminToken) {
1337
- const res = await fetchJson({
1338
- method: 'POST',
1339
- body: {
1340
- app_id: appId,
1341
- token: adminToken,
1342
- },
1343
- path: `/dash/apps/ephemeral/${appId}/claim`,
1344
- debugName: 'Claim ephemeral app',
1345
- errorMessage: 'Failed to claim ephemeral app.',
1346
- command: 'claim',
1347
- });
1348
- if (!res.ok)
1349
- return res;
1350
- console.log(chalk.green('App claimed!'));
1351
- return { ok: true };
1352
- }
1353
- async function pushPerms(appId) {
1354
- const res = await readLocalPermsFileWithErrorLogging();
1355
- if (!res) {
1478
+ if (!permsRes.ok)
1479
+ return permsRes;
1480
+ console.log(chalk.green('Permissions updated!'));
1356
1481
  return { ok: true };
1357
- }
1358
- console.log('Planning perms...');
1359
- const prodPerms = await fetchJson({
1360
- path: `/dash/apps/${appId}/perms/pull`,
1361
- debugName: 'Perms pull',
1362
- errorMessage: 'Failed to pull perms.',
1363
- command: 'push',
1364
1482
  });
1365
- if (!prodPerms.ok)
1366
- return prodPerms;
1367
- const diffedStr = jsonDiff.diffString(prodPerms.data.perms || {}, res.perms || {});
1368
- if (!diffedStr.length) {
1369
- console.log('No perms changes detected. Skipping.');
1370
- return { ok: true };
1371
- }
1372
- const okPush = await promptOk({
1373
- promptText: 'Push these changes to your perms?',
1374
- modifyOutput: (output) => {
1375
- let both = diffedStr + '\n' + output;
1376
- return boxen(both, {
1377
- dimBorder: true,
1378
- padding: {
1379
- left: 1,
1380
- right: 1,
1381
- },
1483
+ }
1484
+ function waitForAuthToken(_a) {
1485
+ return __awaiter(this, arguments, void 0, function* ({ secret }) {
1486
+ var _b, _c, _d;
1487
+ for (let i = 1; i <= 120; i++) {
1488
+ yield sleep(1000);
1489
+ const authCheckRes = yield fetchJson({
1490
+ method: 'POST',
1491
+ debugName: 'Auth check',
1492
+ errorMessage: 'Failed to check auth status.',
1493
+ path: '/dash/cli/auth/check',
1494
+ body: { secret },
1495
+ noAuth: true,
1496
+ noLogError: true,
1497
+ command: 'login',
1382
1498
  });
1383
- },
1384
- }, program.opts());
1385
- if (!okPush)
1386
- return { ok: true };
1387
- const permsRes = await fetchJson({
1388
- method: 'POST',
1389
- path: `/dash/apps/${appId}/rules`,
1390
- debugName: 'Schema apply',
1391
- errorMessage: 'Failed to update schema.',
1392
- body: {
1393
- code: res.perms,
1394
- },
1395
- command: 'push',
1396
- });
1397
- if (!permsRes.ok)
1398
- return permsRes;
1399
- console.log(chalk.green('Permissions updated!'));
1400
- return { ok: true };
1401
- }
1402
- async function waitForAuthToken({ secret }) {
1403
- for (let i = 1; i <= 120; i++) {
1404
- await sleep(1000);
1405
- const authCheckRes = await fetchJson({
1406
- method: 'POST',
1407
- debugName: 'Auth check',
1408
- errorMessage: 'Failed to check auth status.',
1409
- path: '/dash/cli/auth/check',
1410
- body: { secret },
1411
- noAuth: true,
1412
- noLogError: true,
1413
- command: 'login',
1414
- });
1415
- if (authCheckRes.ok) {
1416
- return authCheckRes.data;
1417
- }
1418
- if (authCheckRes.data?.hint.errors?.[0]?.issue === 'waiting-for-user') {
1419
- continue;
1499
+ if (authCheckRes.ok) {
1500
+ return authCheckRes.data;
1501
+ }
1502
+ if (((_d = (_c = (_b = authCheckRes.data) === null || _b === void 0 ? void 0 : _b.hint.errors) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.issue) === 'waiting-for-user') {
1503
+ continue;
1504
+ }
1505
+ error('Failed to authenticate ');
1506
+ prettyPrintJSONErr(authCheckRes.data);
1507
+ return;
1420
1508
  }
1421
- error('Failed to authenticate ');
1422
- prettyPrintJSONErr(authCheckRes.data);
1423
- return;
1424
- }
1425
- error('Timed out waiting for authentication');
1426
- return null;
1509
+ error('Timed out waiting for authentication');
1510
+ return null;
1511
+ });
1427
1512
  }
1428
1513
  // resources
1429
1514
  /**
@@ -1440,69 +1525,66 @@ async function waitForAuthToken({ secret }) {
1440
1525
  * @param {string} [options.command] - The CLI command being executed (e.g., 'push', 'pull', 'login')
1441
1526
  * @returns {Promise<{ ok: boolean; data: any }>}
1442
1527
  */
1443
- async function fetchJson({ debugName, errorMessage, path, body, method, noAuth, noLogError, command, }) {
1444
- const withAuth = !noAuth;
1445
- const withErrorLogging = !noLogError;
1446
- let authToken = null;
1447
- if (withAuth) {
1448
- authToken = await readConfigAuthTokenWithErrorLogging();
1449
- if (!authToken) {
1450
- return { ok: false, data: undefined };
1451
- }
1452
- }
1453
- const timeoutMs = 1000 * 60 * 5; // 5 minutes
1454
- try {
1455
- const res = await fetch(`${instantBackendOrigin}${path}`, {
1456
- method: method ?? 'GET',
1457
- headers: {
1458
- ...(withAuth ? { Authorization: `Bearer ${authToken}` } : {}),
1459
- 'Content-Type': 'application/json',
1460
- 'X-Instant-Source': 'instant-cli',
1461
- 'X-Instant-Version': version,
1462
- ...(command ? { 'X-Instant-Command': command } : {}),
1463
- },
1464
- body: body ? JSON.stringify(body) : undefined,
1465
- signal: AbortSignal.timeout(timeoutMs),
1466
- });
1467
- if (verbose) {
1468
- console.log(debugName, 'response:', res.status, res.statusText);
1528
+ function fetchJson(_a) {
1529
+ return __awaiter(this, arguments, void 0, function* ({ debugName, errorMessage, path, body, method, noAuth, noLogError, command, }) {
1530
+ const withAuth = !noAuth;
1531
+ const withErrorLogging = !noLogError;
1532
+ let authToken = null;
1533
+ if (withAuth) {
1534
+ authToken = yield readConfigAuthTokenWithErrorLogging();
1535
+ if (!authToken) {
1536
+ return { ok: false, data: undefined };
1537
+ }
1469
1538
  }
1470
- let data;
1539
+ const timeoutMs = 1000 * 60 * 5; // 5 minutes
1471
1540
  try {
1472
- data = await res.json();
1473
- }
1474
- catch {
1475
- data = null;
1476
- }
1477
- if (verbose && data) {
1478
- console.log(debugName, 'json:', JSON.stringify(data, null, 2));
1479
- }
1480
- if (!res.ok) {
1481
- if (withErrorLogging) {
1482
- error(errorMessage);
1483
- prettyPrintJSONErr(data);
1541
+ const res = yield fetch(`${instantBackendOrigin}${path}`, {
1542
+ method: method !== null && method !== void 0 ? method : 'GET',
1543
+ headers: Object.assign(Object.assign(Object.assign({}, (withAuth ? { Authorization: `Bearer ${authToken}` } : {})), { 'Content-Type': 'application/json', 'X-Instant-Source': 'instant-cli', 'X-Instant-Version': version }), (command ? { 'X-Instant-Command': command } : {})),
1544
+ body: body ? JSON.stringify(body) : undefined,
1545
+ signal: AbortSignal.timeout(timeoutMs),
1546
+ });
1547
+ if (verbose) {
1548
+ console.log(debugName, 'response:', res.status, res.statusText);
1484
1549
  }
1485
- return { ok: false, data };
1486
- }
1487
- return { ok: true, data };
1488
- }
1489
- catch (err) {
1490
- if (withErrorLogging) {
1491
- if (err.name === 'AbortError') {
1492
- error(`Timeout: It took more than ${timeoutMs / 60000} minutes to get the result.`);
1550
+ let data;
1551
+ try {
1552
+ data = yield res.json();
1493
1553
  }
1494
- else {
1495
- error(`Error: type: ${err.name}, message: ${err.message}`);
1554
+ catch (_b) {
1555
+ data = null;
1556
+ }
1557
+ if (verbose && data) {
1558
+ console.log(debugName, 'json:', JSON.stringify(data, null, 2));
1496
1559
  }
1560
+ if (!res.ok) {
1561
+ if (withErrorLogging) {
1562
+ error(errorMessage);
1563
+ prettyPrintJSONErr(data);
1564
+ }
1565
+ return { ok: false, data };
1566
+ }
1567
+ return { ok: true, data };
1497
1568
  }
1498
- return { ok: false, data: null };
1499
- }
1569
+ catch (err) {
1570
+ if (withErrorLogging) {
1571
+ if (err.name === 'AbortError') {
1572
+ error(`Timeout: It took more than ${timeoutMs / 60000} minutes to get the result.`);
1573
+ }
1574
+ else {
1575
+ error(`Error: type: ${err.name}, message: ${err.message}`);
1576
+ }
1577
+ }
1578
+ return { ok: false, data: null };
1579
+ }
1580
+ });
1500
1581
  }
1501
1582
  function prettyPrintJSONErr(data) {
1502
- if (data?.message) {
1583
+ var _a;
1584
+ if (data === null || data === void 0 ? void 0 : data.message) {
1503
1585
  error(data.message);
1504
1586
  }
1505
- if (Array.isArray(data?.hint?.errors)) {
1587
+ if (Array.isArray((_a = data === null || data === void 0 ? void 0 : data.hint) === null || _a === void 0 ? void 0 : _a.errors)) {
1506
1588
  for (const err of data.hint.errors) {
1507
1589
  error(`${err.in ? err.in.join('->') + ': ' : ''}${err.message}`);
1508
1590
  }
@@ -1511,109 +1593,128 @@ function prettyPrintJSONErr(data) {
1511
1593
  error('Failed to parse error response');
1512
1594
  }
1513
1595
  }
1514
- async function readLocalPermsFile() {
1515
- const readCandidates = getPermsReadCandidates();
1516
- const res = await loadConfig({
1517
- sources: readCandidates,
1518
- merge: false,
1596
+ function readLocalPermsFile() {
1597
+ return __awaiter(this, void 0, void 0, function* () {
1598
+ const readCandidates = getPermsReadCandidates();
1599
+ const res = yield loadConfig({
1600
+ sources: readCandidates,
1601
+ merge: false,
1602
+ });
1603
+ if (!res.config)
1604
+ return;
1605
+ const relativePath = path.relative(process.cwd(), res.sources[0]);
1606
+ return { path: relativePath, perms: res.config };
1519
1607
  });
1520
- if (!res.config)
1521
- return;
1522
- const relativePath = path.relative(process.cwd(), res.sources[0]);
1523
- return { path: relativePath, perms: res.config };
1524
- }
1525
- async function readLocalPermsFileWithErrorLogging() {
1526
- const res = await readLocalPermsFile();
1527
- if (!res) {
1528
- error(`We couldn't find your ${chalk.yellow('`instant.perms.ts`')} file. Make sure it's in the root directory. (Hint: You can use an INSTANT_PERMS_FILE_PATH environment variable to specify it.)`);
1529
- }
1530
- return res;
1531
1608
  }
1532
- async function readLocalSchemaFile() {
1533
- const readCandidates = getSchemaReadCandidates();
1534
- const res = await loadConfig({
1535
- sources: readCandidates,
1536
- merge: false,
1609
+ function readLocalPermsFileWithErrorLogging() {
1610
+ return __awaiter(this, void 0, void 0, function* () {
1611
+ const res = yield readLocalPermsFile();
1612
+ if (!res) {
1613
+ error(`We couldn't find your ${chalk.yellow('`instant.perms.ts`')} file. Make sure it's in the root directory. (Hint: You can use an INSTANT_PERMS_FILE_PATH environment variable to specify it.)`);
1614
+ }
1615
+ return res;
1537
1616
  });
1538
- if (!res.config)
1539
- return;
1540
- const relativePath = path.relative(process.cwd(), res.sources[0]);
1541
- return { path: relativePath, schema: res.config };
1542
- }
1543
- async function readInstantConfigFile() {
1544
- return (await loadConfig({
1545
- sources: [
1546
- // load from `instant.config.xx`
1547
- {
1548
- files: 'instant.config',
1549
- extensions: ['ts', 'mts', 'cts', 'js', 'mjs', 'cjs', 'json'],
1550
- },
1551
- ],
1552
- // if false, the only the first matched will be loaded
1553
- // if true, all matched will be loaded and deep merged
1554
- merge: false,
1555
- })).config;
1556
- }
1557
- async function readLocalSchemaFileWithErrorLogging() {
1558
- const res = await readLocalSchemaFile();
1559
- if (!res) {
1560
- error(`We couldn't find your ${chalk.yellow('`instant.schema.ts`')} file. Make sure it's in the root directory. (Hint: You can use an INSTANT_SCHEMA_FILE_PATH environment variable to specify it.)`);
1561
- return;
1562
- }
1563
- if (res.schema?.constructor?.name !== 'InstantSchemaDef') {
1564
- error("We couldn't find your schema export.");
1565
- error('In your ' +
1566
- chalk.green('`instant.schema.ts`') +
1567
- ' file, make sure you ' +
1568
- chalk.green('`export default schema`'));
1569
- return;
1570
- }
1571
- return res;
1572
1617
  }
1573
- async function readConfigAuthToken(allowAdminToken = true) {
1574
- const options = program.opts();
1575
- if (typeof options.token === 'string') {
1576
- return options.token;
1577
- }
1578
- if (process.env.INSTANT_CLI_AUTH_TOKEN) {
1579
- return process.env.INSTANT_CLI_AUTH_TOKEN;
1580
- }
1581
- if (allowAdminToken) {
1582
- const adminTokenNames = Object.values(potentialAdminTokenEnvs);
1583
- for (const envName of adminTokenNames) {
1584
- const token = process.env[envName];
1585
- if (token) {
1586
- return token;
1587
- }
1618
+ function readLocalSchemaFile() {
1619
+ return __awaiter(this, void 0, void 0, function* () {
1620
+ const readCandidates = getSchemaReadCandidates();
1621
+ const res = yield loadConfig({
1622
+ sources: readCandidates,
1623
+ merge: false,
1624
+ });
1625
+ if (!res.config)
1626
+ return;
1627
+ const relativePath = path.relative(process.cwd(), res.sources[0]);
1628
+ return { path: relativePath, schema: res.config };
1629
+ });
1630
+ }
1631
+ function readInstantConfigFile() {
1632
+ return __awaiter(this, void 0, void 0, function* () {
1633
+ return (yield loadConfig({
1634
+ sources: [
1635
+ // load from `instant.config.xx`
1636
+ {
1637
+ files: 'instant.config',
1638
+ extensions: ['ts', 'mts', 'cts', 'js', 'mjs', 'cjs', 'json'],
1639
+ },
1640
+ ],
1641
+ // if false, the only the first matched will be loaded
1642
+ // if true, all matched will be loaded and deep merged
1643
+ merge: false,
1644
+ })).config;
1645
+ });
1646
+ }
1647
+ function readLocalSchemaFileWithErrorLogging() {
1648
+ return __awaiter(this, void 0, void 0, function* () {
1649
+ var _a, _b;
1650
+ const res = yield readLocalSchemaFile();
1651
+ if (!res) {
1652
+ error(`We couldn't find your ${chalk.yellow('`instant.schema.ts`')} file. Make sure it's in the root directory. (Hint: You can use an INSTANT_SCHEMA_FILE_PATH environment variable to specify it.)`);
1653
+ return;
1588
1654
  }
1589
- }
1590
- const authToken = await readFile(getAuthPaths().authConfigFilePath, 'utf-8').catch(() => null);
1591
- if (authToken) {
1592
- return authToken;
1593
- }
1594
- return null;
1655
+ if (((_b = (_a = res.schema) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name) !== 'InstantSchemaDef') {
1656
+ error("We couldn't find your schema export.");
1657
+ error('In your ' +
1658
+ chalk.green('`instant.schema.ts`') +
1659
+ ' file, make sure you ' +
1660
+ chalk.green('`export default schema`'));
1661
+ return;
1662
+ }
1663
+ return res;
1664
+ });
1595
1665
  }
1596
- export async function readConfigAuthTokenWithErrorLogging() {
1597
- const token = await readConfigAuthToken();
1598
- if (!token) {
1599
- error(`Looks like you are not logged in. Please log in with ${chalk.green('`instant-cli login`')}`);
1600
- }
1601
- return token;
1666
+ function readConfigAuthToken() {
1667
+ return __awaiter(this, arguments, void 0, function* (allowAdminToken = true) {
1668
+ const options = program.opts();
1669
+ if (typeof options.token === 'string') {
1670
+ return options.token;
1671
+ }
1672
+ if (process.env.INSTANT_CLI_AUTH_TOKEN) {
1673
+ return process.env.INSTANT_CLI_AUTH_TOKEN;
1674
+ }
1675
+ if (allowAdminToken) {
1676
+ const adminTokenNames = Object.values(potentialAdminTokenEnvs);
1677
+ for (const envName of adminTokenNames) {
1678
+ const token = process.env[envName];
1679
+ if (token) {
1680
+ return token;
1681
+ }
1682
+ }
1683
+ }
1684
+ const authToken = yield readFile(getAuthPaths().authConfigFilePath, 'utf-8').catch(() => null);
1685
+ if (authToken) {
1686
+ return authToken;
1687
+ }
1688
+ return null;
1689
+ });
1602
1690
  }
1603
- async function readAuthTokenOrLoginWithErrorLogging() {
1604
- const token = await readConfigAuthToken();
1605
- if (token)
1691
+ export function readConfigAuthTokenWithErrorLogging() {
1692
+ return __awaiter(this, void 0, void 0, function* () {
1693
+ const token = yield readConfigAuthToken();
1694
+ if (!token) {
1695
+ error(`Looks like you are not logged in. Please log in with ${chalk.green('`instant-cli login`')}`);
1696
+ }
1606
1697
  return token;
1607
- console.log(`Looks like you are not logged in...`);
1608
- console.log(`Let's log in!`);
1609
- return await login({});
1610
- }
1611
- async function saveConfigAuthToken(authToken) {
1612
- const authPaths = getAuthPaths();
1613
- await mkdir(authPaths.appConfigDirPath, {
1614
- recursive: true,
1615
1698
  });
1616
- return writeFile(authPaths.authConfigFilePath, authToken, 'utf-8');
1699
+ }
1700
+ function readAuthTokenOrLoginWithErrorLogging() {
1701
+ return __awaiter(this, void 0, void 0, function* () {
1702
+ const token = yield readConfigAuthToken();
1703
+ if (token)
1704
+ return token;
1705
+ console.log(`Looks like you are not logged in...`);
1706
+ console.log(`Let's log in!`);
1707
+ return yield login({});
1708
+ });
1709
+ }
1710
+ function saveConfigAuthToken(authToken) {
1711
+ return __awaiter(this, void 0, void 0, function* () {
1712
+ const authPaths = getAuthPaths();
1713
+ yield mkdir(authPaths.appConfigDirPath, {
1714
+ recursive: true,
1715
+ });
1716
+ return writeFile(authPaths.authConfigFilePath, authToken, 'utf-8');
1717
+ });
1617
1718
  }
1618
1719
  // utils
1619
1720
  function sleep(ms) {
@@ -1639,16 +1740,20 @@ function identName(ident) {
1639
1740
  return `${identEtype(ident)}.${identLabel(ident)}`;
1640
1741
  }
1641
1742
  function attrFwdLabel(attr) {
1642
- return attr['forward-identity']?.[2];
1743
+ var _a;
1744
+ return (_a = attr['forward-identity']) === null || _a === void 0 ? void 0 : _a[2];
1643
1745
  }
1644
1746
  function attrFwdEtype(attr) {
1645
- return attr['forward-identity']?.[1];
1747
+ var _a;
1748
+ return (_a = attr['forward-identity']) === null || _a === void 0 ? void 0 : _a[1];
1646
1749
  }
1647
1750
  function attrRevLabel(attr) {
1648
- return attr['reverse-identity']?.[2];
1751
+ var _a;
1752
+ return (_a = attr['reverse-identity']) === null || _a === void 0 ? void 0 : _a[2];
1649
1753
  }
1650
1754
  function attrRevEtype(attr) {
1651
- return attr['reverse-identity']?.[1];
1755
+ var _a;
1756
+ return (_a = attr['reverse-identity']) === null || _a === void 0 ? void 0 : _a[1];
1652
1757
  }
1653
1758
  function attrFwdName(attr) {
1654
1759
  return `${attrFwdEtype(attr)}.${attrFwdLabel(attr)}`;
@@ -1669,23 +1774,26 @@ function isUUID(uuid) {
1669
1774
  const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1670
1775
  return uuidRegex.test(uuid);
1671
1776
  }
1672
- async function detectAppIdFromOptsWithErrorLogging(opts) {
1673
- if (!opts.app)
1674
- return { ok: true };
1675
- const appId = opts.app;
1676
- const config = await readInstantConfigFile();
1677
- const nameMatch = config?.apps?.[appId];
1678
- const namedAppId = nameMatch?.id && isUUID(nameMatch.id) ? nameMatch : null;
1679
- const uuidAppId = appId && isUUID(appId) ? appId : null;
1680
- if (nameMatch && !namedAppId) {
1681
- error(`Expected \`${appId}\` to point to a UUID, but got ${nameMatch.id}.`);
1682
- return { ok: false };
1683
- }
1684
- if (!namedAppId && !uuidAppId) {
1685
- error(`Expected App ID to be a UUID, but got: ${chalk.red(appId)}`);
1686
- return { ok: false };
1687
- }
1688
- return { ok: true, appId: namedAppId || uuidAppId };
1777
+ function detectAppIdFromOptsWithErrorLogging(opts) {
1778
+ return __awaiter(this, void 0, void 0, function* () {
1779
+ var _a;
1780
+ if (!opts.app)
1781
+ return { ok: true };
1782
+ const appId = opts.app;
1783
+ const config = yield readInstantConfigFile();
1784
+ const nameMatch = (_a = config === null || config === void 0 ? void 0 : config.apps) === null || _a === void 0 ? void 0 : _a[appId];
1785
+ const namedAppId = (nameMatch === null || nameMatch === void 0 ? void 0 : nameMatch.id) && isUUID(nameMatch.id) ? nameMatch : null;
1786
+ const uuidAppId = appId && isUUID(appId) ? appId : null;
1787
+ if (nameMatch && !namedAppId) {
1788
+ error(`Expected \`${appId}\` to point to a UUID, but got ${nameMatch.id}.`);
1789
+ return { ok: false };
1790
+ }
1791
+ if (!namedAppId && !uuidAppId) {
1792
+ error(`Expected App ID to be a UUID, but got: ${chalk.red(appId)}`);
1793
+ return { ok: false };
1794
+ }
1795
+ return { ok: true, appId: namedAppId || uuidAppId };
1796
+ });
1689
1797
  }
1690
1798
  function detectAppIdFromEnvWithErrorLogging() {
1691
1799
  const found = Object.keys(potentialEnvs)