Skip to content

Commit 1903d13

Browse files
authored
Suite of cli and perms bugfixes (#627)
1 parent 289f80e commit 1903d13

File tree

9 files changed

+110
-17
lines changed

9 files changed

+110
-17
lines changed

client/packages/cli/index.js

+38-12
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ const potentialEnvs = {
4949
next: "NEXT_PUBLIC_INSTANT_APP_ID",
5050
svelte: "PUBLIC_INSTANT_APP_ID",
5151
vite: "VITE_INSTANT_APP_ID",
52+
expo: "EXPO_PUBLIC_INSTANT_APP_ID",
5253
};
5354

5455
async function detectEnvType({ pkgDir }) {
@@ -65,6 +66,9 @@ async function detectEnvType({ pkgDir }) {
6566
if (packageJSON.devDependencies?.vite) {
6667
return "vite";
6768
}
69+
if (packageJSON.dependencies?.expo) {
70+
return "expo";
71+
}
6872
return "catchall";
6973
}
7074

@@ -433,8 +437,8 @@ function printDotEnvInfo(envType, appId) {
433437
const otherEnvs = Object.values(rest);
434438
otherEnvs.sort();
435439
const otherEnvStr = otherEnvs.map((x) => " " + chalk.green(x)).join("\n");
436-
console.log(`Alternative names: \n${otherEnvStr}`);
437-
console.log(terminalLink("Dashboard", appDashUrl(appId)));
440+
console.log(`Alternative names: \n${otherEnvStr} \n`);
441+
console.log(terminalLink("Dashboard", appDashUrl(appId)) + '\n');
438442
}
439443

440444
async function handleEnvFile(pkgAndAuthInfo, appId) {
@@ -759,7 +763,7 @@ async function pullSchema(appId, { pkgDir, instantModuleName }) {
759763
"utf-8",
760764
);
761765

762-
console.log("Wrote schema to instant.schema.ts");
766+
console.log("Wrote schema to instant.schema.ts");
763767

764768
return { ok: true };
765769
}
@@ -777,7 +781,7 @@ async function pullPerms(appId, { pkgDir, instantModuleName }) {
777781

778782
if (await pathExists(join(pkgDir, "instant.perms.ts"))) {
779783
const ok = await promptOk(
780-
"This will ovwerwrite your local instant.perms file, OK to proceed?",
784+
"This will overwrite your local instant.perms file, OK to proceed?",
781785
);
782786

783787
if (!ok) return;
@@ -790,7 +794,7 @@ async function pullPerms(appId, { pkgDir, instantModuleName }) {
790794
"utf-8",
791795
);
792796

793-
console.log("Wrote permissions to instant.perms.ts");
797+
console.log("Wrote permissions to instant.perms.ts");
794798

795799
return true;
796800
}
@@ -1125,7 +1129,7 @@ async function pushPerms(appId) {
11251129

11261130
if (!prodPerms.ok) return;
11271131

1128-
const diffedStr = jsonDiff.diffString(prodPerms.data.perms, perms);
1132+
const diffedStr = jsonDiff.diffString(prodPerms.data.perms || {}, perms || {});
11291133
if (!diffedStr.length) {
11301134
console.log("No perms changes detected. Exiting.");
11311135
return;
@@ -1288,13 +1292,33 @@ async function promptOk(message) {
12881292
}).catch(() => false);
12891293
}
12901294

1295+
/**
1296+
* We need to do a bit of a hack of `@instantdb/react-native`.
1297+
*
1298+
* If a user writes import { i } from '@instantdb/react-native'
1299+
*
1300+
* We will fail to evaluate the file. This is because
1301+
* `@instantdb/react-native` brings in `react-native`, which
1302+
* does not run in a node context.
1303+
*
1304+
* To bypass this, we have a 'cli' module inside `react-native`, which
1305+
* has all the necessary imports
1306+
*/
1307+
function transformImports(code) {
1308+
return code.replace(
1309+
/"@instantdb\/react-native"/g,
1310+
'"@instantdb/react-native/dist/cli"'
1311+
);
1312+
}
1313+
12911314
async function readLocalPermsFile() {
12921315
const { config, sources } = await loadConfig({
12931316
sources: [
12941317
// load from `instant.perms.xx`
12951318
{
12961319
files: "instant.perms",
12971320
extensions: ["ts", "mts", "cts", "js", "mjs", "cjs", "json"],
1321+
transform: transformImports,
12981322
},
12991323
],
13001324
// if false, the only the first matched will be loaded
@@ -1326,6 +1350,7 @@ async function readLocalSchemaFile() {
13261350
{
13271351
files: "instant.schema",
13281352
extensions: ["ts", "mts", "cts", "js", "mjs", "cjs"],
1353+
transform: transformImports,
13291354
},
13301355
],
13311356
// if false, the only the first matched will be loaded
@@ -1519,9 +1544,10 @@ function appDashUrl(id) {
15191544
}
15201545

15211546
function generatePermsTypescriptFile(perms, instantModuleName) {
1522-
const rulesTxt = Object.keys(perms).length
1523-
? JSON.stringify(perms, null, 2)
1524-
: `
1547+
const rulesTxt =
1548+
perms && Object.keys(perms).length
1549+
? JSON.stringify(perms, null, 2)
1550+
: `
15251551
{
15261552
/**
15271553
* Welcome to Instant's permission system!
@@ -1539,12 +1565,12 @@ function generatePermsTypescriptFile(perms, instantModuleName) {
15391565
* bind: ["isOwner", "data.creator == auth.uid"],
15401566
* },
15411567
*/
1542-
};
1568+
}
15431569
`.trim();
15441570
return `
15451571
// Docs: https://www.instantdb.com/docs/permissions
15461572
1547-
import { type InstantRules } from "${instantModuleName ?? "@instantdb/core"}";
1573+
import type { InstantRules } from "${instantModuleName ?? "@instantdb/core"}";
15481574
15491575
const rules = ${rulesTxt} satisfies InstantRules;
15501576
@@ -1743,7 +1769,7 @@ type _AppSchema = typeof _schema;
17431769
interface AppSchema extends _AppSchema {}
17441770
const schema: AppSchema = _schema;
17451771
1746-
export { type AppSchema }
1772+
export type { AppSchema }
17471773
export default schema;
17481774
`;
17491775
}

client/packages/core/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,7 @@ type InstantRules = {
891891
create?: string;
892892
update?: string;
893893
delete?: string;
894+
$default?: string;
894895
};
895896
bind?: string[];
896897
};
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from '@instantdb/core';

client/pnpm-lock.yaml

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Docs: https://www.instantdb.com/docs/permissions
2+
3+
import type { InstantRules } from "@instantdb/react-native";
4+
5+
const rules = {
6+
/**
7+
* Welcome to Instant's permission system!
8+
* Right now your rules are empty. To start filling them in, check out the docs:
9+
* https://www.instantdb.com/docs/permissions
10+
*
11+
* Here's an example to give you a feel:
12+
* posts: {
13+
* allow: {
14+
* view: "true",
15+
* create: "isOwner",
16+
* update: "isOwner",
17+
* delete: "isOwner",
18+
* },
19+
* bind: ["isOwner", "data.creator == auth.uid"],
20+
* },
21+
*/
22+
$default: {
23+
allow: {
24+
$default: "true",
25+
},
26+
},
27+
} satisfies InstantRules;
28+
29+
export default rules;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Docs: https://www.instantdb.com/docs/schema
2+
3+
import { i } from "@instantdb/react-native";
4+
5+
const _schema = i.schema({
6+
// This section lets you define entities: think `posts`, `comments`, etc
7+
// Take a look at the docs to learn more:
8+
// https://www.instantdb.com/docs/schema#defining-entities
9+
entities: {
10+
$users: i.entity({
11+
email: i.string().unique().indexed(),
12+
}),
13+
},
14+
// You can define links here.
15+
// For example, if `posts` should have many `comments`.
16+
// More in the docs:
17+
// https://www.instantdb.com/docs/schema#defining-links
18+
links: {},
19+
// If you use presence, you can define a room schema here
20+
// https://www.instantdb.com/docs/schema#defining-rooms
21+
rooms: {},
22+
});
23+
24+
// This helps Typescript display nicer intellisense
25+
type _AppSchema = typeof _schema;
26+
interface AppSchema extends _AppSchema {}
27+
const schema: AppSchema = _schema;
28+
29+
export type { AppSchema };
30+
export default schema;

client/sandbox/react-native-expo/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
"tailwindcss": "3.3.2"
3333
},
3434
"devDependencies": {
35-
"@babel/core": "^7.20.0"
35+
"@babel/core": "^7.20.0",
36+
"instant-cli": "workspace:*"
3637
},
3738
"private": true
3839
}

client/www/components/dash/Perms.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ export const rulesSchema = {
163163
update: { type: 'string' },
164164
delete: { type: 'string' },
165165
view: { type: 'string' },
166+
$default: { type: 'string' },
166167
},
167168
additionalProperties: false,
168169
},

server/src/instant/model/rule.clj

+5-4
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@
7979

8080
(defn get-expr [rule etype action]
8181
(or
82-
(get-in rule [etype "allow" action])
83-
(get-in rule [etype "allow" "$default"])
84-
(get-in rule ["$default" "allow" action])
85-
(get-in rule ["$default" "allow" "$default"])))
82+
(get-in rule [etype "allow" action])
83+
(get-in rule [etype "allow" "$default"])
84+
(get-in rule ["$default" "allow" action])
85+
(get-in rule ["$default" "allow" "$default"])))
8686

8787
(defn extract [rule etype action]
8888
(when-let [expr (get-in rule [etype "allow" action])]
@@ -158,6 +158,7 @@
158158
[etype action]
159159
(when (and (not= "$users" etype)
160160
(not= "$files" etype)
161+
(not= "$default" etype)
161162
(string/starts-with? etype "$"))
162163
[[etype
163164
action

0 commit comments

Comments
 (0)