@mnci/cli 4.24.0 → 4.26.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 +1 -1
- package/dist/cli.js +83 -17
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1336,7 +1336,7 @@ already use:
|
|
|
1336
1336
|
- **`node-function-app` overlay**: `@azure/functions` is installed for real
|
|
1337
1337
|
(a plain `@nx/node:application` app has no Azure dependency by default,
|
|
1338
1338
|
unlike a plugin-generated one), an HTTP-triggered `app.http(...)` sample
|
|
1339
|
-
(v4 programming model) is written as a `src/hello/` slice (`hello.handler.ts`
|
|
1339
|
+
(v4 programming model) is written as a `src/hello/` slice (`hello.handler.ts` adapting the transport, `greet.use-case.ts` and its spec, `greeting.contract.ts`, behind an `index.ts`; `--empty` skips the slice), `host.json` is
|
|
1340
1340
|
added, and the manifest is repaired — `main: 'main.js'` (the dist shim) and
|
|
1341
1341
|
`@azure/functions` added to `dependencies` for Azure's deploy-time install
|
|
1342
1342
|
to find.
|
package/dist/cli.js
CHANGED
|
@@ -2744,8 +2744,57 @@ function reshapeScaffoldSlice(projectRoot, name, extension, role, empty) {
|
|
|
2744
2744
|
(0, import_node_fs5.rmSync)(libDir, { recursive: true, force: true });
|
|
2745
2745
|
if (empty) {
|
|
2746
2746
|
emptySlice(projectRoot, sliceDir);
|
|
2747
|
+
} else if (role === "use-case") {
|
|
2748
|
+
writeWorkedExample(sliceDir, name, esm);
|
|
2747
2749
|
}
|
|
2748
2750
|
}
|
|
2751
|
+
function writeWorkedExample(sliceDir, name, esm) {
|
|
2752
|
+
const suffix = esm ? ".js" : "";
|
|
2753
|
+
writeFileEnsured(
|
|
2754
|
+
(0, import_node_path5.join)(sliceDir, `${name}.contract.ts`),
|
|
2755
|
+
`/** What greeting someone returns. */
|
|
2756
|
+
export interface Greeting {
|
|
2757
|
+
readonly message: string
|
|
2758
|
+
}
|
|
2759
|
+
`
|
|
2760
|
+
);
|
|
2761
|
+
writeFileEnsured(
|
|
2762
|
+
(0, import_node_path5.join)(sliceDir, `${name}.use-case.ts`),
|
|
2763
|
+
`import type { Greeting } from './${name}.contract${suffix}'
|
|
2764
|
+
|
|
2765
|
+
/**
|
|
2766
|
+
* Greets someone by name.
|
|
2767
|
+
*
|
|
2768
|
+
* @remarks
|
|
2769
|
+
* A worked example of a use case: one outcome, returning a contract. Replace it
|
|
2770
|
+
* with your own.
|
|
2771
|
+
*
|
|
2772
|
+
* @param name - Who to greet.
|
|
2773
|
+
* @returns The greeting.
|
|
2774
|
+
*/
|
|
2775
|
+
export function greet (name: string): Greeting {
|
|
2776
|
+
return { message: 'Hello, ' + name + '!' }
|
|
2777
|
+
}
|
|
2778
|
+
`
|
|
2779
|
+
);
|
|
2780
|
+
writeFileEnsured(
|
|
2781
|
+
(0, import_node_path5.join)(sliceDir, `${name}.use-case.spec.ts`),
|
|
2782
|
+
`import { greet } from './${name}.use-case${suffix}'
|
|
2783
|
+
|
|
2784
|
+
describe('greet', () => {
|
|
2785
|
+
it('greets by name', () => {
|
|
2786
|
+
expect(greet('world')).toEqual({ message: 'Hello, world!' })
|
|
2787
|
+
})
|
|
2788
|
+
})
|
|
2789
|
+
`
|
|
2790
|
+
);
|
|
2791
|
+
writeFileEnsured(
|
|
2792
|
+
(0, import_node_path5.join)(sliceDir, "index.ts"),
|
|
2793
|
+
`export * from './${name}.contract${suffix}'
|
|
2794
|
+
export * from './${name}.use-case${suffix}'
|
|
2795
|
+
`
|
|
2796
|
+
);
|
|
2797
|
+
}
|
|
2749
2798
|
function repointSpecifier(source, from, to) {
|
|
2750
2799
|
let result = source;
|
|
2751
2800
|
for (const quote of ["'", '"']) {
|
|
@@ -4017,6 +4066,10 @@ var NODE_FUNCTION_APP_MAIN = `// esbuild only includes what is reachable from he
|
|
|
4017
4066
|
// function slice you create under src/ (through its index).
|
|
4018
4067
|
import './hello'
|
|
4019
4068
|
`;
|
|
4069
|
+
var NODE_FUNCTION_APP_MAIN_EMPTY = `// esbuild only includes what is reachable from here, so import each function slice
|
|
4070
|
+
// you create under src/ (through its index).
|
|
4071
|
+
export {}
|
|
4072
|
+
`;
|
|
4020
4073
|
var NODE_FUNCTION_APP_HOST_JSON = `{
|
|
4021
4074
|
"version": "2.0",
|
|
4022
4075
|
"extensionBundle": {
|
|
@@ -4027,11 +4080,11 @@ var NODE_FUNCTION_APP_HOST_JSON = `{
|
|
|
4027
4080
|
`;
|
|
4028
4081
|
var NODE_FUNCTION_APP_HELLO = `import { app } from '@azure/functions'
|
|
4029
4082
|
import type { HttpRequest, HttpResponseInit } from '@azure/functions'
|
|
4030
|
-
import {
|
|
4083
|
+
import { greet } from './greet.use-case'
|
|
4031
4084
|
|
|
4032
4085
|
async function hello(request: HttpRequest): Promise<HttpResponseInit> {
|
|
4033
4086
|
const name = request.query.get('name') ?? 'world'
|
|
4034
|
-
return { body:
|
|
4087
|
+
return { body: greet(name).message }
|
|
4035
4088
|
}
|
|
4036
4089
|
|
|
4037
4090
|
app.http('hello', {
|
|
@@ -4043,15 +4096,22 @@ app.http('hello', {
|
|
|
4043
4096
|
`;
|
|
4044
4097
|
var NODE_FUNCTION_APP_HELLO_BARREL = `export * from './hello.handler'
|
|
4045
4098
|
`;
|
|
4046
|
-
var
|
|
4047
|
-
|
|
4099
|
+
var NODE_FUNCTION_APP_GREETING_CONTRACT = `/** What greeting someone returns. */
|
|
4100
|
+
export interface Greeting {
|
|
4101
|
+
readonly message: string
|
|
4102
|
+
}
|
|
4103
|
+
`;
|
|
4104
|
+
var NODE_FUNCTION_APP_GREET_USE_CASE = `import type { Greeting } from './greeting.contract'
|
|
4105
|
+
|
|
4106
|
+
export function greet (name: string): Greeting {
|
|
4107
|
+
return { message: 'Hello, ' + name + '!' }
|
|
4048
4108
|
}
|
|
4049
4109
|
`;
|
|
4050
|
-
var
|
|
4110
|
+
var NODE_FUNCTION_APP_GREET_SPEC = `import { greet } from './greet.use-case'
|
|
4051
4111
|
|
|
4052
|
-
describe('
|
|
4112
|
+
describe('greet', () => {
|
|
4053
4113
|
it('greets a name', () => {
|
|
4054
|
-
expect(
|
|
4114
|
+
expect(greet('world')).toEqual({ message: 'Hello, world!' })
|
|
4055
4115
|
})
|
|
4056
4116
|
})
|
|
4057
4117
|
`;
|
|
@@ -4099,22 +4159,28 @@ function nodeFunctionAppStartTarget(name) {
|
|
|
4099
4159
|
options: { command: "func start", cwd: `apps/${name}` }
|
|
4100
4160
|
};
|
|
4101
4161
|
}
|
|
4102
|
-
function addNodeFunctionApp(workspaceRoot, name, stack) {
|
|
4162
|
+
function addNodeFunctionApp(workspaceRoot, name, stack, empty = false) {
|
|
4103
4163
|
runNodeApp(workspaceRoot, name, stack, "none");
|
|
4104
4164
|
ensureAzureFunctionsPackage(workspaceRoot);
|
|
4105
4165
|
const nodeFunctionAppRoot = (0, import_node_path12.join)(workspaceRoot, "apps", name);
|
|
4106
|
-
writeFileEnsured((0, import_node_path12.join)(nodeFunctionAppRoot, "src/main.ts"), NODE_FUNCTION_APP_MAIN);
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4166
|
+
writeFileEnsured((0, import_node_path12.join)(nodeFunctionAppRoot, "src/main.ts"), empty ? NODE_FUNCTION_APP_MAIN_EMPTY : NODE_FUNCTION_APP_MAIN);
|
|
4167
|
+
if (!empty) {
|
|
4168
|
+
const slice = (0, import_node_path12.join)(nodeFunctionAppRoot, "src/hello");
|
|
4169
|
+
writeFileEnsured((0, import_node_path12.join)(slice, "hello.handler.ts"), NODE_FUNCTION_APP_HELLO);
|
|
4170
|
+
writeFileEnsured((0, import_node_path12.join)(slice, "greet.use-case.ts"), NODE_FUNCTION_APP_GREET_USE_CASE);
|
|
4171
|
+
writeFileEnsured((0, import_node_path12.join)(slice, "greet.use-case.spec.ts"), NODE_FUNCTION_APP_GREET_SPEC);
|
|
4172
|
+
writeFileEnsured((0, import_node_path12.join)(slice, "greeting.contract.ts"), NODE_FUNCTION_APP_GREETING_CONTRACT);
|
|
4173
|
+
writeFileEnsured((0, import_node_path12.join)(slice, "index.ts"), NODE_FUNCTION_APP_HELLO_BARREL);
|
|
4174
|
+
}
|
|
4111
4175
|
writeFileEnsured((0, import_node_path12.join)(nodeFunctionAppRoot, "host.json"), NODE_FUNCTION_APP_HOST_JSON);
|
|
4112
4176
|
repairNodeFunctionAppManifest(nodeFunctionAppRoot, workspaceRoot);
|
|
4113
4177
|
ensureAdmZip(workspaceRoot);
|
|
4114
4178
|
addNxTargets((0, import_node_path12.join)(nodeFunctionAppRoot, "package.json"), {
|
|
4115
4179
|
package: nodeFunctionAppPackageTarget(name),
|
|
4116
4180
|
prune: nodeFunctionAppPruneTarget(name),
|
|
4117
|
-
start: nodeFunctionAppStartTarget(name)
|
|
4181
|
+
start: nodeFunctionAppStartTarget(name),
|
|
4182
|
+
// With no spec the runner exits non-zero; an empty scaffold must still pass `nx test`.
|
|
4183
|
+
...empty && { test: { options: { passWithNoTests: true } } }
|
|
4118
4184
|
});
|
|
4119
4185
|
removeGeneratedEslintConfig(workspaceRoot, `apps/${name}`);
|
|
4120
4186
|
registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:start` });
|
|
@@ -6493,7 +6559,7 @@ var PROJECT_KINDS = [
|
|
|
6493
6559
|
"csharp-internal-lib",
|
|
6494
6560
|
"vscode-extension"
|
|
6495
6561
|
];
|
|
6496
|
-
var EMPTY_KINDS = /* @__PURE__ */ new Set(["npm-lib", "internal-lib", "react-lib", "react-internal-lib"]);
|
|
6562
|
+
var EMPTY_KINDS = /* @__PURE__ */ new Set(["npm-lib", "internal-lib", "react-lib", "react-internal-lib", "node-function-app"]);
|
|
6497
6563
|
async function runAdd(kind, name, options) {
|
|
6498
6564
|
const workspaceRoot = process.cwd();
|
|
6499
6565
|
if (!fileExists((0, import_node_path25.join)(workspaceRoot, "nx.json"))) {
|
|
@@ -6539,7 +6605,7 @@ async function runAdd(kind, name, options) {
|
|
|
6539
6605
|
break;
|
|
6540
6606
|
}
|
|
6541
6607
|
case "node-function-app": {
|
|
6542
|
-
addNodeFunctionApp(workspaceRoot, resolvedName, stack);
|
|
6608
|
+
addNodeFunctionApp(workspaceRoot, resolvedName, stack, options.empty === true);
|
|
6543
6609
|
break;
|
|
6544
6610
|
}
|
|
6545
6611
|
case "npm-lib": {
|
|
@@ -7657,7 +7723,7 @@ function buildProgram(cliVersion) {
|
|
|
7657
7723
|
"node-app only: express | fastify | koa | nest | none (default: none)"
|
|
7658
7724
|
).option(
|
|
7659
7725
|
"--empty",
|
|
7660
|
-
"npm-lib, internal-lib, react-lib, react-internal-lib: scaffold the slice skeleton only, with no sample code or spec"
|
|
7726
|
+
"npm-lib, internal-lib, react-lib, react-internal-lib, node-function-app: scaffold the slice skeleton only, with no sample code or spec"
|
|
7661
7727
|
).option(
|
|
7662
7728
|
"--lib <name>",
|
|
7663
7729
|
"python-vendor only: the internal Python library (libs/<name>) to vendor into <name>"
|