Skip to content
This repository was archived by the owner on Sep 12, 2019. It is now read-only.

Commit 5ef5230

Browse files
authored
implement basic netlify functions:list command (#211)
* implement basic netlify functions:list command * add check against deployment * note and check functions folder source
1 parent ff8ea5d commit 5ef5230

File tree

3 files changed

+120
-53
lines changed

3 files changed

+120
-53
lines changed

src/commands/functions/list.js

Lines changed: 84 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,98 @@
1-
const { Command, flags } = require("@oclif/command");
1+
const chalk = require("chalk");
2+
const Command = require("@netlify/cli-utils");
3+
const { flags } = require("@oclif/command");
24
const AsciiTable = require("ascii-table");
3-
5+
const { getFunctions } = require("../../utils/get-functions");
46
class FunctionsListCommand extends Command {
57
async run() {
6-
var table = new AsciiTable("Netlify Functions");
7-
table
8-
.setHeading("Name", "Url", "Type", "id")
9-
.addRow(
10-
"function-abc",
11-
"site.com/.netlify/function-abc",
12-
"http GET",
13-
"124123-ddhshs1212-1211"
14-
)
15-
.addRow(
16-
"send-email-function",
17-
"site.com/.netlify/send-email-function",
18-
"http POST",
19-
"x3123-22345-1211"
20-
)
21-
.addRow(
22-
"lol-function-cool",
23-
"site.com/.netlify/lol-function-cool",
24-
"scheduled",
25-
"weyhfd-hjjk-67533"
8+
let { flags } = this.parse(FunctionsListCommand);
9+
const { api, site, config } = this.netlify;
10+
11+
// get deployed site details
12+
// copied from `netlify status`
13+
const siteId = site.id;
14+
if (!siteId) {
15+
this.warn("Did you run `netlify link` yet?");
16+
this.error(`You don't appear to be in a folder that is linked to a site`);
17+
}
18+
let siteData;
19+
try {
20+
siteData = await api.getSite({ siteId });
21+
} catch (e) {
22+
if (e.status === 401 /* unauthorized*/) {
23+
this.warn(
24+
`Log in with a different account or re-link to a site you have permission for`
25+
);
26+
this.error(
27+
`Not authorized to view the currently linked site (${siteId})`
28+
);
29+
}
30+
if (e.status === 404 /* missing */) {
31+
this.error(`The site this folder is linked to can't be found`);
32+
}
33+
this.error(e);
34+
}
35+
const deploy = siteData.published_deploy || {};
36+
const deployed_functions = deploy.available_functions || [];
37+
38+
const functionsDir =
39+
flags.functions ||
40+
(config.dev && config.dev.functions) ||
41+
(config.build && config.build.functions);
42+
if (typeof functionsDir === "undefined") {
43+
this.error(
44+
"functions directory is undefined, did you forget to set it in netlify.toml?"
45+
);
46+
process.exit(1);
47+
}
48+
var table = new AsciiTable(
49+
`Netlify Functions (based on local functions folder "${functionsDir}")`
50+
);
51+
const functions = getFunctions(functionsDir);
52+
53+
table.setHeading("Name", "Url", "moduleDir", "deployed");
54+
Object.entries(functions).forEach(([functionName, { moduleDir }]) => {
55+
const isDeployed = deployed_functions
56+
.map(({ n }) => n)
57+
.includes(functionName);
58+
59+
// this.log(`${chalk.yellow("function name")}: ${functionName}`);
60+
// this.log(
61+
// ` ${chalk.yellow(
62+
// "url"
63+
// )}: ${`/.netlify/functions/${functionName}`}`
64+
// );
65+
// this.log(` ${chalk.yellow("moduleDir")}: ${moduleDir}`);
66+
// this.log(
67+
// ` ${chalk.yellow("deployed")}: ${
68+
// isDeployed ? chalk.green("yes") : chalk.yellow("no")
69+
// }`
70+
// );
71+
// this.log("----------");
72+
table.addRow(
73+
functionName,
74+
`/.netlify/functions/${functionName}`,
75+
moduleDir,
76+
isDeployed ? "yes" : "no"
2677
);
27-
this.log(`netlify functions:list NOT IMPLEMENTED YET`);
78+
});
2879
this.log(table.toString());
2980
}
3081
}
3182

32-
FunctionsListCommand.description = `list sites
33-
...
34-
Extra documentation goes here
83+
FunctionsListCommand.description = `list functions that exist locally
84+
85+
Helpful for making sure that you have formatted your functions correctly
86+
87+
NOT the same as listing the functions that have been deployed. For that info you need to go to your Netlify deploy log.
3588
`;
3689
FunctionsListCommand.aliases = ["function:list"];
3790
FunctionsListCommand.flags = {
38-
name: flags.string({ char: "n", description: "name to print" })
91+
name: flags.string({ char: "n", description: "name to print" }),
92+
functions: flags.string({
93+
char: "f",
94+
description: "Specify a functions folder to serve"
95+
})
3996
};
4097

4198
// TODO make visible once implementation complete

src/utils/get-functions.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
const fs = require("fs");
2+
const path = require("path");
3+
const { findModuleDir, findHandler } = require("./finders");
4+
5+
module.exports = {
6+
getFunctions(dir) {
7+
const functions = {};
8+
if (fs.existsSync(dir)) {
9+
fs.readdirSync(dir).forEach(file => {
10+
if (dir === "node_modules") {
11+
return;
12+
}
13+
const functionPath = path.resolve(path.join(dir, file));
14+
const handlerPath = findHandler(functionPath);
15+
if (!handlerPath) {
16+
return;
17+
}
18+
if (path.extname(functionPath) === ".js") {
19+
functions[file.replace(/\.js$/, "")] = {
20+
functionPath,
21+
moduleDir: findModuleDir(functionPath)
22+
};
23+
} else if (fs.lstatSync(functionPath).isDirectory()) {
24+
functions[file] = {
25+
functionPath: handlerPath,
26+
moduleDir: findModuleDir(functionPath)
27+
};
28+
}
29+
});
30+
}
31+
return functions;
32+
}
33+
};

src/utils/serve-functions.js

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ const {
1313
// NETLIFYDEVWARN,
1414
NETLIFYDEVERR
1515
} = require("netlify-cli-logo");
16-
17-
const { findModuleDir, findHandler } = require("./finders");
16+
const { getFunctions } = require("./get-functions");
1817

1918
const defaultPort = 34567;
2019

@@ -55,30 +54,7 @@ function buildClientContext(headers) {
5554
}
5655

5756
function createHandler(dir) {
58-
const functions = {};
59-
if (fs.existsSync(dir)) {
60-
fs.readdirSync(dir).forEach(file => {
61-
if (dir === "node_modules") {
62-
return;
63-
}
64-
const functionPath = path.resolve(path.join(dir, file));
65-
const handlerPath = findHandler(functionPath);
66-
if (!handlerPath) {
67-
return;
68-
}
69-
if (path.extname(functionPath) === ".js") {
70-
functions[file.replace(/\.js$/, "")] = {
71-
functionPath,
72-
moduleDir: findModuleDir(functionPath)
73-
};
74-
} else if (fs.lstatSync(functionPath).isDirectory()) {
75-
functions[file] = {
76-
functionPath: handlerPath,
77-
moduleDir: findModuleDir(functionPath)
78-
};
79-
}
80-
});
81-
}
57+
const functions = getFunctions(dir);
8258

8359
const clearCache = action => path => {
8460
console.log(`${NETLIFYDEVLOG} ${path} ${action}, reloading...`); // eslint-disable-line no-console
@@ -144,6 +120,7 @@ function createHandler(dir) {
144120

145121
let callbackWasCalled = false;
146122
const callback = createCallback(response);
123+
// we already checked that it exports a function named handler above
147124
const promise = handler.handler(
148125
lambdaRequest,
149126
{ clientContext: buildClientContext(request.headers) || {} },

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy