instant-cli 0.22.98-experimental.highl.20766596946.1 → 0.22.99-experimental.add-user-perm-rules.20792844601.1

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