Skip to content

Commit ce54d9d

Browse files
committed
feat: generate mobx store
1 parent cb53a10 commit ce54d9d

File tree

9 files changed

+402
-188
lines changed

9 files changed

+402
-188
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ node_modules
22
*.js
33
*.d.ts
44
.vscode
5+
.merry-cache-*

action.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ export enum FlutterAction {
33
page = 'page',
44
model = 'model',
55
fastlane = 'fastlane',
6+
mobx = 'mobx'
67
}
78

89
export interface FlutterOptions {
910
name: string
1011
stateful?: boolean
1112
src?: string
13+
dist?: string
14+
tpl?: string
1215
}

index.ts

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Plugin } from '@merryjs/cli/lib/plugin'
22
import path from 'path'
33
import { FlutterAction, FlutterOptions } from './action'
44
import model from './model'
5+
import mobx from './mobx'
56

67
/**
78
* FlutterAnswers
@@ -13,24 +14,29 @@ export default (api: Plugin) => {
1314
.option('-n, --name [value]', 'name of your widget/model/page')
1415
.option('-s, --stateful', 'stateful widget')
1516
.option('-o, --src [value]', 'source path of quick type')
17+
.option('-d, --dist [value]', 'dist folder for widget')
18+
.option('-t, --tpl [value]', 'template for generate mobx store')
1619
.action(
1720
async (
1821
action: FlutterAction,
1922
options: FlutterOptions = {
2023
name: '',
2124
}
2225
) => {
23-
if (action === undefined) {
26+
const availableActions = Object.keys(FlutterAction).filter(
27+
f => !(parseInt(f, 10) >= 0)
28+
)
29+
if (action === undefined || !availableActions.includes(action)) {
2430
api.log(
25-
`action required, supported actions: ${Object.keys(FlutterAction)
26-
.filter(f => !(parseInt(f, 10) >= 0))
31+
`action required, supported actions: ${availableActions
2732
.map(f => f)
2833
.join(' ')}`
2934
)
3035
return
3136
}
3237
if (
3338
FlutterAction.fastlane !== action &&
39+
FlutterAction.mobx !== action &&
3440
(!options.name || typeof options.name === 'function')
3541
) {
3642
api.log('name option required')
@@ -57,13 +63,22 @@ export default (api: Plugin) => {
5763
)
5864
break
5965
case FlutterAction.model:
66+
options.dist = options.dist || 'models'
6067
await model(api, options)
6168
break
69+
case FlutterAction.mobx:
70+
options.dist = options.dist || 'stores'
71+
await mobx(api, options)
72+
break
6273
case FlutterAction.page:
6374
const page = options.stateful ? './page-stateful.hbs' : './page.hbs'
6475
await api.tmpl(
6576
page,
66-
path.join(api.conf.dist, 'pages', `{{snakecase name}}.dart`),
77+
path.join(
78+
api.conf.dist,
79+
options.dist || 'pages',
80+
`{{snakecase name}}.dart`
81+
),
6782
options
6883
)
6984
break
@@ -73,7 +88,11 @@ export default (api: Plugin) => {
7388
: './widget.hbs'
7489
await api.tmpl(
7590
tpl,
76-
path.join(api.conf.dist, 'widgets', `{{snakecase name}}.dart`),
91+
path.join(
92+
api.conf.dist,
93+
options.dist || 'pages',
94+
`{{snakecase name}}.dart`
95+
),
7796
options
7897
)
7998
break

mobx.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { Plugin } from '@merryjs/cli/lib/plugin'
2+
import path from 'path'
3+
import { FlutterOptions } from './action'
4+
import * as quickType from 'quicktype'
5+
import { generatePaths } from '@merryjs/swagger'
6+
import changeCase from 'change-case'
7+
import fg from 'fast-glob'
8+
export default async (api: Plugin, options: FlutterOptions) => {
9+
const cacheName = `.merry-cache-${Date.now()}`
10+
const cache = path.join(__dirname, cacheName)
11+
api.fs.emptyDirSync(cache)
12+
api.fs.ensureDirSync(cache)
13+
14+
if (!options.src) {
15+
api.log('--src required')
16+
return
17+
}
18+
19+
// fix tpl path
20+
if (options.tpl) {
21+
options.tpl = path.join(process.cwd(), options.tpl)
22+
} else {
23+
options.tpl = './store.tpl'
24+
}
25+
const result = await generatePaths(options.src, {
26+
definitionName: '{path}',
27+
})
28+
29+
for (const key in result) {
30+
if (result.hasOwnProperty(key)) {
31+
const element = result[key]
32+
const fileName = getFullPath(key)
33+
const out = `${api.conf.dist}/${options.dist}/${fileName}.dart`
34+
const tsFile = `${cache}/${options.dist}/${fileName}.ts`
35+
36+
// generate ts file
37+
await api.tmpl('./model.tpl', tsFile, {
38+
definitions: result[key],
39+
})
40+
41+
// generate dart files from typescript files
42+
const dartFile = `${cache}/${options.dist}/${fileName}.dart`
43+
await quickType.main({
44+
srcLang: 'typescript',
45+
src: [tsFile],
46+
lang: 'dart',
47+
out: dartFile,
48+
})
49+
50+
// read ts to dart file.
51+
const dartModel = api.fs
52+
.readFileSync(dartFile, 'utf-8')
53+
// replace import so we can import it in anywhere
54+
.replace("import 'dart:convert';", '')
55+
56+
await api.tmpl(options.tpl, out, {
57+
definitions: element,
58+
model: dartModel,
59+
fileName: getFullPath(key, true),
60+
})
61+
}
62+
}
63+
api.fs.remove(cache)
64+
}
65+
66+
/**
67+
* get full path by key
68+
* @param key
69+
*/
70+
function getFullPath(key: string, filename: boolean = false) {
71+
const paths = key.startsWith('/') ? key.substr(1).split('/') : key.split('/')
72+
let folder = ''
73+
let p = ''
74+
if (paths.length > 1) {
75+
folder = paths[0]
76+
p = paths.filter((_, index) => index !== 0).join('/')
77+
} else {
78+
p = key
79+
}
80+
if (filename) {
81+
return changeCase.snakeCase(p)
82+
}
83+
const fullPath =
84+
(folder ? changeCase.snakeCase(folder) + '/' : '') + changeCase.snakeCase(p)
85+
return fullPath
86+
}

model.tpl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
///
2+
/// ********************************************************
3+
///
4+
/// Auto generated by `merry flutter mobx`
5+
///
6+
/// ********************************************************
7+
///
8+
9+
{{#each definitions}}
10+
{{#this}}
11+
{{#if responses}}
12+
13+
/// {{summary}}
14+
{{{responses}}}
15+
{{/if}}
16+
17+
{{#if parameters}}
18+
19+
/// {{summary}}
20+
{{{parameters}}}
21+
{{/if}}
22+
23+
24+
{{/this}}
25+
{{/each}}

model.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ export default async (api: Plugin, options: FlutterOptions) => {
1717
api.log('src required')
1818
return
1919
}
20-
api.fs.ensureDirSync(`${api.conf.dist}/models`)
20+
api.fs.ensureDirSync(`${api.conf.dist}/${options.dist}`)
2121
try {
22-
const out = `${api.conf.dist}/models/${fileName}`
22+
const out = `${api.conf.dist}/${options.dist}/${fileName}`
2323
await quickType.main({
2424
out: out,
2525
lang: 'dart',

0 commit comments

Comments
 (0)