Skip to content

Commit 8bcb462

Browse files
Project create now supports typescript in nodejs (#247)
This is a more realistic way to support typescript than using a specialized typescript library. Version now 4.2.3,
1 parent 326d45c commit 8bcb462

File tree

3 files changed

+83
-32
lines changed

3 files changed

+83
-32
lines changed

package-lock.json

+9-9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nimbella/nimbella-cli",
3-
"version": "4.2.2",
3+
"version": "4.2.3",
44
"description": "A comprehensive CLI for the Nimbella stack",
55
"main": "lib/index.js",
66
"repository": {
@@ -17,7 +17,7 @@
1717
"@adobe/aio-cli-plugin-runtime": "github:nimbella/aio-cli-plugin-runtime#v2021-11-19-1",
1818
"@adobe/aio-lib-core-config": "^2.0.0",
1919
"@adobe/aio-lib-runtime": "^3.3.0",
20-
"@nimbella/nimbella-deployer": "4.3.4",
20+
"@nimbella/nimbella-deployer": "4.3.5",
2121
"@nimbella/storage": "^0.0.7",
2222
"@oclif/command": "^1",
2323
"@oclif/config": "^1",

src/generator/project.ts

+72-21
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,45 @@ const gitignores = `.nimbella
3131
__deployer__.zip
3232
__pycache__/
3333
node_modules
34+
package-lock.json
3435
.DS_Store
3536
`
3637

38+
const ignoreForTypescript = 'lib/\n'
39+
40+
// A canned package.json for a minimal typescript project
41+
const packageJsonForTypescript = `{
42+
"main": "lib/hello.js",
43+
"devDependencies": {
44+
"typescript": "^4"
45+
},
46+
"scripts": {
47+
"build": "tsc -b"
48+
}
49+
}
50+
`
51+
52+
// A canned tsconfig.json for typescript project
53+
const tsconfigJSON = `{
54+
"compilerOptions": {
55+
"baseUrl": ".",
56+
"esModuleInterop": true,
57+
"importHelpers": true,
58+
"module": "commonjs",
59+
"outDir": "lib",
60+
"rootDir": "src",
61+
"target": "es2019"
62+
},
63+
"include": [
64+
"src/**/*"
65+
]
66+
}
67+
`
68+
3769
// Working function used by project create
3870
export async function createProject(project: string, flags: any, logger: any): Promise<void> {
3971
const { overwrite, language } = flags
40-
const { kind, sampleText } = languageToKindAndSample(language, logger)
72+
const { kind, sampleText, ts } = languageToKindAndSample(language, logger)
4173
const validKind = await isKindAValidRuntime(kind)
4274
if (!validKind) {
4375
logger.handleError(`${language} is not a supported language`)
@@ -54,15 +86,23 @@ export async function createProject(project: string, flags: any, logger: any): P
5486
}
5587
}
5688
createProjectPackage(samplePackage)
57-
if (kind) {
58-
generateSample(kind, projectConfig, sampleText, samplePackage)
59-
}
89+
const actionDir = generateSample(kind, projectConfig, sampleText, samplePackage, ts)
6090
// Write the config.
6191
renameActionsToFunctions(projectConfig)
6292
const data = yaml.safeDump(projectConfig)
6393
fs.writeFileSync(configFile, data)
6494
// Add the .gitignore
65-
fs.writeFileSync(gitignoreFile, gitignores)
95+
const ignores = gitignores + (ts ? ignoreForTypescript : '')
96+
fs.writeFileSync(gitignoreFile, ignores)
97+
// Add typescript-specific information
98+
if (ts) {
99+
const pjFile = path.join(actionDir, 'package.json')
100+
fs.writeFileSync(pjFile, packageJsonForTypescript)
101+
const tscFile = path.join(actionDir, 'tsconfig.json')
102+
fs.writeFileSync(tscFile, tsconfigJSON)
103+
const includeFile = path.join(actionDir, '.include')
104+
fs.writeFileSync(includeFile, 'lib\n')
105+
}
66106
const msgs = [
67107
`A sample project called '${project}' was created for you.`,
68108
'You may deploy it by running the command shown on the next line:',
@@ -97,22 +137,29 @@ function configTemplate(): DeployStructure {
97137

98138
// Convert a user-specified language name to a runtime kind plus a sample.
99139
// Handle the error case of user requesting an unsupported language.
100-
function languageToKindAndSample(language: string, logger: any): { kind: string, sampleText: string } {
140+
function languageToKindAndSample(language: string, logger: any): { kind: string, sampleText: string, ts: boolean } {
101141
language = language.toLowerCase()
102142
if (!languages.includes(language)) {
103143
logger.handleError(`${language} is not a supported language`)
104144
}
105-
const kind = languageToKind(language)
106-
return { kind, sampleText: samples[language] }
145+
const { kind, ts } = languageToKind(language)
146+
return { kind, sampleText: samples[language], ts }
107147
}
108148

109149
// Generate a sample. The sample is called 'hello'.
110-
function generateSample(kind: string, config: DeployStructure, sampleText: string, samplePackage: string) {
150+
function generateSample(kind: string, config: DeployStructure, sampleText: string, samplePackage: string, ts: boolean): string {
111151
const [runtime] = kind.split(':')
112-
const suffix = fileExtensionForRuntime(runtime, false)
152+
const suffix = ts ? 'ts' : fileExtensionForRuntime(runtime, false)
113153
const actionDir = path.join(samplePackage, 'hello')
114154
fs.mkdirSync(actionDir, { recursive: true })
115-
const file = path.join(actionDir, `hello.${suffix}`)
155+
let file: string
156+
if (ts) {
157+
const srcDir = path.join(actionDir, 'src')
158+
fs.mkdirSync(srcDir)
159+
file = path.join(srcDir, `hello.${suffix}`)
160+
} else {
161+
file = path.join(actionDir, `hello.${suffix}`)
162+
}
116163
fs.writeFileSync(file, sampleText)
117164
const sampPkg = config.packages.find(pkg => pkg.name === 'sample')
118165
const action: ActionSpec = {
@@ -127,6 +174,7 @@ function generateSample(kind: string, config: DeployStructure, sampleText: strin
127174
limits: limitsFor(runtime)
128175
}
129176
sampPkg.actions.push(action)
177+
return actionDir
130178
}
131179

132180
// Set time limits based on the runtime. Most runtimes are fine with the default
@@ -142,30 +190,33 @@ function limitsFor(runtime: string): any {
142190

143191
function languageToKind(language: string) {
144192
let runtime = language
193+
let ts = false
145194
switch (language) {
195+
case 'ts':
196+
case 'typescript':
197+
ts = true
198+
runtime = 'nodejs'
199+
break
146200
case 'js':
147201
case 'javascript':
148202
runtime = 'nodejs'
149203
break
150-
case 'ts':
151-
runtime = 'typescript'
152-
break
153204
case 'py':
154205
runtime = 'python'
155206
break
156-
case 'rb':
157-
runtime = 'ruby'
158-
break
159-
case 'rs':
160-
runtime = 'rust'
161-
break
207+
// case 'rb':
208+
// runtime = 'ruby'
209+
// break
210+
// case 'rs':
211+
// runtime = 'rust'
212+
// break
162213
case 'golang':
163214
runtime = 'go'
164215
break
165216
default:
166217
break
167218
}
168-
return `${runtime}:default`
219+
return { kind: `${runtime}:default`, ts }
169220
}
170221

171222
// Test whether a path in the file system is a project based on some simple heuristics. The path is known to exist.

0 commit comments

Comments
 (0)