sptc 0.0.20 → 0.0.21

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.
Files changed (33) hide show
  1. package/README.md +6 -0
  2. package/bin/sptcd-web.js +27 -0
  3. package/dist/sptc-web-demo/build/index.js +24 -0
  4. package/dist/sptc-web-demo/build/lib.js +116 -0
  5. package/dist/sptc-web-demo/build/postcss.config.js +31 -0
  6. package/dist/sptc-web-demo/build/sptc.inject.js +73 -0
  7. package/dist/sptc-web-demo/build/webpack.lib.js +242 -0
  8. package/dist/sptc-web-demo/package.json +48 -0
  9. package/dist/sptc-web-demo/server/app/controllers/assets.s +31 -0
  10. package/dist/sptc-web-demo/server/app/controllers/data.s +39 -0
  11. package/dist/sptc-web-demo/server/app/controllers/error.s +10 -0
  12. package/dist/sptc-web-demo/server/app/controllers/ssr.s +6 -0
  13. package/dist/sptc-web-demo/server/app/library/request.s +44 -0
  14. package/dist/sptc-web-demo/server/app/library/response.s +12 -0
  15. package/dist/sptc-web-demo/server/app/library/sqlite.s +91 -0
  16. package/dist/sptc-web-demo/server/app/library/ssr.s +142 -0
  17. package/dist/sptc-web-demo/server/app/library/utils.s +108 -0
  18. package/dist/sptc-web-demo/server/app/models/Message.s +62 -0
  19. package/dist/sptc-web-demo/server/app/setting.s +9 -0
  20. package/dist/sptc-web-demo/server/index.s +24 -0
  21. package/dist/sptc-web-demo/server/public/externals/js/react-dom.production.min.js +244 -0
  22. package/dist/sptc-web-demo/server/public/externals/js/react.production.min.js +33 -0
  23. package/dist/sptc-web-demo/server/public/externals/js/vconsole.js +10 -0
  24. package/dist/sptc-web-demo/src/app/index.jsx +131 -0
  25. package/dist/sptc-web-demo/src/app/index.scss +108 -0
  26. package/dist/sptc-web-demo/src/components/AnimateView/index.jsx +415 -0
  27. package/dist/sptc-web-demo/src/components/AnimateView/index.scss +167 -0
  28. package/dist/sptc-web-demo/src/components/UseComponent/index.jsx +93 -0
  29. package/dist/sptc-web-demo/src/index.jsx +47 -0
  30. package/dist/sptc-web-demo/src/ssrInit.js +20 -0
  31. package/dist/sptc-web-demo/src/utils/base.js +28 -0
  32. package/dist/sptc-web-demo/src/utils/fetch.js +56 -0
  33. package/package.json +6 -4
package/README.md CHANGED
@@ -73,3 +73,9 @@ module.exports={
73
73
 
74
74
 
75
75
  ```
76
+
77
+
78
+ ### sptcd-create-project
79
+ ```
80
+ Run this command `sptcd-create-project` to create a sample web project that supports react server-side rendering. The sample project already contains commonly used codes, such as reading and writing databases, multi-page data interaction, routing, etc., so it is very suitable for full-stack projects that need to get started quickly.
81
+ ```
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env node
2
+
3
+ const {Command}=require('commander')
4
+ const version=require('../package.json').version
5
+ const program=new Command()
6
+ .name(`create web project`)
7
+ .description(`create web project`)
8
+ .version(version)
9
+ .requiredOption('-d, --dir <string>', 'Specify the project directory.', './sptc-web-demo')
10
+ .action(({
11
+ dir,
12
+ })=>{
13
+ const fs=require('fs-extra')
14
+ try{
15
+ fs.copySync(__dirname+'/../dist/sptc-web-demo', dir)
16
+ console.log()
17
+ console.log('New project created in `'+dir+'` !')
18
+ console.log('The following steps are necessary for developing:')
19
+ console.log('1. enter the project directory ', dir)
20
+ console.log('2. run `npm i` to install the requirements')
21
+ console.log('3. run `npm run dev` to start the demo')
22
+ console.log()
23
+ }catch(e) {
24
+ console.error(e)
25
+ }
26
+ })
27
+ .parse()
@@ -0,0 +1,24 @@
1
+ const {getRuntimeArgv, checkEnv, run}=require(__dirname+'/lib')
2
+ checkEnv()
3
+ const {IS_DEV, IS_BUILD, IS_SERVE, NPM_ARGV_ORIGINAL}=getRuntimeArgv()
4
+
5
+ process.env.NODE_ENV=IS_DEV? 'development': 'production'
6
+ const {webpackDev, webpackBuild}=require(__dirname+'/webpack.lib')
7
+
8
+ const nk='NODE_OPTIONS', nv='--openssl-legacy-provider'
9
+ if(+process.version.match(/^v(\d+)/)[1]>16 && process.env[nk]!==nv) {
10
+ run('cross-env', [nk+'='+nv, 'npm', ...NPM_ARGV_ORIGINAL])
11
+ }else{
12
+ const open=require('open')
13
+ if(IS_DEV) {
14
+ run('cross-env', 'sptcd_environ=dev sptcd -rindex.s -wserver'.split(' '))
15
+ webpackDev()
16
+ open('http://127.0.0.1:3000')
17
+ }else if(IS_BUILD) {
18
+ webpackBuild()
19
+ }else if(IS_SERVE) {
20
+ run('cross-env', 'sptcd_environ=beta sptcd -rindex.s -wserver -n2 -s'.split(' '))
21
+ console.log('-- The HTTP service is started with the address 127.0.0.1:9090 --')
22
+ open('http://127.0.0.1:9090')
23
+ }
24
+ }
@@ -0,0 +1,116 @@
1
+ const APP_PATH=__dirname+'/..'
2
+ const pkg=require(APP_PATH+'/package.json')
3
+ const chalk=require('chalk')
4
+ const fs=require('fs')
5
+
6
+ const RUNTIME_RND_STR=Date.now().toString(36)
7
+ function getRuntimeArgv() {
8
+ const p=process.argv[2]
9
+ const IS_DEV=p==='dev'
10
+ const IS_BUILD=p==='build'
11
+ const IS_SERVE=p==='serve'
12
+ const t=JSON.parse(process.env.npm_config_argv).original
13
+ let e={}
14
+ for(let s of t) {
15
+ s.replace(/^--(.+?)=(.+)/, (_, k, v)=>{
16
+ e[k]=v
17
+ })
18
+ }
19
+ return {
20
+ NPM_ARGV: e,
21
+ NPM_ARGV_ORIGINAL: t,
22
+ IS_DEV,
23
+ IS_BUILD,
24
+ IS_SERVE,
25
+ RND: RUNTIME_RND_STR,
26
+ }
27
+ }
28
+
29
+ function satisfiesVersion(target_v, custom_v) {
30
+ function _cmp(v1, v2, g=3) {
31
+ v1=v1.split('.').slice(0, g)
32
+ v2=v2.split('.').slice(0, g)
33
+ for(;v1.length<3;) v1.push(0)
34
+ for(;v2.length<3;) v2.push(0)
35
+ for(let i=0; i<3; i++) {
36
+ const _v1=parseInt(v1[i]) || 0, _v2=parseInt(v2[i]) || 0
37
+ if(_v1>_v2) return 1
38
+ if(_v1<_v2) return -1
39
+ }
40
+ return 0
41
+ }
42
+ if(target_v==='*' || target_v===custom_v) return true
43
+ let s=false
44
+ target_v.replace(/^(>=|>|\^|~)\s*(\S+)/, (_, x, t_ver)=>{
45
+ if(x==='>=') {
46
+ s=_cmp(custom_v, t_ver)>=0
47
+ }else if(x==='>') {
48
+ s=_cmp(custom_v, t_ver)>0
49
+ }else if(x==='<=') {
50
+ s=_cmp(custom_v, t_ver)<=0
51
+ }else if(x==='<') {
52
+ s=_cmp(custom_v, t_ver)<0
53
+ }else if(x==='^' || x==='~') {
54
+ s=_cmp(custom_v, t_ver)>=0
55
+ if(x==='^') {
56
+ s=s && _cmp(custom_v, t_ver.replace(/^\d+/, _=>+_+1), 1)<=0
57
+ }else{
58
+ s=s && _cmp(custom_v, t_ver.replace(/(^.+?\.)(\d+)/, (_, a, b)=>a+(+b+1)), 2)<=0
59
+ }
60
+ }
61
+ })
62
+ return s
63
+ }
64
+
65
+ function checkEnv() {
66
+ if(!satisfiesVersion(pkg.engines.node, process.version.replace(/^v/, ''))) {
67
+ console.log([
68
+ chalk.red('Node version not met :('),
69
+ chalk.yellow(`You are using Node ${process.version}. Node ${pkg.engines.node} is required.`),
70
+ ].join('\n'))
71
+ process.exit(1)
72
+ }
73
+
74
+ const unmatched=[]
75
+ const t=Object.assign({}, pkg.dependencies, pkg.devDependencies)
76
+ for(let n in t) {
77
+ let custom_v=''
78
+ try{
79
+ custom_v=require(APP_PATH+'/node_modules/'+n+'/package.json').version
80
+ }catch(e) {}
81
+ if(satisfiesVersion(t[n], custom_v)<=0) {
82
+ unmatched.push([n, t[n], custom_v])
83
+ }
84
+ }
85
+ if(unmatched.length) {
86
+ console.log(chalk.red(`The following packages should be installed:`))
87
+ for(let [name, tv, cv] of unmatched) {
88
+ console.log(`${name} required: ${tv} | current: ${cv || 'uninstalled'}`)
89
+ }
90
+ process.exit()
91
+ }
92
+ }
93
+
94
+ function getPostCssPlugins() {
95
+ return require("postcss-load-config").sync({}, __dirname+'/postcss.config.js')
96
+ }
97
+
98
+ function requireNodeModuleFile(fn) {
99
+ return require(APP_PATH+'/node_modules/'+fn)
100
+ }
101
+
102
+ function run(exe, argv) {
103
+ const p=require('child_process').spawn(
104
+ require('os').platform()==='win32'? exe+'.cmd': exe, argv)
105
+ p.stdout.on('data', b=>process.stdout.write(b))
106
+ p.stderr.on('data', b=>process.stderr.write(b))
107
+ }
108
+
109
+ module.exports={
110
+ APP_PATH,
111
+ getRuntimeArgv,
112
+ checkEnv,
113
+ getPostCssPlugins,
114
+ requireNodeModuleFile,
115
+ run,
116
+ }
@@ -0,0 +1,31 @@
1
+ var autoprefixer = require('autoprefixer')
2
+
3
+ module.exports = {
4
+ plugins: [
5
+ autoprefixer({
6
+ overrideBrowserslist: [
7
+ 'Android >= 4.0',
8
+ 'iOS >= 6',
9
+ 'last 5 QQAndroid versions',
10
+ 'last 5 UCAndroid versions'
11
+ ],
12
+ cascade: true
13
+ }),
14
+ require("postcss-px-to-viewport")({
15
+ unitToConvert: 'px',
16
+ viewportWidth: 1875,
17
+ unitPrecision: 5,
18
+ propList: ['*'],
19
+ viewportUnit: 'rem',
20
+ fontViewportUnit: 'rem',
21
+ selectorBlackList: [],
22
+ minPixelValue: 1,
23
+ mediaQuery: false,
24
+ replace: true,
25
+ include: 'src/**',
26
+ landscape: false,
27
+ landscapeUnit: 'rem',
28
+ landscapeWidth: 568
29
+ })
30
+ ]
31
+ };
@@ -0,0 +1,73 @@
1
+ const argv=require('./lib').getRuntimeArgv()
2
+
3
+ function is_server(ctx) {
4
+ return (ctx.webpackLoaderThis.target + '').indexOf('node') > -1;
5
+ }
6
+
7
+ const A={
8
+ EXTENDS: (ctx) => ({
9
+ ...argv,
10
+ IS_NODE_TARGET: is_server(ctx),
11
+ }),
12
+ TPLS: [
13
+ /\.jsx?$/, ctx=>{
14
+ let {str, fn}=ctx
15
+ let appends={}
16
+ if (str.match(/<&[*=]/)) {
17
+ str=str.replace(/<(\/)?&([*=&])([^\s>]+)/g, (_, b, a, p) => {
18
+ appends[`import UseComponent from '@/components/UseComponent'`]=1
19
+ if(a==='*') {
20
+ if(b) return `</UseComponent`
21
+ return `<UseComponent key={"pathto_component_${p}"} UseComponentGetter={_=>import("${p}")}`
22
+ }else if(a==='=') {
23
+ appends[`import UseComponent from '@/components/UseComponent'`]=1
24
+ if(b) return `</UseComponent`
25
+ return `<UseComponent key={"pathto_component_${p}"} UseComponentSync={true} UseComponentGetter={_=>require("${p}")}`
26
+ } else if(a==='&') {
27
+ const name = `Comp_pathto_component_${p.replace(/[^a-z\d_]+/g, '_')}`
28
+ appends[`import ${name} from '${p}'`]=1
29
+ if(b) return `</${name}`
30
+ return `<${name}`
31
+ }
32
+ })
33
+ str=Object.keys(appends).join('\n')+'\n'+str
34
+ }
35
+ return str;
36
+ },
37
+
38
+ /\.jsx?$/, ctx=>{
39
+ let adds={}
40
+ let str=ctx.str.replace(/\*IMG\((['"])(.+?)\1\)/g, (_, a, pth)=>{
41
+ let e='IMG_'+pth.replace(/[^a-z\d_]+/g, '_')
42
+ adds[e]=pth
43
+ return e
44
+ })
45
+ for(let e in adds) {
46
+ str=`import ${e} from '${adds[e]}'\n`+str
47
+ }
48
+ return str
49
+ },
50
+
51
+ /\.jsx?/, ctx=>{
52
+ const {str, fn}=ctx
53
+ if(fn.match(/ssrInit.js/)) return str
54
+ if(!is_server(ctx)) return str
55
+ return `
56
+ import e from '@/ssrInit'
57
+ const {window, document, navigator,location}=e
58
+ `+str
59
+ },
60
+
61
+ /\.(scss|jsx?)/, ctx=>{
62
+ const {str, fn}=ctx
63
+ const path=require('path')
64
+ const src=path.resolve(__dirname+'/src')
65
+ const ffn=path.resolve(fn).substr(src.length).replace(/\.[a-z\d]+$/, '')
66
+ let t=ffn.replace(/[\/\\]+([^/\\]+)\.[^/\\]+$/, '').replace(/[^a-z\d_-]/ig, '_')
67
+ return str.replace(/\b__view_scope\b/g, 'V_'+argv.RND+'_'+t)
68
+ },
69
+
70
+ ],
71
+ };
72
+
73
+ module.exports=A
@@ -0,0 +1,242 @@
1
+ const {
2
+ APP_PATH,
3
+ getRuntimeArgv,
4
+ getPostCssPlugins,
5
+ requireNodeModuleFile,
6
+ }=require(__dirname+'/lib')
7
+ const craco=require('@craco/craco')
8
+ const webpack=require('webpack')
9
+ const Webpackbar=require('webpackbar')
10
+ const chalk=require('chalk')
11
+ const fs=require('fs')
12
+ const MiniCssExtractPlugin=require('mini-css-extract-plugin')
13
+ const fs_extra=require('fs-extra')
14
+ const {NPM_ARGV}=getRuntimeArgv()
15
+ const path=require('path')
16
+ const createWebpackBase=requireNodeModuleFile('react-scripts/config/webpack.config')
17
+ function createWebpackConfig({isServer=false, env='development'}) {
18
+ const IS_DEV=env==='development'
19
+ const webpackConfig={
20
+ target: !isServer? 'web': 'node',
21
+ name: !isServer? 'client': 'server',
22
+ mode: IS_DEV? 'development': 'production',
23
+ optimization: {
24
+ runtimeChunk: false,
25
+ splitChunks: false,
26
+ },
27
+ }
28
+ const base=createWebpackBase(env)
29
+ base.plugins.push(
30
+ new Webpackbar({
31
+ name: webpackConfig.name,
32
+ basic: false,
33
+ }),
34
+ )
35
+
36
+ craco.removePlugins(base, x=>[
37
+ 'HtmlWebpackPlugin',
38
+ 'ManifestPlugin',
39
+ 'ESLintWebpackPlugin',
40
+ ].includes(x.constructor.name))
41
+
42
+ craco.removeLoaders(base, craco.loaderByName('style-loader'))
43
+ craco.getLoaders(base, craco.loaderByName('postcss-loader')).matches.map(e=>{
44
+ const _fn=e.loader.options.plugins
45
+ e.loader.options.plugins=_=>[..._fn(), ...getPostCssPlugins().plugins]
46
+ })
47
+ craco.getLoaders(base, craco.loaderByName('babel-loader')).matches.map(e=>{
48
+ e.loader.options.plugins=[]
49
+ })
50
+ base.module.rules.push({
51
+ test: /\.([tj]sx?|scss)/,
52
+ exclude: /node_modules/,
53
+ options: {
54
+ file: __dirname+'/sptc.inject.js',
55
+ },
56
+ loader: 'sptc/dist/webpack.loader.js',
57
+ })
58
+
59
+ if(isServer) {
60
+ craco.removePlugins(base, x=>[
61
+ 'MiniCssExtractPlugin',
62
+ 'InterpolateHtmlPlugin',
63
+ 'InlineChunkHtmlPlugin',
64
+ 'WebpackManifestPlugin',
65
+ 'ReactRefreshPlugin',
66
+ 'ForkTsCheckerWebpackPlugin',
67
+ 'WatchMissingNodeModulesPlugin',
68
+ 'ModuleNotFoundPlugin',
69
+ 'ModuleScopePlugin',
70
+ ].includes(x.constructor.name))
71
+
72
+ craco.removeLoaders(base, craco.loaderByName('mini-css-extract-plugin'))
73
+ base.module.rules[1].oneOf.map(x=>{
74
+ if(x.test && ('.css'.match(x.test) || '.scss'.match(x.test))) {
75
+ x.use='null-loader'
76
+ }
77
+ })
78
+
79
+ base.resolve.plugins=[]
80
+ base.output.filename='server/index.js'
81
+ base.entry=APP_PATH+'/src/index.jsx';
82
+ base.output.chunkFilename='server/chunk.[contenthash].js';
83
+ base.output.libraryTarget='commonjs2';
84
+ }else{
85
+ if(IS_DEV) {
86
+ craco.removePlugins(base, craco.pluginByName('HotModuleReplacementPlugin'))
87
+ base.plugins.push(
88
+ new webpack.DefinePlugin('process', '{}'),
89
+ new webpack.HotModuleReplacementPlugin(),
90
+ new MiniCssExtractPlugin({
91
+ filename: 'static/css/[name].css',
92
+ chunkFilename: 'static/css/[name].chunk.css',
93
+ }),
94
+ )
95
+ base.module.rules[1].oneOf.map(rule=>{
96
+ if(!rule.use) return;
97
+ if(rule.use.find(x=>x.loader.indexOf('postcss-loader'))) {
98
+ rule.use.unshift({
99
+ loader: MiniCssExtractPlugin.loader,
100
+ options: {},
101
+ })
102
+ }
103
+ })
104
+ }
105
+ const newEntry=APP_PATH+'/src/index.jsx'
106
+ if(typeof base.entry==='string') {
107
+ base.entry=newEntry
108
+ }else if(Array.isArray(base.entry)) {
109
+ base.entry[base.entry.length-1]=newEntry
110
+ }
111
+ }
112
+
113
+ if(!IS_DEV) {
114
+ webpackConfig.externals=isServer? {
115
+ react: 'react',
116
+ 'react-dom': 'react-dom',
117
+ }: {
118
+ react: 'React',
119
+ 'react-dom': 'ReactDom',
120
+ }
121
+ }
122
+
123
+ base.resolve.alias=Object.assign(base.resolve.alias, {
124
+ '@': APP_PATH+'/src',
125
+ src: APP_PATH+'/src',
126
+ })
127
+ base.output.chunkCallbackName='webpackChunk_'+Date.now().toString(36)
128
+ base.output.jsonpFunction='webpackJsonp_'+Date.now().toString(36)
129
+ if(!IS_DEV) {
130
+ base.output.path=APP_PATH+'/dist'
131
+ base.output.publicPath='/assets/app/'
132
+ }
133
+ const conf=Object.assign(Object.assign({}, base), webpackConfig)
134
+ conf.devtool='none'
135
+ return conf
136
+ }
137
+
138
+ function webpackDev(port=3000) {
139
+ fs_extra.emptyDirSync(APP_PATH+'/dist')
140
+ const createDevBase=requireNodeModuleFile('react-scripts/config/webpackDevServer.config')
141
+ const devConfig=Object.assign({}, createDevBase(), {
142
+ writeToDisk: fn=>fn.indexOf('server')>0,
143
+ injectClient: true,
144
+ disableHostCheck: true,
145
+ index: '',
146
+ proxy: {
147
+ context: ['/'],
148
+ target: 'http://127.0.0.1:9090/',
149
+ },
150
+ })
151
+
152
+ const clientConfig=createWebpackConfig({isServer: false})
153
+ const serverConfig=createWebpackConfig({isServer: true})
154
+ const config=[clientConfig, serverConfig]
155
+ const multiCompiler=webpack(config)
156
+
157
+ multiCompiler.hooks.done.tap('done', stats=>{
158
+ const [clientStats, serverStats] = stats.toJson({
159
+ all: false,
160
+ warnings: true,
161
+ errors: true,
162
+ modules: false,
163
+ entrypoints: true,
164
+ publicPath: false,
165
+ }).children
166
+ const errors=[...clientStats.errors, ...serverStats.errors]
167
+ const warnings=[...clientStats.warnings, ...serverStats.warnings]
168
+
169
+ if(errors.length) {
170
+ console.log(chalk.red('Failed to compile.\n'))
171
+ console.log(errors[0])
172
+ }else if(warnings.length) {
173
+ console.log(chalk.yellow('Compiled with warnings.\n'))
174
+ console.log(warnings.join('\n\n'))
175
+ }else{
176
+ const hot=clientStats.entrypoints.main.assets.find(x=>x.endsWith('.hot-update.js'))
177
+ const ret={
178
+ srv: '/server/index.js',
179
+ js: '/static/js/bundle.js',
180
+ css: '/static/css/main.css',
181
+ hot: hot? '/'+hot: '',
182
+ }
183
+ fs.writeFileSync(APP_PATH+'/dist/assets.json', JSON.stringify(ret))
184
+
185
+ console.log(chalk.green('Compiled successfully!'))
186
+ }
187
+ })
188
+
189
+ const WebpackDevServer=require('webpack-dev-server')
190
+ const devServer=new WebpackDevServer(multiCompiler, devConfig)
191
+ devServer.listen(port, '0.0.0.0', e=>{
192
+ if(e) throw e
193
+ devServer.middleware.waitUntilValid(_=>{
194
+ console.log(`> Ready on http://0.0.0.0:${port}`)
195
+ })
196
+ })
197
+ }
198
+
199
+ function webpackBuild() {
200
+ fs_extra.emptyDirSync(APP_PATH+'/dist')
201
+ const clientConfig=createWebpackConfig({isServer: false, env: 'production'})
202
+ const serverConfig=createWebpackConfig({isServer: true, env: 'production'})
203
+ const config=[clientConfig, serverConfig]
204
+ const multiCompiler=webpack(config)
205
+
206
+ multiCompiler.run((err, multiStats)=>{
207
+ if(err) {
208
+ throw err
209
+ }
210
+ if(multiStats.hasErrors()) {
211
+ const message = multiStats.toJson({ all: false, errors: true }).errors.join('\n')
212
+ throw new Error(message)
213
+ }
214
+
215
+ const [clientStats]=multiStats.toJson({
216
+ all: false,
217
+ warnings: false,
218
+ errors: false,
219
+ modules: false,
220
+ entrypoints: true,
221
+ publicPath: false,
222
+ }).children
223
+ const _f=re=>clientStats.entrypoints.main.assets.find(x=>x.match(re))
224
+ const ret={
225
+ srv: 'server/index.js',
226
+ js: _f(/main\..+?\.js$/),
227
+ css: _f(/main\..+?\.css$/),
228
+ }
229
+ fs.writeFileSync(APP_PATH+'/dist/assets.json', JSON.stringify(ret))
230
+ const srv_dist=path.resolve(APP_PATH+'/server/public/app')
231
+ fs_extra.emptyDirSync(srv_dist)
232
+ fs_extra.moveSync(APP_PATH+'/dist', srv_dist, {overwrite: true})
233
+
234
+ console.info(multiStats.toString({ colors: true }))
235
+ })
236
+
237
+ }
238
+
239
+ module.exports={
240
+ webpackDev,
241
+ webpackBuild,
242
+ }
@@ -0,0 +1,48 @@
1
+ {
2
+ "scripts": {
3
+ "serve": "node build/index.js serve",
4
+ "build": "node build/index.js build",
5
+ "dev": "node build/index.js dev"
6
+ },
7
+ "dependencies": {
8
+ "@babel/plugin-proposal-private-property-in-object": "^7.21.0",
9
+ "@craco/craco": "^6.1.1",
10
+ "bootstrap-icons": "^1.11.3",
11
+ "chalk": "^4.1.0",
12
+ "cross-env": "^7.0.3",
13
+ "fs-extra": "^10.1.0",
14
+ "mini-css-extract-plugin": "1.6.2",
15
+ "multiparty": "^4.2.3",
16
+ "node-fetch": "^3.3.2",
17
+ "null-loader": "^4.0.1",
18
+ "open": "^8.4.2",
19
+ "postcss": "^7.0.0",
20
+ "postcss-px-to-viewport": "^1.1.1",
21
+ "react": "16.10.1",
22
+ "react-dom": "16.10.1",
23
+ "react-scripts": "4.0.3",
24
+ "sass": "^1.69.5",
25
+ "sptc": "^0.0.20",
26
+ "sqlite": "^5.1.1",
27
+ "sqlite3": "^5.1.7",
28
+ "webpack-dev-server": "3.11.1",
29
+ "webpackbar": "^5.0.2"
30
+ },
31
+ "browserslist": {
32
+ "production": [
33
+ "> 1%",
34
+ "last 2 versions",
35
+ "not ie <= 8",
36
+ "Android >= 4.4",
37
+ "iOS >= 8"
38
+ ],
39
+ "development": [
40
+ "last 1 chrome version",
41
+ "last 1 firefox version",
42
+ "last 1 safari version"
43
+ ]
44
+ },
45
+ "engines": {
46
+ "node": ">= 12.22.12"
47
+ }
48
+ }
@@ -0,0 +1,31 @@
1
+ <?js
2
+ class assetsController{
3
+ async indexAction() {
4
+ const fn='/'+$_REQUEST_FILE['subRoute'][1]
5
+ const path=require('path')
6
+ const fs=require('fs')
7
+ try{
8
+ return new Promise(done=>{
9
+ const _fn=__WEB__+'/'+path.resolve(fn)
10
+ const rs=fs.createReadStream(_fn)
11
+ defer(_=>rs.close())
12
+ const mime=({
13
+ '.js': 'application/x-javascript',
14
+ '.css': 'text/css',
15
+ '.jpg': 'image/jpeg',
16
+ '.png': 'image/png',
17
+ '.jpeg': 'image/jpeg',
18
+ })[path.parse(fn).ext] || 'application/octet-stream'
19
+ setResponseHeaders({
20
+ 'content-type': mime,
21
+ 'content-length': fs.statSync(_fn).size,
22
+ })
23
+ rs.on('data', buf=>echo(buf))
24
+ rs.on('end', done)
25
+ rs.on('error', done)
26
+ })
27
+ }catch(e) {
28
+ console.log(e)
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,39 @@
1
+ <?js
2
+ class dataController extends Lib_request{
3
+ constructor(data) {
4
+ super(data)
5
+ }
6
+ async getAppInfoAction() {
7
+ const v=new MessageModel
8
+ const data={}
9
+ data.requireSetup=await v.requireSetup()
10
+ Lib_response.json({data})
11
+ }
12
+ async setupAction() {
13
+ const v=new MessageModel
14
+ if(!v.requireSetup()) {
15
+ Lib_response.json({error: new Error('database exists')})
16
+ return
17
+ }
18
+ const [err]=await v.Setup()
19
+ Lib_response.json({error: err})
20
+ }
21
+ async listAction() {
22
+ const v=new MessageModel
23
+ const {begin_id}=await this.getRequestData()
24
+ const [err, msgs]=await v.getList(+begin_id)
25
+ Lib_response.json({data: msgs || [], error: err})
26
+ }
27
+ async addAction() {
28
+ const v=new MessageModel
29
+ const {msg}=await this.getRequestData()
30
+ const [err, data]=await v.add(msg)
31
+ Lib_response.json({data, error: err})
32
+ }
33
+ async detailAction() {
34
+ const v=new MessageModel
35
+ const {uuid}=await this.getRequestData()
36
+ const [err, data]=await v.detail(uuid)
37
+ Lib_response.json({data, error: err})
38
+ }
39
+ }
@@ -0,0 +1,10 @@
1
+ <?js
2
+ class errorController{
3
+ constructor(e) {
4
+ this._e=e
5
+ }
6
+ indexAction() {
7
+ if(!isDebug()) return;
8
+ echo('<pre>', this._e.stack, '</pre>')
9
+ }
10
+ }
@@ -0,0 +1,6 @@
1
+ <?js
2
+ class ssrController{
3
+ async indexAction() {
4
+ await Lib_ssr.render()
5
+ }
6
+ }