Skip to content

Commit

Permalink
add better example scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
timsuchanek committed Aug 29, 2019
1 parent 5ee7fe3 commit 9b67547
Show file tree
Hide file tree
Showing 7 changed files with 252 additions and 11 deletions.
9 changes: 2 additions & 7 deletions cli/introspection/src/prompt/screens/Step41Introspection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ const AnySpinner = Spinner as any
const Step41Introspection: React.FC = () => {
const router = useContext(RouterContext)
const [state] = useInitState()
const { connector, introspect } = useConnector()
const [tableCount, setTableCount] = useState(0)

const sqliteHref = state.useBlank ? 'tool-selection' : 'download-example'
const { connector, introspect, selectedDatabaseMeta } = useConnector()

const { dbCredentials } = state

Expand All @@ -29,8 +26,6 @@ const Step41Introspection: React.FC = () => {
async function run() {
if (connector) {
const db = dbCredentials!.type === DatabaseType.postgres ? dbCredentials!.schema : dbCredentials!.database
const result = await connector.connector.getMetadata(db!)
setTableCount(result.countOfTables)
await introspect(db!)
router.setRoute('tool-selection')
} else {
Expand All @@ -44,7 +39,7 @@ const Step41Introspection: React.FC = () => {
<Box flexDirection="column">
<Box>
<AnySpinner /> Introspecting {dbType} {schemaWord} <Color bold>{dbCredentials.schema || ''}</Color> with{' '}
<Color bold>{tableCount || 0}</Color> tables.
<Color bold>{selectedDatabaseMeta ? selectedDatabaseMeta.countOfTables : 0}</Color> tables.
</Box>
</Box>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { credentialsToUri } from '../../convertCredentials'
import { DatabaseType } from 'prisma-datamodel'
import { ConnectorType } from '@prisma/photon/dist/isdlToDatamodel2'
import { useConnector } from '../components/useConnector'
import { minimalScript } from '../utils/templates/script'
import { minimalScript, exampleScript } from '../utils/templates/script'
import { ErrorBox } from '../components/ErrorBox'
import { photonDefaultConfig } from '../utils/defaults'

Expand Down Expand Up @@ -81,14 +81,17 @@ const Step60DownloadExample: React.FC = () => {
await writeFile(schemaPath, newSchema)

// replace example if it's based on introspection
// TODO: Use more sophisticated example as specified here https://prisma-specs.netlify.com/cli/init/introspection-results/
if (introspectionResult) {
const pathToScript =
state.selectedLanguage === 'javascript'
? path.join(state.outputDir, 'script.js')
: path.join(state.outputDir, 'script.ts')

const newScript = minimalScript({ typescript: state.selectedLanguage === 'typescript' })
// TODO: Use more sophisticated example as specified here https://prisma-specs.netlify.com/cli/init/introspection-results/
const newScript = await exampleScript({
typescript: state.selectedLanguage === 'typescript',
datamodel: introspectionResult,
})
if (await exists(pathToScript)) {
await writeFile(pathToScript, newScript)
}
Expand Down
2 changes: 1 addition & 1 deletion cli/introspection/src/prompt/screens/Step61Success.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const Step61Success: React.FC = () => {

return (
<Box flexDirection="column">
<Box marginLeft={2} flexDirection="column" textWrap="wrap">
<Box flexDirection="column" textWrap="wrap">
{directoryCreated && (
<Color green>
<Color bgKeyword="green" white>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { exampleScript } from '../script'

test('exampleScript', async () => {
const schema = `datasource db {
provider = "sqlite"
url = "file:dev.db"
default = true
}
generator photon {
provider = "photonjs"
output = "@generated/photon"
transpile = false
}
model User {
id String @id @default(uuid())
username String
posts Post[]
}
model Post {
id String @id @default(uuid())
data String
user User?
}`

expect(await exampleScript({ datamodel: schema, typescript: true })).toMatchInlineSnapshot(`
"/**
*
* This code was auto-generated based on the introspection result.
* Consider it a playground to explore the Photon API.
* Feel free to change it as much as you like or delete it altogether.
*
* The model \`User\` was randomly selected to demonstrate some API calls.
*
* Tip: Use the auto-completion of your editor to explore available API operations.
*
*/
import Photon from '@generated/photon'
const photon = new Photon()
async function main() {
// Tip: Explore some arguments to \`findMany\`
const allUsers = await photon.users.findMany()
console.log(\`Retrieved all published users: \`, allUsers)
// Comment out the lines below to create a new User
// ATTENTION: This code creates a new record in your database
// const newUser = await photon.users.create({
// data: {
// // add some values here
// },
// })
// console.log(\`Created a new User: \`, newUser)
}
main()
.catch(e => console.error(e))
.finally(async () => {
await photon.disconnect()
})"
`)

expect(await exampleScript({ datamodel: schema, typescript: false })).toMatchInlineSnapshot(`
"/**
*
* This code was auto-generated based on the introspection result.
* Consider it a playground to explore the Photon API.
* Feel free to change it as much as you like or delete it altogether.
*
* The model \`User\` was randomly selected to demonstrate some API calls.
*
* Tip: Use the auto-completion of your editor to explore available API operations.
*
*/
const Photon = require('@generated/photon')
const photon = new Photon()
async function main() {
// Tip: Explore some arguments to \`findMany\`
const allUsers = await photon.users.findMany()
console.log(\`Retrieved all published users: \`, allUsers)
// Comment out the lines below to create a new User
// ATTENTION: This code creates a new record in your database
// const newUser = await photon.users.create({
// data: {
// // add some values here
// },
// })
// console.log(\`Created a new User: \`, newUser)
}
main()
.catch(e => console.error(e))
.finally(async () => {
await photon.disconnect()
})"
`)
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { sortModels } from '../sortModels'
import { DMMF } from '@prisma/photon/dist/runtime/dmmf-types'

test('sortModels', () => {
const models: DMMF.Model[] = [
{
name: 'Car',
fields: [],
isEmbedded: false,
dbName: null,
},
{
name: 'Bike',
fields: [],
isEmbedded: false,
dbName: null,
},
{
name: 'Post',
fields: [],
isEmbedded: false,
dbName: null,
},
{
name: 'User',
fields: [],
isEmbedded: false,
dbName: null,
},
]

expect(sortModels(models)).toMatchInlineSnapshot(`
Array [
Object {
"dbName": null,
"fields": Array [],
"isEmbedded": false,
"name": "User",
},
Object {
"dbName": null,
"fields": Array [],
"isEmbedded": false,
"name": "Post",
},
Object {
"dbName": null,
"fields": Array [],
"isEmbedded": false,
"name": "Bike",
},
Object {
"dbName": null,
"fields": Array [],
"isEmbedded": false,
"name": "Car",
},
]
`)
})
57 changes: 57 additions & 0 deletions cli/introspection/src/prompt/utils/templates/script.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import { getDMMF } from '@prisma/photon'
import { sortModels } from './sortModels'
import { capitalize } from '@prisma/photon/dist/runtime/utils/common'

export const minimalScript = ({ typescript }: { typescript: boolean }) => `/**
*
* This code is a start point for you to explore the Photon API.
Expand All @@ -23,3 +27,56 @@ main()

const getImportStatement = es6 =>
es6 ? `import Photon from '@generated/photon'` : `const Photon = require('@generated/photon')`

export const exampleScript = async ({ typescript, datamodel }: { typescript: boolean; datamodel: string }) => {
const dmmf = await getDMMF({ datamodel })
const theModel = sortModels(dmmf.datamodel.models)[0]

if (!theModel) {
throw new Error(`Schema must contain at least one model`)
}

const mapping = dmmf.mappings.find(mapping => mapping.model === theModel.name)

if (!mapping) {
throw new Error(`Could not find mapping for model ${theModel.name}`)
}

const { plural } = mapping

return `/**
*
* This code was auto-generated based on the introspection result.
* Consider it a playground to explore the Photon API.
* Feel free to change it as much as you like or delete it altogether.
*
* The model \`${theModel.name}\` was randomly selected to demonstrate some API calls.
*
* Tip: Use the auto-completion of your editor to explore available API operations.
*
*/
${getImportStatement(typescript)}
const photon = new Photon()
async function main() {
// Tip: Explore some arguments to \`findMany\`
const all${capitalize(plural)} = await photon.${plural}.findMany()
console.log(\`Retrieved all published ${plural}: \`, all${capitalize(plural)})
// Comment out the lines below to create a new ${theModel.name}
// ATTENTION: This code creates a new record in your database
// const new${theModel.name} = await photon.${plural}.create({
// data: {
// // add some values here
// },
// })
// console.log(\`Created a new ${theModel.name}: \`, new${theModel.name})
}
main()
.catch(e => console.error(e))
.finally(async () => {
await photon.disconnect()
})`
}
23 changes: 23 additions & 0 deletions cli/introspection/src/prompt/utils/templates/sortModels.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { DMMF } from '@prisma/photon/dist/runtime/dmmf-types'

const modelOrder = ['User', 'Player', 'Customer', 'Product', 'Order', 'Article', 'Post', 'Message']

export function sortModels(models: DMMF.Model[]): DMMF.Model[] {
return models.sort((a, b) => {
if (modelOrder.includes(a.name) && modelOrder.includes(b.name)) {
const aIndex = modelOrder.indexOf(a.name)
const bIndex = modelOrder.indexOf(b.name)
return aIndex < bIndex ? -1 : 1
}

if (modelOrder.includes(a.name)) {
return -1
}

if (modelOrder.includes(b.name)) {
return 1
}

return a.name < b.name ? -1 : 1
})
}

0 comments on commit 9b67547

Please sign in to comment.