fireschema
fireschema copied to clipboard
ts-morph raises an exception when running the sample schema
Thanks for the nice tool! When I run the sample schema, An exception is being thrown in the visitor that handles the AST. I tried to investigate, but I couldn't isolate if it was a setup problem or if it was originally not working. If you know anything about it, please let me know.
Error is as follows:
$ npx fireschema schema.ts
For some reason the top parent was not a source file.
$ ./node_modules/fireschema/dist/bin/cli.js schema.ts
/home/katsuya/fireschema_test/node_modules/ts-morph/dist/ts-morph.js:19177
throw new common.errors.NotImplementedError("For some reason the top parent was not a source file.");
^
NotImplementedError: For some reason the top parent was not a source file.
at getSourceFileFromNode (/home/katsuya/fireschema_test/node_modules/ts-morph/dist/ts-morph.js:19177:19)
at getSourceFileNode (/home/katsuya/fireschema_test/node_modules/ts-morph/dist/ts-morph.js:19166:76)
at Object.createWrappedNode (/home/katsuya/fireschema_test/node_modules/ts-morph/dist/ts-morph.js:19163:76)
at visitNode (/home/katsuya/fireschema_test/node_modules/fireschema/dist/_transformer/main.js:65:35)
at visitNodeAndChildren (/home/katsuya/fireschema_test/node_modules/fireschema/dist/_transformer/main.js:36:57)
at /home/katsuya/fireschema_test/node_modules/fireschema/dist/_transformer/main.js:36:98
at visitNode (/home/katsuya/fireschema_test/node_modules/typescript/lib/typescript.js:85158:23)
at Object.visitEachChild (/home/katsuya/fireschema_test/node_modules/typescript/lib/typescript.js:85538:59)
at visitNodeAndChildren (/home/katsuya/fireschema_test/node_modules/fireschema/dist/_transformer/main.js:36:42)
at /home/katsuya/fireschema_test/node_modules/fireschema/dist/_transformer/main.js:36:98
[1] 3497853 exit 1 ./node_modules/fireschema/dist/bin/cli.js schema.ts
It occurs in the following steps:
$ mkdir fireschema_test
$ cd fireschema_test
$ cat <<"EOF" > package.json
{
"name": "fireschema_test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@google-cloud/pubsub": "^2.17.0",
"@tsconfig/recommended": "^1.0.1",
"firebase": "^8.3.11",
"firebase-admin": "^9.11.1",
"firebase-functions": "^3.15.5",
"fireschema": "^4.0.4",
"react": "^17.0.2",
"ts-node": "^10.2.1",
"ttypescript": "^1.5.12",
"typescript": "^4.4.2"
}
}
EOF
$ cat <<"EOF" > tsconfig.json
{
"extends": "@tsconfig/recommended/tsconfig.json",
"compilerOptions": {
"plugins": [
{
"transform": "fireschema/transformer"
}
]
},
"include": ["*.ts"]
}
EOF
$ node -v
v14.17.4
$ npm -v
7.21.1
$ npx fireschema schema.ts
For some reason the top parent was not a source file.
The sample schema is as follows:
import { Merge } from 'type-fest'
import {
$allow,
$collectionGroups,
$collectionSchema,
$docLabel,
$functions,
$or,
$schema,
createFirestoreSchema,
FTypes,
} from 'fireschema'
// user
export type User = {
name: string
displayName: string | null
age: number
timestamp: FTypes.Timestamp
options: { a: boolean } | undefined
}
export type UserDecoded = Merge<User, { timestamp: Date }>
const UserSchema = $collectionSchema<User, UserDecoded>()({
decoder: (data) => ({
...data,
timestamp: data.timestamp.toDate(),
}),
})
// post
type PostA = {
type: 'a'
tags: { id: number; name: string }[]
text: string
}
type PostB = {
type: 'b'
tags: { id: number; name: string }[]
texts: string[]
}
const PostSchema = $collectionSchema<PostA | PostB>()({
selectors: (q) => ({
byTag: (tag: string) => q.where('tags', 'array-contains', tag),
}),
})
export const firestoreSchema = createFirestoreSchema({
[$functions]: {
// whether /admins/<uid> exists
['isAdmin()']: `
return exists(/databases/$(database)/documents/admins/$(request.auth.uid));
`,
// whether uid matches
['matchesUser(uid)']: `
return request.auth.uid == uid;
`,
},
[$collectionGroups]: {
posts: {
[$docLabel]: 'postId',
[$schema]: PostSchema,
[$allow]: {
read: true,
},
},
},
// /users/{uid}
users: {
[$docLabel]: 'uid', // {uid}
[$schema]: UserSchema, // collectionSchema
[$allow]: {
// access control
read: true, // all user
write: $or(['matchesUser(uid)', 'isAdmin()']), // only users matching {uid} or admins
},
// /users/{uid}/posts/{postId}
posts: {
[$docLabel]: 'postId',
[$schema]: PostSchema,
[$allow]: {
read: true,
write: 'matchesUser(uid)',
},
},
},
})
Thanks for the report!
I tried changing TypeScript version to 4.2, and it worked fine.
Compiling with custom transformer often causes errors due to version compatibility between typescript and ts-morph, so we will not use custom transformer in v5 or later.
https://github.com/yarnaimo/fireschema/tree/v5
You can try it with npm i -S fireschema@next
.