@foxtware/mineral 0.1.7 → 0.1.8
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.
- package/api/utils.js +5 -0
- package/bin/mineral.js +6 -0
- package/hosting/generateHosted.js +22 -2
- package/hosting/hostingPreview.js +160 -0
- package/hosting/wrappers.js +1 -1
- package/package.json +7 -2
package/api/utils.js
CHANGED
|
@@ -1134,6 +1134,10 @@ class ArgsWarden {
|
|
|
1134
1134
|
}
|
|
1135
1135
|
}
|
|
1136
1136
|
|
|
1137
|
+
const gidToId = (gid) => {
|
|
1138
|
+
return gid.split('/').pop();
|
|
1139
|
+
};
|
|
1140
|
+
|
|
1137
1141
|
module.exports = {
|
|
1138
1142
|
wait,
|
|
1139
1143
|
timeMs,
|
|
@@ -1162,4 +1166,5 @@ module.exports = {
|
|
|
1162
1166
|
Getter,
|
|
1163
1167
|
sentenceCaseString,
|
|
1164
1168
|
ArgsWarden,
|
|
1169
|
+
gidToId,
|
|
1165
1170
|
};
|
package/bin/mineral.js
CHANGED
|
@@ -11,6 +11,12 @@ if (command === 'host') {
|
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
if (command === 'hosting_preview') {
|
|
15
|
+
const { startHostingPreview } = require('../hosting/hostingPreview');
|
|
16
|
+
startHostingPreview();
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
14
20
|
const { startServer } = require('../server');
|
|
15
21
|
|
|
16
22
|
startServer();
|
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const { wrapHostedFunction } = require('./hosting.utils');
|
|
3
3
|
|
|
4
|
+
const requirePathForHostedJs = (modulePath) => {
|
|
5
|
+
if (modulePath === './hosting/wrappers.js') {
|
|
6
|
+
return './wrappers.js';
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
if (modulePath.startsWith('./api/')) {
|
|
10
|
+
return `../${ modulePath.slice(2) }`;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return modulePath;
|
|
14
|
+
};
|
|
15
|
+
|
|
4
16
|
const formatResolvedWrapperForHostedJs = ({ modulePath, wrapperName }) => (
|
|
5
|
-
`require('${ modulePath }').${ wrapperName }`
|
|
17
|
+
`require('${ requirePathForHostedJs(modulePath) }').${ wrapperName }`
|
|
6
18
|
);
|
|
7
19
|
|
|
8
20
|
const formatWrapperList = (resolvedWrappers = []) => {
|
|
@@ -53,7 +65,7 @@ const generateHostedJs = ({
|
|
|
53
65
|
});
|
|
54
66
|
|
|
55
67
|
exportLines.push(
|
|
56
|
-
` ${ hostedName }: wrapHostedFunction(() => require('${ requirePath }'), '${ handlerName }'${ wrappersArg }),`,
|
|
68
|
+
` ${ hostedName }: wrapHostedFunction(() => require('${ requirePathForHostedJs(requirePath) }'), '${ handlerName }'${ wrappersArg }),`,
|
|
57
69
|
);
|
|
58
70
|
}
|
|
59
71
|
|
|
@@ -77,6 +89,14 @@ const writeHostedJs = ({
|
|
|
77
89
|
});
|
|
78
90
|
|
|
79
91
|
fs.mkdirSync(getHostingDir(workspace), { recursive: true });
|
|
92
|
+
|
|
93
|
+
if (fs.existsSync(hostedPath)) {
|
|
94
|
+
const existingContent = fs.readFileSync(hostedPath, 'utf8');
|
|
95
|
+
if (existingContent === content) {
|
|
96
|
+
return hostedPath;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
80
100
|
fs.writeFileSync(hostedPath, content);
|
|
81
101
|
return hostedPath;
|
|
82
102
|
};
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
const http = require('http');
|
|
2
|
+
const { createRequire } = require('module');
|
|
3
|
+
const { respondJson, errorToReadable } = require('../server.utils');
|
|
4
|
+
const { getWorkspace, setWorkspace, loadWorkspaceEnv, toAbsolutePath } = require('../api/workspace');
|
|
5
|
+
const { getApiDirs, readCliFlag } = require('../cli');
|
|
6
|
+
const { loadHandlers } = require('../server');
|
|
7
|
+
const {
|
|
8
|
+
readHostingYml,
|
|
9
|
+
resolveHostedHandlersForDeploy,
|
|
10
|
+
wrapHostedFunction,
|
|
11
|
+
} = require('./hosting.utils');
|
|
12
|
+
const { copyCredsToEnv } = require('./copyCredsToEnv');
|
|
13
|
+
|
|
14
|
+
const getConfig = (options = {}) => ({
|
|
15
|
+
port: Number(options.port ?? process.env.PORT ?? 8000),
|
|
16
|
+
workspace: toAbsolutePath(
|
|
17
|
+
options.workspace
|
|
18
|
+
?? readCliFlag('--workspace')
|
|
19
|
+
?? process.env.MINERAL_WORKSPACE
|
|
20
|
+
?? process.cwd(),
|
|
21
|
+
),
|
|
22
|
+
api_dirs: getApiDirs(options),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const handlerByRouteName = (handlers) => {
|
|
26
|
+
const byName = new Map();
|
|
27
|
+
|
|
28
|
+
for (const handler of handlers.values()) {
|
|
29
|
+
byName.set(handler.routeName, handler);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return byName;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const loadHostedRoutes = (config) => {
|
|
36
|
+
const { functions } = readHostingYml(config.workspace);
|
|
37
|
+
const handlers = loadHandlers({
|
|
38
|
+
...config,
|
|
39
|
+
host_mode: true,
|
|
40
|
+
});
|
|
41
|
+
const handlersByName = handlerByRouteName(handlers);
|
|
42
|
+
const hostedHandlers = resolveHostedHandlersForDeploy({
|
|
43
|
+
functions,
|
|
44
|
+
workspace: config.workspace,
|
|
45
|
+
handlersByName,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const workspaceRequire = createRequire(`${ config.workspace.replace(/\/$/, '') }/package.json`);
|
|
49
|
+
const routes = new Map();
|
|
50
|
+
|
|
51
|
+
for (const hostedHandler of hostedHandlers) {
|
|
52
|
+
const {
|
|
53
|
+
hostedName,
|
|
54
|
+
handlerName,
|
|
55
|
+
resolvedBeforeWrappers = [],
|
|
56
|
+
resolvedAfterWrappers = [],
|
|
57
|
+
requirePath,
|
|
58
|
+
} = hostedHandler;
|
|
59
|
+
|
|
60
|
+
const beforeWrappers = resolvedBeforeWrappers.map(({ modulePath, wrapperName }) => (
|
|
61
|
+
workspaceRequire(modulePath)[wrapperName]
|
|
62
|
+
));
|
|
63
|
+
const afterWrappers = resolvedAfterWrappers.map(({ modulePath, wrapperName }) => (
|
|
64
|
+
workspaceRequire(modulePath)[wrapperName]
|
|
65
|
+
));
|
|
66
|
+
|
|
67
|
+
routes.set(
|
|
68
|
+
`/${ hostedName }`,
|
|
69
|
+
wrapHostedFunction(
|
|
70
|
+
() => workspaceRequire(requirePath),
|
|
71
|
+
handlerName,
|
|
72
|
+
{
|
|
73
|
+
beforeWrappers,
|
|
74
|
+
afterWrappers,
|
|
75
|
+
},
|
|
76
|
+
),
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return routes;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const createHostedPreviewServer = (handlers) => http.createServer(async (req, res) => {
|
|
84
|
+
if (req.method === 'GET' && req.url === '/') {
|
|
85
|
+
respondJson(res, 200, {
|
|
86
|
+
ok: true,
|
|
87
|
+
data: {
|
|
88
|
+
mode: 'hosting_preview',
|
|
89
|
+
routes: [...handlers.keys()].sort(),
|
|
90
|
+
workspace: getWorkspace(),
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const route = (req.url || '/').split('?')[0];
|
|
97
|
+
const handler = handlers.get(route);
|
|
98
|
+
|
|
99
|
+
if (!handler) {
|
|
100
|
+
respondJson(res, 404, {
|
|
101
|
+
ok: false,
|
|
102
|
+
error: {
|
|
103
|
+
code: 'NOT_FOUND',
|
|
104
|
+
message: `No hosted handler found for route ${ route }`,
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
await handler(req, res);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
if (res.headersSent) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
respondJson(res, 500, {
|
|
118
|
+
ok: false,
|
|
119
|
+
error: {
|
|
120
|
+
code: 'UNHANDLED_ERROR',
|
|
121
|
+
message: 'Unhandled server error.',
|
|
122
|
+
details: errorToReadable(error),
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const startHostingPreview = (options = {}) => {
|
|
129
|
+
process.env.HOSTED = 'true';
|
|
130
|
+
|
|
131
|
+
const config = getConfig(options);
|
|
132
|
+
|
|
133
|
+
setWorkspace(config.workspace);
|
|
134
|
+
copyCredsToEnv(config.workspace);
|
|
135
|
+
loadWorkspaceEnv();
|
|
136
|
+
|
|
137
|
+
const handlers = loadHostedRoutes(config);
|
|
138
|
+
const server = createHostedPreviewServer(handlers);
|
|
139
|
+
|
|
140
|
+
server.listen(config.port, () => {
|
|
141
|
+
console.log(`Hosting preview running on port ${ config.port }`);
|
|
142
|
+
console.log(`Workspace: ${ config.workspace }`);
|
|
143
|
+
console.log('Hosted routes:');
|
|
144
|
+
|
|
145
|
+
for (const route of [...handlers.keys()].sort()) {
|
|
146
|
+
console.log(route);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
return server;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
module.exports = {
|
|
154
|
+
startHostingPreview,
|
|
155
|
+
loadHostedRoutes,
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
if (require.main === module) {
|
|
159
|
+
startHostingPreview();
|
|
160
|
+
}
|
package/hosting/wrappers.js
CHANGED
|
@@ -22,7 +22,7 @@ const allowCrossOriginCallsAndHandleOptions = async (req, res) => {
|
|
|
22
22
|
|
|
23
23
|
res.setHeader('Access-Control-Allow-Origin', origin || '*');
|
|
24
24
|
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
25
|
-
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, x-api-key, x-wf-token, x-wf-value');
|
|
25
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, x-api-key, x-wf-token, x-wf-value, x-wf-app');
|
|
26
26
|
|
|
27
27
|
if (req.method === 'OPTIONS') {
|
|
28
28
|
res.writeHead(204);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@foxtware/mineral",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"bin": {
|
|
5
5
|
"mineral": "bin/mineral.js"
|
|
6
6
|
},
|
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
12
|
"creds_to_env": "node hosting/copyCredsToEnv.js",
|
|
13
|
-
"dev": "node --watch --watch-path=./api --watch-path=./server.js --watch-path=./server.utils.js --watch-path=./.creds.yml server.js",
|
|
13
|
+
"dev": "node --watch --watch-path=./api --watch-path=./server.js --watch-path=./server.utils.js --watch-path=./hosting --watch-path=./.creds.yml server.js",
|
|
14
|
+
"hosting_preview": "node --watch --watch-path=./api --watch-path=./hosting/.hosting.yml --watch-path=./hosting/wrappers.js --watch-path=./.creds.yml hosting/hostingPreview.js",
|
|
15
|
+
"tunnel": "ngrok http http://localhost:8000",
|
|
14
16
|
"new": "node _build_scripts/createNewFunction.js",
|
|
15
17
|
"serve": "PORT=8100 node server.js",
|
|
16
18
|
"start": "node server.js",
|
|
@@ -22,5 +24,8 @@
|
|
|
22
24
|
"json-2-csv": "^5.5.9",
|
|
23
25
|
"xml2js": "^0.6.2",
|
|
24
26
|
"yaml": "^2.9.0"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"ngrok": "^5.0.0-beta.2"
|
|
25
30
|
}
|
|
26
31
|
}
|