instant-cli 0.22.95 → 0.22.96-experimental.add-posthog-frontend.20386914944.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "instant-cli",
3
3
  "type": "module",
4
- "version": "0.22.95",
4
+ "version": "0.22.96-experimental.add-posthog-frontend.20386914944.1",
5
5
  "description": "Instant's CLI",
6
6
  "homepage": "https://github.com/instantdb/instant/tree/main/client/packages/cli",
7
7
  "repository": {
@@ -21,8 +21,6 @@
21
21
  "instant-cli": "bin/index.js"
22
22
  },
23
23
  "dependencies": {
24
- "acorn": "^8.15.0",
25
- "acorn-typescript": "^1.4.13",
26
24
  "ansi-escapes": "4.3.2",
27
25
  "boxen": "^8.0.1",
28
26
  "chalk": "^5.3.0",
@@ -41,9 +39,9 @@
41
39
  "strip-ansi": "^7.1.2",
42
40
  "terminal-link": "^3.0.0",
43
41
  "unconfig": "^0.5.5",
44
- "@instantdb/platform": "0.22.95",
45
- "@instantdb/version": "0.22.95",
46
- "@instantdb/core": "0.22.95"
42
+ "@instantdb/core": "0.22.96-experimental.add-posthog-frontend.20386914944.1",
43
+ "@instantdb/version": "0.22.96-experimental.add-posthog-frontend.20386914944.1",
44
+ "@instantdb/platform": "0.22.96-experimental.add-posthog-frontend.20386914944.1"
47
45
  },
48
46
  "devDependencies": {
49
47
  "@babel/core": "^7.17.9",
package/src/index.js CHANGED
@@ -50,7 +50,6 @@ import {
50
50
  getSchemaPathToWrite,
51
51
  getPermsPathToWrite,
52
52
  } from './util/findConfigCandidates.js';
53
- import { mergeSchema } from './util/mergeSchema.js';
54
53
 
55
54
  const execAsync = promisify(exec);
56
55
 
@@ -479,10 +478,6 @@ program
479
478
  '-p --package <react|react-native|core|admin>',
480
479
  'Which package to automatically install if there is not one installed already.',
481
480
  )
482
- .option(
483
- '--experimental-type-preservation',
484
- "[Experimental] Preserve manual type changes like `status: i.json<'online' | 'offline'>()` when doing `instant-cli pull schema`",
485
- )
486
481
  .description('Pull schema and perm files from production.')
487
482
  .addHelpText(
488
483
  'after',
@@ -660,7 +655,7 @@ async function handlePull(bag, opts) {
660
655
  );
661
656
  return;
662
657
  }
663
- await pull(bag, appId, { ...pkgAndAuthInfo, ...opts });
658
+ await pull(bag, appId, pkgAndAuthInfo);
664
659
  }
665
660
 
666
661
  async function push(bag, appId, opts) {
@@ -769,6 +764,7 @@ async function login(options) {
769
764
  debugName: 'Login register',
770
765
  errorMessage: 'Failed to register login.',
771
766
  noAuth: true,
767
+ command: 'login',
772
768
  });
773
769
 
774
770
  if (!registerRes.ok) {
@@ -934,6 +930,7 @@ async function promptCreateApp(opts) {
934
930
  method: 'GET',
935
931
  path: '/dash',
936
932
  errorMessage: 'Failed to fetch apps.',
933
+ command: 'init',
937
934
  });
938
935
  if (!res.ok) {
939
936
  return { ok: false };
@@ -966,6 +963,7 @@ async function promptCreateApp(opts) {
966
963
  debugName: 'App create',
967
964
  errorMessage: 'Failed to create app.',
968
965
  body: app,
966
+ command: 'init',
969
967
  });
970
968
 
971
969
  if (!appRes.ok) return { ok: false };
@@ -984,6 +982,7 @@ async function promptImportAppOrCreateApp() {
984
982
  method: 'GET',
985
983
  path: '/dash',
986
984
  errorMessage: 'Failed to fetch apps.',
985
+ command: 'init',
987
986
  });
988
987
  if (!res.ok) {
989
988
  return { ok: false };
@@ -1003,6 +1002,7 @@ async function promptImportAppOrCreateApp() {
1003
1002
  method: 'GET',
1004
1003
  path: `/dash/orgs/${orgId}`,
1005
1004
  errorMessage: 'Failed to fetch apps.',
1005
+ command: 'init',
1006
1006
  });
1007
1007
  if (!orgsRes.ok) {
1008
1008
  throw new Error('Failed to fetch org apps');
@@ -1032,6 +1032,7 @@ async function createApp(title, orgId) {
1032
1032
  debugName: 'App create',
1033
1033
  errorMessage: 'Failed to create app.',
1034
1034
  body: app,
1035
+ command: 'init',
1035
1036
  });
1036
1037
  if (!appRes.ok) throw new Error('Failed to create app');
1037
1038
  return { appId: id, adminToken: token };
@@ -1188,16 +1189,14 @@ async function getOrPromptPackageAndAuthInfoWithErrorLogging(opts) {
1188
1189
  return { pkgDir, projectType, instantModuleName, authToken };
1189
1190
  }
1190
1191
 
1191
- async function pullSchema(
1192
- appId,
1193
- { pkgDir, instantModuleName, experimentalTypePreservation },
1194
- ) {
1192
+ async function pullSchema(appId, { pkgDir, instantModuleName }) {
1195
1193
  console.log('Pulling schema...');
1196
1194
 
1197
1195
  const pullRes = await fetchJson({
1198
1196
  path: `/dash/apps/${appId}/schema/pull`,
1199
1197
  debugName: 'Schema pull',
1200
1198
  errorMessage: 'Failed to pull schema.',
1199
+ command: 'pull',
1201
1200
  });
1202
1201
 
1203
1202
  if (!pullRes.ok) return pullRes;
@@ -1229,26 +1228,16 @@ async function pullSchema(
1229
1228
  const shortSchemaPath = getSchemaPathToWrite(prev?.path);
1230
1229
  const schemaPath = join(pkgDir, shortSchemaPath);
1231
1230
 
1232
- let newSchemaContent = generateSchemaTypescriptFile(
1233
- prev?.schema,
1234
- apiSchemaToInstantSchemaDef(pullRes.data.schema),
1235
- instantModuleName,
1231
+ await writeTypescript(
1232
+ schemaPath,
1233
+ generateSchemaTypescriptFile(
1234
+ prev?.schema,
1235
+ apiSchemaToInstantSchemaDef(pullRes.data.schema),
1236
+ instantModuleName,
1237
+ ),
1238
+ 'utf-8',
1236
1239
  );
1237
1240
 
1238
- if (prev && experimentalTypePreservation) {
1239
- try {
1240
- const oldSchemaContent = await readFile(prev.path, 'utf-8');
1241
- newSchemaContent = mergeSchema(oldSchemaContent, newSchemaContent);
1242
- } catch (e) {
1243
- warn(
1244
- 'Failed to merge schema with existing file. Overwriting instead.',
1245
- e,
1246
- );
1247
- }
1248
- }
1249
-
1250
- await writeTypescript(schemaPath, newSchemaContent, 'utf-8');
1251
-
1252
1241
  console.log('✅ Wrote schema to ' + shortSchemaPath);
1253
1242
 
1254
1243
  return { ok: true };
@@ -1261,6 +1250,7 @@ async function pullPerms(appId, { pkgDir, instantModuleName }) {
1261
1250
  path: `/dash/apps/${appId}/perms/pull`,
1262
1251
  debugName: 'Perms pull',
1263
1252
  errorMessage: 'Failed to pull perms.',
1253
+ command: 'pull',
1264
1254
  });
1265
1255
 
1266
1256
  if (!pullRes.ok) return pullRes;
@@ -1507,6 +1497,7 @@ async function waitForIndexingJobsToFinish(appId, data) {
1507
1497
  method: 'GET',
1508
1498
  path: `/dash/apps/${appId}/indexing-jobs/group/${groupId}`,
1509
1499
  errorMessage: 'Failed to check indexing status.',
1500
+ command: 'push',
1510
1501
  });
1511
1502
  if (!res.ok) {
1512
1503
  break;
@@ -1576,6 +1567,7 @@ async function pushSchema(appId, opts) {
1576
1567
  path: `/dash/apps/${appId}/schema/pull`,
1577
1568
  debugName: 'Schema plan',
1578
1569
  errorMessage: 'Failed to get old schema.',
1570
+ command: 'push',
1579
1571
  });
1580
1572
 
1581
1573
  if (!pulledSchemaResponse.ok) return pulledSchemaResponse;
@@ -1666,6 +1658,7 @@ async function pushSchema(appId, opts) {
1666
1658
  body: {
1667
1659
  steps: txSteps,
1668
1660
  },
1661
+ command: 'push',
1669
1662
  });
1670
1663
  console.log(chalk.green('Schema updated!'));
1671
1664
  if (!applyRes.ok) return applyRes;
@@ -1690,6 +1683,7 @@ async function claimEphemeralApp(appId, adminToken) {
1690
1683
  path: `/dash/apps/ephemeral/${appId}/claim`,
1691
1684
  debugName: 'Claim ephemeral app',
1692
1685
  errorMessage: 'Failed to claim ephemeral app.',
1686
+ command: 'claim',
1693
1687
  });
1694
1688
 
1695
1689
  if (!res.ok) return res;
@@ -1710,6 +1704,7 @@ async function pushPerms(appId) {
1710
1704
  path: `/dash/apps/${appId}/perms/pull`,
1711
1705
  debugName: 'Perms pull',
1712
1706
  errorMessage: 'Failed to pull perms.',
1707
+ command: 'push',
1713
1708
  });
1714
1709
 
1715
1710
  if (!prodPerms.ok) return prodPerms;
@@ -1749,6 +1744,7 @@ async function pushPerms(appId) {
1749
1744
  body: {
1750
1745
  code: res.perms,
1751
1746
  },
1747
+ command: 'push',
1752
1748
  });
1753
1749
 
1754
1750
  if (!permsRes.ok) return permsRes;
@@ -1769,6 +1765,7 @@ async function waitForAuthToken({ secret }) {
1769
1765
  body: { secret },
1770
1766
  noAuth: true,
1771
1767
  noLogError: true,
1768
+ command: 'login',
1772
1769
  });
1773
1770
  if (authCheckRes.ok) {
1774
1771
  return authCheckRes.data;
@@ -1797,6 +1794,7 @@ async function waitForAuthToken({ secret }) {
1797
1794
  * @param {Object} [options.body=undefined]
1798
1795
  * @param {boolean} [options.noAuth]
1799
1796
  * @param {boolean} [options.noLogError]
1797
+ * @param {string} [options.command] - The CLI command being executed (e.g., 'push', 'pull', 'login')
1800
1798
  * @returns {Promise<{ ok: boolean; data: any }>}
1801
1799
  */
1802
1800
  async function fetchJson({
@@ -1807,6 +1805,7 @@ async function fetchJson({
1807
1805
  method,
1808
1806
  noAuth,
1809
1807
  noLogError,
1808
+ command,
1810
1809
  }) {
1811
1810
  const withAuth = !noAuth;
1812
1811
  const withErrorLogging = !noLogError;
@@ -1825,7 +1824,9 @@ async function fetchJson({
1825
1824
  headers: {
1826
1825
  ...(withAuth ? { Authorization: `Bearer ${authToken}` } : {}),
1827
1826
  'Content-Type': 'application/json',
1828
- 'Instant-CLI-Version': version,
1827
+ 'X-Instant-Source': 'instant-cli',
1828
+ 'X-Instant-Version': version,
1829
+ ...(command ? { 'X-Instant-Command': command } : {}),
1829
1830
  },
1830
1831
  body: body ? JSON.stringify(body) : undefined,
1831
1832
  signal: AbortSignal.timeout(timeoutMs),
@@ -1,197 +0,0 @@
1
- import { describe, test, expect } from 'vitest';
2
- import { mergeSchema } from '../src/util/mergeSchema';
3
-
4
- test('preserves type annotations', () => {
5
- const oldFile = `
6
- import { i } from '@instantdb/core';
7
- import { Label } from './types';
8
-
9
- const _schema = i.schema({
10
- entities: {
11
- $users: i.entity({
12
- email: i.string().unique().indexed(),
13
- }),
14
- todos: i.entity({
15
- title: i.string(),
16
- status: i.string<'todo' | 'in_progress' | 'done'>(),
17
- priority: i.number<1 | 2 | 3>(),
18
- labels: i.json<Label[]>().optional(),
19
- }),
20
- projects: i.entity({
21
- name: i.string(),
22
- }),
23
- },
24
- links: {
25
- todoProject: {
26
- forward: { on: 'todos', has: 'one', label: 'project' },
27
- reverse: { on: 'projects', has: 'many', label: 'todos' },
28
- },
29
- projectOwner: {
30
- forward: { on: 'projects', has: 'one', label: 'owner' },
31
- reverse: { on: '$users', has: 'many', label: 'projects' },
32
- },
33
- },
34
- rooms: {
35
- projectRoom: {
36
- presence: i.entity({
37
- cursor: i.json<{ x: number; y: number }>(),
38
- }),
39
- },
40
- },
41
- });
42
-
43
- export default _schema;
44
- `;
45
-
46
- const newFile = `
47
- import { i } from '@instantdb/core';
48
-
49
- const _schema = i.schema({
50
- entities: {
51
- $users: i.entity({
52
- email: i.string().unique().indexed(),
53
- }),
54
- todos: i.entity({
55
- title: i.string(),
56
- status: i.string(),
57
- priority: i.number(),
58
- labels: i.json().optional(),
59
- }),
60
- projects: i.entity({
61
- name: i.string(),
62
- }),
63
- },
64
- links: {
65
- todoProject: {
66
- forward: { on: 'todos', has: 'one', label: 'project' },
67
- reverse: { on: 'projects', has: 'many', label: 'todos' },
68
- },
69
- projectOwner: {
70
- forward: { on: 'projects', has: 'one', label: 'owner' },
71
- reverse: { on: '$users', has: 'many', label: 'projects' },
72
- },
73
- },
74
- rooms: {
75
- projectRoom: {
76
- presence: i.entity({
77
- cursor: i.json(),
78
- }),
79
- },
80
- },
81
- });
82
-
83
- export default _schema;
84
- `;
85
-
86
- const result = mergeSchema(oldFile, newFile);
87
-
88
- // Type annotations preserved
89
- expect(result).toContain("i.string<'todo' | 'in_progress' | 'done'>()");
90
- expect(result).toContain('i.number<1 | 2 | 3>()');
91
- expect(result).toContain('i.json<Label[]>()');
92
- expect(result).toContain('i.json<{ x: number; y: number }>()');
93
-
94
- // Import preserved
95
- expect(result).toContain("import { Label } from './types';");
96
- });
97
-
98
- test('preserves different import styles', () => {
99
- const oldFile = `
100
- import { i } from '@instantdb/core';
101
- import { Label } from './types';
102
- import { Tag as MyTag } from './types';
103
- import Priority from './Priority';
104
- import * as Models from './models';
105
- import type { Meta } from './meta';
106
-
107
- const _schema = i.schema({
108
- entities: {
109
- a: i.entity({ f: i.json<Label>() }),
110
- b: i.entity({ f: i.json<MyTag>() }),
111
- c: i.entity({ f: i.json<Priority>() }),
112
- d: i.entity({ f: i.json<Models.Status>() }),
113
- e: i.entity({ f: i.json<Meta>() }),
114
- },
115
- });
116
- `;
117
-
118
- const newFile = `
119
- import { i } from '@instantdb/core';
120
-
121
- const _schema = i.schema({
122
- entities: {
123
- a: i.entity({ f: i.json() }),
124
- b: i.entity({ f: i.json() }),
125
- c: i.entity({ f: i.json() }),
126
- d: i.entity({ f: i.json() }),
127
- e: i.entity({ f: i.json() }),
128
- },
129
- });
130
- `;
131
-
132
- const result = mergeSchema(oldFile, newFile);
133
-
134
- // All import styles preserved (named imports from same module are combined)
135
- expect(result).toContain('Label');
136
- expect(result).toContain('Tag as MyTag');
137
- expect(result).toContain("import Priority from './Priority';");
138
- expect(result).toContain("import * as Models from './models';");
139
- expect(result).toContain("import type { Meta } from './meta';");
140
-
141
- // Type annotations preserved
142
- expect(result).toContain('i.json<Label>()');
143
- expect(result).toContain('i.json<MyTag>()');
144
- expect(result).toContain('i.json<Priority>()');
145
- expect(result).toContain('i.json<Models.Status>()');
146
- expect(result).toContain('i.json<Meta>()');
147
- });
148
-
149
- test('handles entity additions and removals', () => {
150
- const oldFile = `
151
- import { i } from '@instantdb/core';
152
- import { Label } from './types';
153
-
154
- const _schema = i.schema({
155
- entities: {
156
- todos: i.entity({
157
- labels: i.json<Label[]>(),
158
- }),
159
- oldEntity: i.entity({
160
- data: i.json<{ removed: true }>(),
161
- }),
162
- },
163
- });
164
- `;
165
-
166
- const newFile = `
167
- import { i } from '@instantdb/core';
168
- import { Label } from './types';
169
-
170
- const _schema = i.schema({
171
- entities: {
172
- todos: i.entity({
173
- labels: i.json(),
174
- }),
175
- newEntity: i.entity({
176
- data: i.json(),
177
- }),
178
- },
179
- });
180
- `;
181
-
182
- const result = mergeSchema(oldFile, newFile);
183
-
184
- // Existing entity type preserved
185
- expect(result).toContain('i.json<Label[]>()');
186
-
187
- // Removed entity is gone
188
- expect(result).not.toContain('oldEntity');
189
-
190
- // New entity has no type annotation
191
- expect(result).toContain('newEntity: i.entity({');
192
- expect(result).not.toContain('i.json<{ removed: true }>()');
193
-
194
- // Import not duplicated (was already in newFile)
195
- const importMatches = result.match(/import { Label } from '\.\/types';/g);
196
- expect(importMatches?.length).toBe(1);
197
- });
@@ -1,2 +0,0 @@
1
- export function mergeSchema(oldFile: any, newFile: any): any;
2
- //# sourceMappingURL=mergeSchema.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mergeSchema.d.ts","sourceRoot":"","sources":["../../src/util/mergeSchema.js"],"names":[],"mappings":"AAkMA,6DAyKC"}