Skip to content

Commit

Permalink
Support Dev Mode (#141)
Browse files Browse the repository at this point in the history
  • Loading branch information
mildronize committed May 11, 2024
2 parents 923971a + 70cdcb2 commit a1fc496
Show file tree
Hide file tree
Showing 16 changed files with 107 additions and 83 deletions.
2 changes: 1 addition & 1 deletion infra/azure-functions/src/azure-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export async function assignRoleAssignment(infraConfig: InfraEnvConfig, options:

const resourceGroup = `rg-nammatham-${resourceName.prefix}`;
const role = 'Contributor';
const assignee = process.env.AZURE_APPLICATION_ID;
const assignee = process.env.AZURE_APPLICATION_ID;
const scope = `/subscriptions/${process.env.AZURE_SUBSCRIPTION_ID}/resourceGroups/${resourceGroup}`;
await $`az role assignment create --role ${role} --assignee ${assignee} --scope ${scope}`;
}
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
"type": "git",
"url": "https://github.com/thaitype/nammatham.git"
},
"peerDependencies": {
"tsx": "^4.7.0"
},
"devDependencies": {
"@inquirer/prompts": "^3.3.0",
"@types/fs-extra": "^11.0.4",
Expand Down
7 changes: 2 additions & 5 deletions packages/main/src/command/build/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,11 @@ import { system } from 'pkg-fetch';
import type { NammathamConfigs } from '../nammatham-config';
import type { TargetBunOptions, TargetOptions } from './types';

import { createDebugger } from '../utils';
import { debug } from './internal';
import { buildExecutableBun } from './bun';
import { findNearestPackageData } from '../packages';
import { buildExecutableNodeJs, buildNodeJs } from './nodejs';
import { constructHostConfig, constructLocalSettings } from '../config';

export const debug = createDebugger('nammatham:build');

/**
* Hard code the function.json for the SimpleHttpTrigger
*/
Expand Down Expand Up @@ -55,7 +52,7 @@ export async function buildRuntime(config: NammathamConfigs) {
export async function build(config: NammathamConfigs): Promise<void> {
const targetPath = path.resolve(config.buildPath ?? '.nmt', 'dist');
fs.mkdirSync(targetPath, { recursive: true });
await fs.promises.writeFile(path.join(targetPath, 'host.json'), constructHostConfig(config), 'utf-8');
await fs.promises.writeFile(path.join(targetPath, 'host.json'), constructHostConfig(config, 'build'), 'utf-8');
await fs.promises.writeFile(path.join(targetPath, 'local.settings.json'), constructLocalSettings(), 'utf-8');

if (config.buildOptions?.disabled) {
Expand Down
4 changes: 2 additions & 2 deletions packages/main/src/command/build/bun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import path from 'node:path';
import type { NammathamConfigs } from '../nammatham-config';
import type { TargetBunOptions, TargetOptions } from './types';

import { debug, getDistDirectory, getExecutablePath, getPackageInfo } from './build';

import { debug } from './internal';
import { getDistDirectory, getExecutablePath, getPackageInfo } from './build';
/**
* Call bun as a sub-process to build the executable file, for preventing the bundle with tsup
*/
Expand Down
3 changes: 3 additions & 0 deletions packages/main/src/command/build/internal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { createDebugger } from '../utils';

export const debug = createDebugger('nammatham:build');
16 changes: 10 additions & 6 deletions packages/main/src/command/build/nodejs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { build as esbuild } from 'esbuild';

import type { NammathamConfigs } from '../nammatham-config';

import { debug, getDistDirectory, getExecutablePath, getPackageInfo } from './build';

import { debug } from './internal';
import { getDistDirectory, getExecutablePath, getPackageInfo } from './build';
/**
* When publish into Azure Functions, the package.json will not be included in the final package.
* So, it needs to specify the output file manually wheather it is ESM or CommonJS. for example `main.mjs` or `main.cjs`
Expand Down Expand Up @@ -69,15 +69,19 @@ export async function buildNodeJs(options: NammathamConfigs): Promise<BuildNodeJ
*/
export async function buildExecutableNodeJs(options: NammathamConfigs, result: BuildNodeJsResult): Promise<void> {
if (options.buildOptions?.nodeToolChain?.package !== 'pkg') {
throw new Error(`(buildExecutableNodeJs) Unsupported package tool: ${options.buildOptions?.nodeToolChain?.package}`);
throw new Error(
`(buildExecutableNodeJs) Unsupported package tool: ${options.buildOptions?.nodeToolChain?.package}`
);
}
const target = options.buildOptions?.target;
if(options.runtime !== 'node'){
if (options.runtime !== 'node') {
throw new Error(`(buildExecutableNodeJs) Unsupported runtime: ${options.runtime}`);
}
const nodeVersion = options.buildOptions?.nodeToolChain?.version;
if(nodeVersion !== 18){
throw new Error(`(buildExecutableNodeJs) Only support node.js version 18 due to minimum version of Nammatham Framework.`);
if (nodeVersion !== 18) {
throw new Error(
`(buildExecutableNodeJs) Only support node.js version 18 due to minimum version of Nammatham Framework.`
);
}
const runtime = options.runtime + nodeVersion;
if (!target) {
Expand Down
2 changes: 1 addition & 1 deletion packages/main/src/command/build/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export interface BuildOptions {
* Disable the build process. This is useful when you want to disable the build process for a specific environment.
* You need to manage the build process manually, however, the other Azure Functions configurations will be managed by the framework.
* For example, `function.json`, `local.settings.json`, and `host.json` will be managed by the framework.
*
*
* @default false
*/
disabled?: boolean;
Expand Down
25 changes: 7 additions & 18 deletions packages/main/src/command/cli.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { build } from './build';
import { writeConfig } from './dev';
import { createDebugger } from './utils';
import { loadEnvVariables } from './config';
import { loadConfigFromFile } from './config-loader';
import { loadEnvVariables, writeConfig } from './config';
import { startAzureFunctionHost } from './azure-func-host';

const debug = createDebugger('nammatham:cli');

export async function main() {
console.log(`Start the command`);
debug?.(`Working Directory: ${process.cwd()}`);

/**
* Remove the first two arguments which are the node binary and the script file
*
* TODO: Use a library like yargs or commander to parse the arguments
*/
const args = process.argv.slice(2);
console.log(`Args: ${args}`);
Expand All @@ -24,26 +26,13 @@ export async function main() {
const envVars = loadEnvVariables(config?.envVariablesConfig);
debug?.(`Loaded env variables: ${JSON.stringify(envVars)}`);

// debug?.(`Command: ${args[0]}`);
if (args[0] === 'dev') {
debug?.(`Starting dev server`);
await writeConfig(config, envVars);
/**
* setup host.json for dev
"watchDirectories": [
"../src", // Watch the source directory
"." // watch the function.json
]
"defaultExecutablePath": "../node_modules/.bin/tsx",
"arguments": [
"watch",
"../src/main.ts"
]
*/
debug?.(`Config written`);
await startAzureFunctionHost(config);
} else if (args[0] === 'build') {
console.log(`Build the code`);
await build(config);
}
console.log(`End the command`);
}
4 changes: 2 additions & 2 deletions packages/main/src/command/config-loader/types/host-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ export interface ExtensionBundle {
id?: string;
/**
* The version range of the bundle to install. The Functions runtime always picks the maximum permissible version defined by the version range or interval.
* For example, a version value range of `[4.0.0, 5.0.0)` allows all bundle versions from `4.0.0` up to but not including `5.0.0`. For more information,
* see the [interval notation for specifying version ranges](https://learn.microsoft.com/en-us/nuget/reference/package-versioning#version-ranges).
* For example, a version value range of `[4.0.0, 5.0.0)` allows all bundle versions from `4.0.0` up to but not including `5.0.0`. For more information,
* see the [interval notation for specifying version ranges](https://learn.microsoft.com/en-us/nuget/reference/package-versioning#version-ranges).
*
* The following table lists the currently available version ranges of the default `Microsoft.Azure.Functions.ExtensionBundle` bundles and links to the extensions they include.
*
Expand Down
46 changes: 0 additions & 46 deletions packages/main/src/command/config/config-writer.ts

This file was deleted.

47 changes: 47 additions & 0 deletions packages/main/src/command/config/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type { EnvVariables } from './load-env-vars';
import type { HostConfigV2, LocalSettings, NammathamConfigs } from '../config-loader';

import { getExecutablePath } from '../build';

export function constructHostConfig(config: NammathamConfigs, mode: 'dev' | 'build'): string {
let description: NonNullable<HostConfigV2['customHandler']>['description'] = {};
let watchDirectories: HostConfigV2['watchDirectories'];
if (mode === 'build') {
description = {
defaultExecutablePath: getExecutablePath(config.buildOptions?.target),
};
} else if (mode === 'dev') {
description = {
defaultExecutablePath: '../node_modules/.bin/tsx',
arguments: ['watch', '../src/main.ts'],
};
watchDirectories = ['../src', '.'];
}
return JSON.stringify(
{
customHandler: {
description,
enableForwardingHttpRequest: true,
},
watchDirectories,
...config.hostConfig,
} as HostConfigV2,
null,
2
);
}

export function constructLocalSettings(envVars?: EnvVariables): string {
return JSON.stringify(
{
IsEncrypted: false,
Values: {
...envVars,
FUNCTIONS_WORKER_RUNTIME: 'custom',
AzureWebJobsStorage: envVars?.AzureWebJobsStorage ?? 'UseDevelopmentStorage=true',
},
} satisfies LocalSettings,
null,
2
);
}
2 changes: 1 addition & 1 deletion packages/main/src/command/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from './load-env-vars';
export * from './config-writer';
export * from './config';
2 changes: 1 addition & 1 deletion packages/main/src/command/config/load-env-vars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import 'dotenv/config';

export type EnvVariables = Record<string, string | undefined>;

const debug = createDebugger('nammatham:config');
export const debug = createDebugger('nammatham:config');

export function loadUserDefinedEnvVariables(): EnvVariables {
for (const envFile of DEFAULT_ENV_FILEs) {
Expand Down
25 changes: 25 additions & 0 deletions packages/main/src/command/dev/dev.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import fs from 'node:fs';
import path from 'node:path';

import type { EnvVariables } from '../config';
import type { NammathamConfigs } from '../config-loader';

import { createDebugger } from '../utils';
import { constructHostConfig, constructLocalSettings } from '../config';

const debug = createDebugger('nammatham:dev');

export async function writeConfig(config: NammathamConfigs, envVars: EnvVariables, tmpPath = '') {
fs.mkdirSync(path.resolve(config.buildPath ?? './nmt', tmpPath), { recursive: true });
const targetPath = path.resolve(config.buildPath ?? './nmt', tmpPath);
const result = await Promise.allSettled([
fs.promises.writeFile(path.join(targetPath, 'host.json'), constructHostConfig(config, 'dev'), 'utf-8'),
fs.promises.writeFile(path.join(targetPath, 'local.settings.json'), constructLocalSettings(envVars), 'utf-8'),
]);
result.forEach((r) => {
if (r.status === 'rejected') {
throw new Error(r.reason);
}
});

}
1 change: 1 addition & 0 deletions packages/main/src/command/dev/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './dev';
1 change: 1 addition & 0 deletions packages/main/src/command/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './config-loader';
export * from './build';
export * from './dev';

0 comments on commit a1fc496

Please sign in to comment.