do-functions-cli 1.0.0
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/README.md +70 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +32 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/create.d.ts +4 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +130 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/constants.d.ts +11 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +11 -0
- package/dist/constants.js.map +1 -0
- package/dist/schemas/doFunction.d.ts +23 -0
- package/dist/schemas/doFunction.d.ts.map +1 -0
- package/dist/schemas/doFunction.js +19 -0
- package/dist/schemas/doFunction.js.map +1 -0
- package/dist/schemas/doPackage.d.ts +25 -0
- package/dist/schemas/doPackage.d.ts.map +1 -0
- package/dist/schemas/doPackage.js +14 -0
- package/dist/schemas/doPackage.js.map +1 -0
- package/dist/schemas/doProjectYml.d.ts +26 -0
- package/dist/schemas/doProjectYml.d.ts.map +1 -0
- package/dist/schemas/doProjectYml.js +12 -0
- package/dist/schemas/doProjectYml.js.map +1 -0
- package/dist/utils/scaffold.d.ts +24 -0
- package/dist/utils/scaffold.d.ts.map +1 -0
- package/dist/utils/scaffold.js +56 -0
- package/dist/utils/scaffold.js.map +1 -0
- package/dist/utils/util.d.ts +24 -0
- package/dist/utils/util.d.ts.map +1 -0
- package/dist/utils/util.js +56 -0
- package/dist/utils/util.js.map +1 -0
- package/dist/utils/validators.d.ts +8 -0
- package/dist/utils/validators.d.ts.map +1 -0
- package/dist/utils/validators.js +14 -0
- package/dist/utils/validators.js.map +1 -0
- package/package.json +49 -0
- package/templates/functions/javascript/.include +1 -0
- package/templates/functions/javascript/index.js +3 -0
- package/templates/functions/javascript/package.json +10 -0
- package/templates/functions/typescript/.include +1 -0
- package/templates/functions/typescript/index.ts +3 -0
- package/templates/functions/typescript/package.json +12 -0
- package/templates/functions/typescript/tsconfig.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# do-functions-cli
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+
|
|
6
|
+
A CLI tool to streamline working with DigitalOcean Serverless Functions.
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- Create new function packages via an interactive `create` command
|
|
11
|
+
- Support for multiple languages (JavaScript, TypeScript, more to come)
|
|
12
|
+
- Auto-install dependencies in the generated package (optional)
|
|
13
|
+
- Automatically update the root `project.yml` with the new package/function (optional)
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
Global:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm i -g do-functions-cli
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Local:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm i -D do-functions-cli
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
Run the CLI and follow the prompts:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Show help
|
|
35
|
+
npx do-functions-cli --help
|
|
36
|
+
|
|
37
|
+
# Create a new function
|
|
38
|
+
npx do-functions-cli create
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Roadmap / Ideas
|
|
42
|
+
|
|
43
|
+
- Non-interactive flags for commands (see below)
|
|
44
|
+
- Additional commands: `validate`, `deploy`, etc.
|
|
45
|
+
|
|
46
|
+
## Planned CLI Flags
|
|
47
|
+
|
|
48
|
+
- `--packages-dir <path>`: Set root packages directory (defaults to `./packages`).
|
|
49
|
+
- `--function <package/name>`: Provide function identifier directly.
|
|
50
|
+
- `--<language>`: Choose template language (e.g., `--javascript`, `--typescript`).
|
|
51
|
+
- `--install` / `--no-install`: Control dependency installation step.
|
|
52
|
+
- `--add-project` / `--no-add-project`: Control `project.yml` auto-update.
|
|
53
|
+
- `--dry-run`: Show intended actions without any file changes.
|
|
54
|
+
- `--verbose`: Print detailed logs for troubleshooting.
|
|
55
|
+
|
|
56
|
+
## Troubleshooting
|
|
57
|
+
|
|
58
|
+
- If `project.yml` parsing fails, ensure the file is valid YAML and matches the expected schema:
|
|
59
|
+
|
|
60
|
+
```yaml
|
|
61
|
+
packages:
|
|
62
|
+
- name: Package Name
|
|
63
|
+
functions:
|
|
64
|
+
- name: sample/func1
|
|
65
|
+
runtime: nodejs:18
|
|
66
|
+
web: true
|
|
67
|
+
...
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
- Ensure Node.js 18+ for best compatibility with templates and runtime.
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import createCommand from './commands/create.js';
|
|
4
|
+
import fs from 'fs-extra/esm';
|
|
5
|
+
const packageJson = await fs.readJSON(new URL('../package.json', import.meta.url));
|
|
6
|
+
const cliVersion = packageJson.version;
|
|
7
|
+
// Initialize the main CLI program
|
|
8
|
+
const program = new Command();
|
|
9
|
+
program
|
|
10
|
+
.name('do-functions-cli')
|
|
11
|
+
.description('CLI tool for managing DigitalOcean serverless functions')
|
|
12
|
+
.version(cliVersion);
|
|
13
|
+
// Register the 'create' command for creating new serverless functions
|
|
14
|
+
program.addCommand(createCommand);
|
|
15
|
+
// Parse command-line arguments and execute
|
|
16
|
+
program.parse(process.argv);
|
|
17
|
+
/**
|
|
18
|
+
* Handle uncaught exceptions globally.
|
|
19
|
+
*
|
|
20
|
+
* ExitPromptError is thrown when a user cancels an interactive prompt,
|
|
21
|
+
* so we handle it gracefully. Other errors are re-thrown for proper error reporting.
|
|
22
|
+
*/
|
|
23
|
+
process.on('uncaughtException', (error) => {
|
|
24
|
+
if (error instanceof Error && error.name === 'ExitPromptError') {
|
|
25
|
+
console.log('👋 until next time!');
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
// Rethrow unknown errors for proper error handling and exit
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,aAAa,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,MAAM,cAAc,CAAC;AAE9B,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACnF,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC;AAEvC,kCAAkC;AAClC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAC9B,OAAO;KACJ,IAAI,CAAC,kBAAkB,CAAC;KACxB,WAAW,CAAC,yDAAyD,CAAC;KACtE,OAAO,CAAC,UAAU,CAAC,CAAC;AAEvB,sEAAsE;AACtE,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAElC,2CAA2C;AAC3C,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE5B;;;;;GAKG;AACH,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,KAAK,EAAE,EAAE;IACxC,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IACrC,CAAC;SAAM,CAAC;QACN,4DAA4D;QAC5D,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC,QAAA,MAAM,aAAa,SAAwB,CAAC;AAmH5C,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command module for creating new DigitalOcean serverless functions.
|
|
3
|
+
*
|
|
4
|
+
* This module provides an interactive CLI command that guides users through:
|
|
5
|
+
* 1. Selecting a packages directory
|
|
6
|
+
* 2. Creating a new function with package/name structure
|
|
7
|
+
* 3. Choosing between different language templates
|
|
8
|
+
* 4. Installing dependencies (optional)
|
|
9
|
+
* 5. Adding the function to project.yml configuration (optional)
|
|
10
|
+
*/
|
|
11
|
+
import { confirm, input, select } from '@inquirer/prompts';
|
|
12
|
+
import { Command } from 'commander';
|
|
13
|
+
import fs from 'fs-extra';
|
|
14
|
+
import * as child_process from 'node:child_process';
|
|
15
|
+
import * as path from 'node:path';
|
|
16
|
+
import * as util from 'node:util';
|
|
17
|
+
import ora from 'ora';
|
|
18
|
+
import { scaffoldFunction, updateProjectConfig } from '../utils/util.js';
|
|
19
|
+
import { validateFunctionName } from '../utils/validators.js';
|
|
20
|
+
// Promisify exec to use async/await syntax
|
|
21
|
+
const exec = util.promisify(child_process.exec);
|
|
22
|
+
const createCommand = new Command('create');
|
|
23
|
+
createCommand.description('create a new serverless function');
|
|
24
|
+
createCommand.option('-y, --yes', 'skip all optional prompts and use defaults');
|
|
25
|
+
createCommand.action(async (options) => {
|
|
26
|
+
const userPackagesDir = await input({
|
|
27
|
+
message: 'Enter the root function packages directory:',
|
|
28
|
+
default: './packages',
|
|
29
|
+
});
|
|
30
|
+
const userFuncPath = await input({
|
|
31
|
+
message: 'Enter the package/function name to create:',
|
|
32
|
+
default: 'sample/hello',
|
|
33
|
+
validate: validateFunctionName,
|
|
34
|
+
});
|
|
35
|
+
const [pkgName, funcName] = userFuncPath.split('/');
|
|
36
|
+
const resolvedFuncDir = path.resolve(userPackagesDir, userFuncPath);
|
|
37
|
+
if (await fs.exists(resolvedFuncDir)) {
|
|
38
|
+
const overwrite = await confirm({
|
|
39
|
+
message: `The directory "${resolvedFuncDir}" already exists. Do you want to overwrite it?`,
|
|
40
|
+
default: false,
|
|
41
|
+
});
|
|
42
|
+
if (!overwrite) {
|
|
43
|
+
ora('Operation cancelled. No changes were made.').fail();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const funcLanguage = (await select({
|
|
48
|
+
message: 'Choose a language for the function:',
|
|
49
|
+
choices: [
|
|
50
|
+
{ name: 'JavaScript', value: 'javascript' },
|
|
51
|
+
{ name: 'TypeScript', value: 'typescript' },
|
|
52
|
+
],
|
|
53
|
+
default: 'javascript',
|
|
54
|
+
}));
|
|
55
|
+
// Initialize a spinner to show progress to the user
|
|
56
|
+
const spinner = ora(`Creating function '${userFuncPath}'...`).start();
|
|
57
|
+
try {
|
|
58
|
+
await scaffoldFunction({
|
|
59
|
+
targetDir: resolvedFuncDir,
|
|
60
|
+
funcPath: userFuncPath,
|
|
61
|
+
funcLanguage,
|
|
62
|
+
});
|
|
63
|
+
spinner.succeed(`Function "${userFuncPath}" successfully created at "${resolvedFuncDir}"`);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
spinner.fail('An error occurred while creating the function');
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
// Offer to install dependencies in the new function directory
|
|
70
|
+
const installDeps = options.yes ||
|
|
71
|
+
(await confirm({
|
|
72
|
+
message: 'Do you want to install dependencies now?',
|
|
73
|
+
default: true,
|
|
74
|
+
}));
|
|
75
|
+
if (installDeps) {
|
|
76
|
+
spinner.start('Installing dependencies...');
|
|
77
|
+
try {
|
|
78
|
+
// Run npm install in the function directory
|
|
79
|
+
await exec('npm install', { cwd: resolvedFuncDir });
|
|
80
|
+
spinner.succeed('Dependencies installed successfully');
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
spinner.fail('An error occurred while installing dependencies');
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Offer to add the new function to the project configuration file
|
|
88
|
+
const addToProject = options.yes ||
|
|
89
|
+
(await confirm({
|
|
90
|
+
message: 'Do you want to add this function automatically to the project.yml config?',
|
|
91
|
+
default: true,
|
|
92
|
+
}));
|
|
93
|
+
if (addToProject) {
|
|
94
|
+
const projectYmlPath = path.resolve('project.yml');
|
|
95
|
+
const createIfMissing = !(await fs.exists(projectYmlPath))
|
|
96
|
+
? options.yes ||
|
|
97
|
+
(await confirm({
|
|
98
|
+
message: 'A project.yml file was not found. Would you like to create one?',
|
|
99
|
+
default: true,
|
|
100
|
+
}))
|
|
101
|
+
: true;
|
|
102
|
+
if (!createIfMissing) {
|
|
103
|
+
spinner.info('Skipping creating the project.yml file...');
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
spinner.start('Updating project.yml configuration...');
|
|
107
|
+
const result = await updateProjectConfig(projectYmlPath, pkgName, funcName);
|
|
108
|
+
const resultStatusMessageMap = {
|
|
109
|
+
'created-new-config': `Created project.yml with package "${pkgName}" and function "${userFuncPath}"`,
|
|
110
|
+
'added-package': `Added new package "${pkgName}" with function "${userFuncPath}" to project.yml`,
|
|
111
|
+
'added-function': `Added function "${userFuncPath}" to existing package "${pkgName}" in project.yml`,
|
|
112
|
+
'function-exists': `Function "${userFuncPath}" already exists in package "${pkgName}". Skipping update.`,
|
|
113
|
+
error: 'Failed to update project.yml configuration',
|
|
114
|
+
};
|
|
115
|
+
const resultStatusMessage = resultStatusMessageMap[result.status];
|
|
116
|
+
if (result.status === 'error') {
|
|
117
|
+
spinner.fail(resultStatusMessage);
|
|
118
|
+
}
|
|
119
|
+
else if (result.status === 'function-exists') {
|
|
120
|
+
spinner.info(resultStatusMessage);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
spinner.succeed(resultStatusMessage);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
// Export the create command for registration in the CLI
|
|
129
|
+
export default createCommand;
|
|
130
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default runtime environment for DigitalOcean Functions.
|
|
3
|
+
*/
|
|
4
|
+
export declare const DEFAULT_RUNTIME = "nodejs:18";
|
|
5
|
+
/**
|
|
6
|
+
* Regex pattern to validate function names.
|
|
7
|
+
* Function names must be in the format: package/name (e.g., 'myapp/hello')
|
|
8
|
+
* Both the package and function name must contain only lowercase letters.
|
|
9
|
+
*/
|
|
10
|
+
export declare const FUNCTION_NAME_REGEX: RegExp;
|
|
11
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,eAAe,cAAc,CAAC;AAE3C;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,QAAqB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default runtime environment for DigitalOcean Functions.
|
|
3
|
+
*/
|
|
4
|
+
export const DEFAULT_RUNTIME = 'nodejs:18';
|
|
5
|
+
/**
|
|
6
|
+
* Regex pattern to validate function names.
|
|
7
|
+
* Function names must be in the format: package/name (e.g., 'myapp/hello')
|
|
8
|
+
* Both the package and function name must contain only lowercase letters.
|
|
9
|
+
*/
|
|
10
|
+
export const FUNCTION_NAME_REGEX = /^[a-z]+\/[a-z]+$/;
|
|
11
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,WAAW,CAAC;AAE3C;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as z from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Zod schema for validating a DigitalOcean function entry in project.yml
|
|
4
|
+
*
|
|
5
|
+
* Properties:
|
|
6
|
+
* - name: The function name (required)
|
|
7
|
+
* - runtime: The Node.js runtime version (defaults to DEFAULT_RUNTIME)
|
|
8
|
+
* - web: Whether the function is web-accessible (defaults to true)
|
|
9
|
+
*/
|
|
10
|
+
export declare const DOFunctionSchema: z.ZodObject<{
|
|
11
|
+
name: z.ZodString;
|
|
12
|
+
runtime: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
13
|
+
"nodejs:18": "nodejs:18";
|
|
14
|
+
"nodejs:14": "nodejs:14";
|
|
15
|
+
"nodejs:default": "nodejs:default";
|
|
16
|
+
}>>>;
|
|
17
|
+
web: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
18
|
+
}, z.core.$strip>;
|
|
19
|
+
/**
|
|
20
|
+
* TypeScript type derived from the DOFunctionSchema
|
|
21
|
+
*/
|
|
22
|
+
export type DOFunction = z.infer<typeof DOFunctionSchema>;
|
|
23
|
+
//# sourceMappingURL=doFunction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doFunction.d.ts","sourceRoot":"","sources":["../../src/schemas/doFunction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAGzB;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;iBAO3B,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as z from 'zod';
|
|
2
|
+
import { DEFAULT_RUNTIME } from '../constants.js';
|
|
3
|
+
/**
|
|
4
|
+
* Zod schema for validating a DigitalOcean function entry in project.yml
|
|
5
|
+
*
|
|
6
|
+
* Properties:
|
|
7
|
+
* - name: The function name (required)
|
|
8
|
+
* - runtime: The Node.js runtime version (defaults to DEFAULT_RUNTIME)
|
|
9
|
+
* - web: Whether the function is web-accessible (defaults to true)
|
|
10
|
+
*/
|
|
11
|
+
export const DOFunctionSchema = z.object({
|
|
12
|
+
name: z.string(),
|
|
13
|
+
runtime: z
|
|
14
|
+
.enum(['nodejs:14', 'nodejs:18', 'nodejs:default'])
|
|
15
|
+
.optional()
|
|
16
|
+
.default(DEFAULT_RUNTIME),
|
|
17
|
+
web: z.boolean().optional().default(true),
|
|
18
|
+
});
|
|
19
|
+
//# sourceMappingURL=doFunction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doFunction.js","sourceRoot":"","sources":["../../src/schemas/doFunction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,OAAO,EAAE,CAAC;SACP,IAAI,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,gBAAgB,CAAC,CAAC;SAClD,QAAQ,EAAE;SACV,OAAO,CAAC,eAA8B,CAAC;IAC1C,GAAG,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;CAC1C,CAAC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as z from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Zod schema for validating a DigitalOcean function package entry in project.yml
|
|
4
|
+
*
|
|
5
|
+
* Properties:
|
|
6
|
+
* - name: The package name (required, used for namespacing functions)
|
|
7
|
+
* - functions: Array of functions belonging to this package (defaults to empty array)
|
|
8
|
+
*/
|
|
9
|
+
export declare const DOPackageSchema: z.ZodObject<{
|
|
10
|
+
name: z.ZodString;
|
|
11
|
+
functions: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
12
|
+
name: z.ZodString;
|
|
13
|
+
runtime: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
14
|
+
"nodejs:18": "nodejs:18";
|
|
15
|
+
"nodejs:14": "nodejs:14";
|
|
16
|
+
"nodejs:default": "nodejs:default";
|
|
17
|
+
}>>>;
|
|
18
|
+
web: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
19
|
+
}, z.core.$strip>>>>;
|
|
20
|
+
}, z.core.$strip>;
|
|
21
|
+
/**
|
|
22
|
+
* TypeScript type derived from the DOPackageSchema
|
|
23
|
+
*/
|
|
24
|
+
export type DOPackage = z.infer<typeof DOPackageSchema>;
|
|
25
|
+
//# sourceMappingURL=doPackage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doPackage.d.ts","sourceRoot":"","sources":["../../src/schemas/doPackage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAGzB;;;;;;GAMG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;iBAG1B,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as z from 'zod';
|
|
2
|
+
import { DOFunctionSchema } from './doFunction.js';
|
|
3
|
+
/**
|
|
4
|
+
* Zod schema for validating a DigitalOcean function package entry in project.yml
|
|
5
|
+
*
|
|
6
|
+
* Properties:
|
|
7
|
+
* - name: The package name (required, used for namespacing functions)
|
|
8
|
+
* - functions: Array of functions belonging to this package (defaults to empty array)
|
|
9
|
+
*/
|
|
10
|
+
export const DOPackageSchema = z.object({
|
|
11
|
+
name: z.string(),
|
|
12
|
+
functions: z.array(DOFunctionSchema).optional().default([]),
|
|
13
|
+
});
|
|
14
|
+
//# sourceMappingURL=doPackage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doPackage.js","sourceRoot":"","sources":["../../src/schemas/doPackage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;CAC5D,CAAC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as z from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Zod schema for validating a project.yml configuration structure
|
|
4
|
+
*
|
|
5
|
+
* Properties:
|
|
6
|
+
* - packages: Array of packages that make up the project (defaults to empty array)
|
|
7
|
+
*/
|
|
8
|
+
export declare const DOProjectYmlSchema: z.ZodObject<{
|
|
9
|
+
packages: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
10
|
+
name: z.ZodString;
|
|
11
|
+
functions: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
12
|
+
name: z.ZodString;
|
|
13
|
+
runtime: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
14
|
+
"nodejs:18": "nodejs:18";
|
|
15
|
+
"nodejs:14": "nodejs:14";
|
|
16
|
+
"nodejs:default": "nodejs:default";
|
|
17
|
+
}>>>;
|
|
18
|
+
web: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
19
|
+
}, z.core.$strip>>>>;
|
|
20
|
+
}, z.core.$strip>>>>;
|
|
21
|
+
}, z.core.$strip>;
|
|
22
|
+
/**
|
|
23
|
+
* TypeScript type derived from the DOProjectYmlSchema
|
|
24
|
+
*/
|
|
25
|
+
export type DOProjectYml = z.infer<typeof DOProjectYmlSchema>;
|
|
26
|
+
//# sourceMappingURL=doProjectYml.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doProjectYml.d.ts","sourceRoot":"","sources":["../../src/schemas/doProjectYml.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAGzB;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;iBAE7B,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as z from 'zod';
|
|
2
|
+
import { DOPackageSchema } from './doPackage.js';
|
|
3
|
+
/**
|
|
4
|
+
* Zod schema for validating a project.yml configuration structure
|
|
5
|
+
*
|
|
6
|
+
* Properties:
|
|
7
|
+
* - packages: Array of packages that make up the project (defaults to empty array)
|
|
8
|
+
*/
|
|
9
|
+
export const DOProjectYmlSchema = z.object({
|
|
10
|
+
packages: z.array(DOPackageSchema).optional().default([]),
|
|
11
|
+
});
|
|
12
|
+
//# sourceMappingURL=doProjectYml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doProjectYml.js","sourceRoot":"","sources":["../../src/schemas/doProjectYml.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;CAC1D,CAAC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type LanguageChoice = 'typescript' | 'javascript';
|
|
2
|
+
/**
|
|
3
|
+
* Get the template directory for a function depending on language choice.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getTemplateDir(funcLanguage: LanguageChoice): string;
|
|
6
|
+
export type ScaffoldOptions = {
|
|
7
|
+
targetDir: string;
|
|
8
|
+
funcPath: string;
|
|
9
|
+
funcLanguage: LanguageChoice;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Scaffolds a function directory by emptying target and copying template, then updating package.json name.
|
|
13
|
+
*/
|
|
14
|
+
export declare function scaffoldFunction({ targetDir, funcPath, funcLanguage, }: ScaffoldOptions): Promise<void>;
|
|
15
|
+
export type UpdateStatus = 'created-new-config' | 'added-package' | 'added-function' | 'function-exists' | 'error';
|
|
16
|
+
export type UpdateResult = {
|
|
17
|
+
status: UpdateStatus;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Update or create the project.yml configuration with the given package and function.
|
|
21
|
+
* Uses early returns for clarity. Returns a status describing the performed action.
|
|
22
|
+
*/
|
|
23
|
+
export declare function updateProjectConfig(projectYmlPath: string, pkgName: string, funcName: string): Promise<UpdateResult>;
|
|
24
|
+
//# sourceMappingURL=scaffold.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../src/utils/scaffold.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,YAAY,CAAC;AAEzD;;GAEG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,cAAc,GAAG,MAAM,CAOnE;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,cAAc,CAAC;CAC9B,CAAC;AAEF;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,EACrC,SAAS,EACT,QAAQ,EACR,YAAY,GACb,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAQjC;AAED,MAAM,MAAM,YAAY,GACpB,oBAAoB,GACpB,eAAe,GACf,gBAAgB,GAChB,iBAAiB,GACjB,OAAO,CAAC;AAEZ,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,YAAY,CAAC;CACtB,CAAC;AAEF;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,CAAC,CA+BvB"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { DEFAULT_RUNTIME } from '../constants.js';
|
|
4
|
+
import { DOProjectYmlSchema } from '../schemas/doProjectYml.js';
|
|
5
|
+
import YAML from 'yaml';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
/**
|
|
8
|
+
* Get the template directory for a function depending on language choice.
|
|
9
|
+
*/
|
|
10
|
+
export function getTemplateDir(funcLanguage) {
|
|
11
|
+
return path.join(fileURLToPath(new URL('../../', import.meta.url)), 'templates', 'functions', funcLanguage);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Scaffolds a function directory by emptying target and copying template, then updating package.json name.
|
|
15
|
+
*/
|
|
16
|
+
export async function scaffoldFunction({ targetDir, funcPath, funcLanguage, }) {
|
|
17
|
+
await fs.emptyDir(targetDir);
|
|
18
|
+
const templateDir = getTemplateDir(funcLanguage);
|
|
19
|
+
await fs.copy(templateDir, targetDir);
|
|
20
|
+
const packageJsonPath = path.join(targetDir, 'package.json');
|
|
21
|
+
const packageJson = await fs.readJson(packageJsonPath);
|
|
22
|
+
await fs.writeJson(packageJsonPath, { name: `@${funcPath}`, ...packageJson }, { spaces: 2 });
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Update or create the project.yml configuration with the given package and function.
|
|
26
|
+
* Uses early returns for clarity. Returns a status describing the performed action.
|
|
27
|
+
*/
|
|
28
|
+
export async function updateProjectConfig(projectYmlPath, pkgName, funcName) {
|
|
29
|
+
try {
|
|
30
|
+
const functionObj = { name: funcName, runtime: DEFAULT_RUNTIME, web: true };
|
|
31
|
+
const exists = await fs.exists(projectYmlPath);
|
|
32
|
+
if (!exists) {
|
|
33
|
+
const initial = { packages: [{ name: pkgName, functions: [functionObj] }] };
|
|
34
|
+
await fs.writeFile(projectYmlPath, YAML.stringify(initial));
|
|
35
|
+
return { status: 'created-new-config' };
|
|
36
|
+
}
|
|
37
|
+
const parsed = DOProjectYmlSchema.parse(YAML.parse(await fs.readFile(projectYmlPath, 'utf-8')));
|
|
38
|
+
const pkg = parsed.packages.find((p) => p.name === pkgName);
|
|
39
|
+
if (!pkg) {
|
|
40
|
+
parsed.packages.push({ name: pkgName, functions: [functionObj] });
|
|
41
|
+
await fs.writeFile(projectYmlPath, YAML.stringify(parsed));
|
|
42
|
+
return { status: 'added-package' };
|
|
43
|
+
}
|
|
44
|
+
if (pkg.functions.find((f) => f.name === funcName)) {
|
|
45
|
+
return { status: 'function-exists' }; // No write needed
|
|
46
|
+
}
|
|
47
|
+
pkg.functions.push(functionObj);
|
|
48
|
+
await fs.writeFile(projectYmlPath, YAML.stringify(parsed));
|
|
49
|
+
return { status: 'added-function' };
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
console.error(e);
|
|
53
|
+
return { status: 'error' };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=scaffold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../src/utils/scaffold.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type LanguageChoice = 'typescript' | 'javascript';
|
|
2
|
+
/**
|
|
3
|
+
* Get the template directory for a function depending on language choice.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getTemplateDir(funcLanguage: LanguageChoice): string;
|
|
6
|
+
export type ScaffoldOptions = {
|
|
7
|
+
targetDir: string;
|
|
8
|
+
funcPath: string;
|
|
9
|
+
funcLanguage: LanguageChoice;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Scaffolds a function directory by emptying target and copying template, then updating package.json name.
|
|
13
|
+
*/
|
|
14
|
+
export declare function scaffoldFunction({ targetDir, funcPath, funcLanguage, }: ScaffoldOptions): Promise<void>;
|
|
15
|
+
export type UpdateStatus = 'created-new-config' | 'added-package' | 'added-function' | 'function-exists' | 'error';
|
|
16
|
+
export type UpdateResult = {
|
|
17
|
+
status: UpdateStatus;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Update or create the project.yml configuration with the given package and function.
|
|
21
|
+
* Uses early returns for clarity. Returns a status describing the performed action.
|
|
22
|
+
*/
|
|
23
|
+
export declare function updateProjectConfig(projectYmlPath: string, pkgName: string, funcName: string): Promise<UpdateResult>;
|
|
24
|
+
//# sourceMappingURL=util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/utils/util.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,YAAY,CAAC;AAEzD;;GAEG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,cAAc,GAAG,MAAM,CAOnE;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,cAAc,CAAC;CAC9B,CAAC;AAEF;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,EACrC,SAAS,EACT,QAAQ,EACR,YAAY,GACb,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAQjC;AAED,MAAM,MAAM,YAAY,GACpB,oBAAoB,GACpB,eAAe,GACf,gBAAgB,GAChB,iBAAiB,GACjB,OAAO,CAAC;AAEZ,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,YAAY,CAAC;CACtB,CAAC;AAEF;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,CAAC,CA+BvB"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { DEFAULT_RUNTIME } from '../constants.js';
|
|
4
|
+
import { DOProjectYmlSchema } from '../schemas/doProjectYml.js';
|
|
5
|
+
import YAML from 'yaml';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
/**
|
|
8
|
+
* Get the template directory for a function depending on language choice.
|
|
9
|
+
*/
|
|
10
|
+
export function getTemplateDir(funcLanguage) {
|
|
11
|
+
return path.join(fileURLToPath(new URL('../../', import.meta.url)), 'templates', 'functions', funcLanguage);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Scaffolds a function directory by emptying target and copying template, then updating package.json name.
|
|
15
|
+
*/
|
|
16
|
+
export async function scaffoldFunction({ targetDir, funcPath, funcLanguage, }) {
|
|
17
|
+
await fs.emptyDir(targetDir);
|
|
18
|
+
const templateDir = getTemplateDir(funcLanguage);
|
|
19
|
+
await fs.copy(templateDir, targetDir);
|
|
20
|
+
const packageJsonPath = path.join(targetDir, 'package.json');
|
|
21
|
+
const packageJson = await fs.readJson(packageJsonPath);
|
|
22
|
+
await fs.writeJson(packageJsonPath, { name: `@${funcPath}`, ...packageJson }, { spaces: 2 });
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Update or create the project.yml configuration with the given package and function.
|
|
26
|
+
* Uses early returns for clarity. Returns a status describing the performed action.
|
|
27
|
+
*/
|
|
28
|
+
export async function updateProjectConfig(projectYmlPath, pkgName, funcName) {
|
|
29
|
+
try {
|
|
30
|
+
const functionObj = { name: funcName, runtime: DEFAULT_RUNTIME, web: true };
|
|
31
|
+
const exists = await fs.exists(projectYmlPath);
|
|
32
|
+
if (!exists) {
|
|
33
|
+
const initial = { packages: [{ name: pkgName, functions: [functionObj] }] };
|
|
34
|
+
await fs.writeFile(projectYmlPath, YAML.stringify(initial));
|
|
35
|
+
return { status: 'created-new-config' };
|
|
36
|
+
}
|
|
37
|
+
const parsed = DOProjectYmlSchema.parse(YAML.parse(await fs.readFile(projectYmlPath, 'utf-8')));
|
|
38
|
+
const pkg = parsed.packages.find((p) => p.name === pkgName);
|
|
39
|
+
if (!pkg) {
|
|
40
|
+
parsed.packages.push({ name: pkgName, functions: [functionObj] });
|
|
41
|
+
await fs.writeFile(projectYmlPath, YAML.stringify(parsed));
|
|
42
|
+
return { status: 'added-package' };
|
|
43
|
+
}
|
|
44
|
+
if (pkg.functions.find((f) => f.name === funcName)) {
|
|
45
|
+
return { status: 'function-exists' }; // No write needed
|
|
46
|
+
}
|
|
47
|
+
pkg.functions.push(functionObj);
|
|
48
|
+
await fs.writeFile(projectYmlPath, YAML.stringify(parsed));
|
|
49
|
+
return { status: 'added-function' };
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
console.error(e);
|
|
53
|
+
return { status: 'error' };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/utils/util.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates that a function name matches the required format (package/name).
|
|
3
|
+
*
|
|
4
|
+
* @param value - The function name input to validate
|
|
5
|
+
* @returns true if valid, or an error message string if invalid
|
|
6
|
+
*/
|
|
7
|
+
export declare function validateFunctionName(value: string): true | "Function name must be in the format \"package/name\" with lowercase letters only";
|
|
8
|
+
//# sourceMappingURL=validators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/utils/validators.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,6FAMjD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { FUNCTION_NAME_REGEX } from '../constants.js';
|
|
2
|
+
/**
|
|
3
|
+
* Validates that a function name matches the required format (package/name).
|
|
4
|
+
*
|
|
5
|
+
* @param value - The function name input to validate
|
|
6
|
+
* @returns true if valid, or an error message string if invalid
|
|
7
|
+
*/
|
|
8
|
+
export function validateFunctionName(value) {
|
|
9
|
+
if (!FUNCTION_NAME_REGEX.test(value)) {
|
|
10
|
+
return 'Function name must be in the format "package/name" with lowercase letters only';
|
|
11
|
+
}
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=validators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validators.js","sourceRoot":"","sources":["../../src/utils/validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAChD,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,OAAO,gFAAgF,CAAC;IAC1F,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "do-functions-cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/grantchatterton/do-functions-cli.git"
|
|
8
|
+
},
|
|
9
|
+
"author": "Grant Chatterton",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"bin": {
|
|
12
|
+
"do-functions-cli": "dist/cli.js"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"format": "prettier --write .",
|
|
17
|
+
"format:check": "prettier --check .",
|
|
18
|
+
"prepublishOnly": "npm run build",
|
|
19
|
+
"watch": "tsc -w"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@inquirer/prompts": "^8.0.1",
|
|
23
|
+
"commander": "^14.0.2",
|
|
24
|
+
"fs-extra": "^11.3.2",
|
|
25
|
+
"ora": "^9.0.0",
|
|
26
|
+
"yaml": "^2.8.1",
|
|
27
|
+
"zod": "^4.1.13"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/fs-extra": "^11.0.4",
|
|
31
|
+
"@types/node": "^24.10.1",
|
|
32
|
+
"prettier": "^3.7.2",
|
|
33
|
+
"typescript": "^5.9.3"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist",
|
|
37
|
+
"templates"
|
|
38
|
+
],
|
|
39
|
+
"keywords": [
|
|
40
|
+
"functions",
|
|
41
|
+
"utility",
|
|
42
|
+
"typescript",
|
|
43
|
+
"cli",
|
|
44
|
+
"npm",
|
|
45
|
+
"do",
|
|
46
|
+
"digitalocean",
|
|
47
|
+
"serverless"
|
|
48
|
+
]
|
|
49
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
dist/bundle.js
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
dist/bundle.js
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"private": true,
|
|
3
|
+
"type": "module",
|
|
4
|
+
"scripts": {
|
|
5
|
+
"build": "tsc --noEmit && esbuild ./index.ts --bundle --platform=node --target=node18 --format=cjs --outfile=./dist/bundle.js --minify"
|
|
6
|
+
},
|
|
7
|
+
"devDependencies": {
|
|
8
|
+
"@types/node": "^24.10.1",
|
|
9
|
+
"esbuild": "^0.27.0",
|
|
10
|
+
"typescript": "^5.9.3"
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Visit https://aka.ms/tsconfig to read more about this file
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
// File Layout
|
|
5
|
+
// "rootDir": "./src",
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
|
|
8
|
+
// Environment Settings
|
|
9
|
+
// See also https://aka.ms/tsconfig/module
|
|
10
|
+
"module": "es2022",
|
|
11
|
+
"target": "es2022",
|
|
12
|
+
// For nodejs:
|
|
13
|
+
"lib": ["ES2022"],
|
|
14
|
+
"types": ["node"],
|
|
15
|
+
// and npm install -D @types/node
|
|
16
|
+
|
|
17
|
+
// Other Outputs
|
|
18
|
+
"sourceMap": true,
|
|
19
|
+
"declaration": true,
|
|
20
|
+
"declarationMap": true,
|
|
21
|
+
|
|
22
|
+
// Stricter Typechecking Options
|
|
23
|
+
"noUncheckedIndexedAccess": true,
|
|
24
|
+
"exactOptionalPropertyTypes": true,
|
|
25
|
+
|
|
26
|
+
// Style Options
|
|
27
|
+
// "noImplicitReturns": true,
|
|
28
|
+
// "noImplicitOverride": true,
|
|
29
|
+
// "noUnusedLocals": true,
|
|
30
|
+
// "noUnusedParameters": true,
|
|
31
|
+
// "noFallthroughCasesInSwitch": true,
|
|
32
|
+
// "noPropertyAccessFromIndexSignature": true,
|
|
33
|
+
|
|
34
|
+
// Recommended Options
|
|
35
|
+
"strict": true,
|
|
36
|
+
"jsx": "react-jsx",
|
|
37
|
+
"verbatimModuleSyntax": true,
|
|
38
|
+
"isolatedModules": true,
|
|
39
|
+
"noUncheckedSideEffectImports": true,
|
|
40
|
+
"moduleDetection": "force",
|
|
41
|
+
"skipLibCheck": true
|
|
42
|
+
}
|
|
43
|
+
}
|