create-medplum 0.0.1 → 3.2.28
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 +16 -2
- package/dist/esm/index.mjs +38 -33
- package/dist/esm/index.mjs.map +2 -2
- package/dist/types/main.d.ts +1 -1
- package/dist/types/main.d.ts.map +1 -1
- package/dist/types/main.test.d.ts +3 -0
- package/dist/types/main.test.d.ts.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
# Medplum NPM Initializer
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This package is an NPM initializer for creating a new Medplum project.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm init medplum
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The user will be prompted for the following information:
|
|
12
|
+
|
|
13
|
+
1. Which Medplum starter template to use
|
|
14
|
+
2. The name of the project
|
|
15
|
+
3. The Medplum base URL
|
|
16
|
+
|
|
17
|
+
Learn more about NPM initializers: https://docs.npmjs.com/cli/v11/commands/npm-init
|
|
4
18
|
|
|
5
19
|
## About Medplum
|
|
6
20
|
|
|
@@ -8,4 +22,4 @@ Medplum is a healthcare platform that helps you quickly develop high-quality com
|
|
|
8
22
|
|
|
9
23
|
## License
|
|
10
24
|
|
|
11
|
-
Apache 2.0. Copyright © Medplum
|
|
25
|
+
Apache 2.0. Copyright © Medplum 2025
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1,26 +1,31 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/main.ts
|
|
4
|
-
import
|
|
5
|
-
import
|
|
4
|
+
import cp from "node:child_process";
|
|
5
|
+
import fs from "node:fs";
|
|
6
6
|
import path from "node:path";
|
|
7
|
-
import
|
|
7
|
+
import readline from "node:readline/promises";
|
|
8
8
|
var STARTER_PROJECTS = [
|
|
9
9
|
{
|
|
10
10
|
id: "medplum-hello-world",
|
|
11
11
|
name: "Hello World",
|
|
12
12
|
description: "Minimal starter application showing basic Medplum integration"
|
|
13
13
|
},
|
|
14
|
+
{
|
|
15
|
+
id: "foomedical",
|
|
16
|
+
name: "Foo Medical",
|
|
17
|
+
description: "Full featured patient portal with open registration"
|
|
18
|
+
},
|
|
14
19
|
{
|
|
15
20
|
id: "medplum-provider",
|
|
16
|
-
name: "
|
|
21
|
+
name: "Provider",
|
|
17
22
|
description: "Simple EHR application with patient and encounter management"
|
|
18
23
|
}
|
|
19
24
|
];
|
|
20
|
-
async function prompt(
|
|
25
|
+
async function prompt(terminal, question, defaultValue, validationFunc, validationMessage) {
|
|
21
26
|
while (true) {
|
|
22
27
|
const defaultPrompt = defaultValue ? ` (${defaultValue})` : "";
|
|
23
|
-
const answer = await
|
|
28
|
+
const answer = await terminal.question(`${question}${defaultPrompt}: `) || defaultValue;
|
|
24
29
|
if (validationFunc(answer)) {
|
|
25
30
|
return answer;
|
|
26
31
|
}
|
|
@@ -28,7 +33,7 @@ async function prompt(readline, question, defaultValue, validationFunc, validati
|
|
|
28
33
|
}
|
|
29
34
|
}
|
|
30
35
|
async function promptForConfig() {
|
|
31
|
-
const
|
|
36
|
+
const terminal = readline.createInterface({
|
|
32
37
|
input: process.stdin,
|
|
33
38
|
output: process.stdout
|
|
34
39
|
});
|
|
@@ -37,80 +42,80 @@ async function promptForConfig() {
|
|
|
37
42
|
console.log(`${i + 1}) ${STARTER_PROJECTS[i].name} - ${STARTER_PROJECTS[i].description}`);
|
|
38
43
|
}
|
|
39
44
|
const answer = await prompt(
|
|
40
|
-
|
|
45
|
+
terminal,
|
|
41
46
|
"Enter number",
|
|
42
47
|
"1",
|
|
43
48
|
(str) => {
|
|
44
49
|
const num = parseInt(str, 10);
|
|
45
50
|
return num >= 1 && num <= STARTER_PROJECTS.length;
|
|
46
51
|
},
|
|
47
|
-
"Please enter a number between 1 and
|
|
52
|
+
"Please enter a number between 1 and " + STARTER_PROJECTS.length
|
|
48
53
|
);
|
|
49
54
|
const starterProject = STARTER_PROJECTS[parseInt(answer, 10) - 1];
|
|
50
55
|
const projectName = await prompt(
|
|
51
|
-
|
|
56
|
+
terminal,
|
|
52
57
|
"What is your project name?",
|
|
53
58
|
starterProject.id,
|
|
54
59
|
(name) => name && /^[a-zA-Z0-9-_]+$/.test(name),
|
|
55
60
|
"Project name may only include letters, numbers, dashes, and underscores"
|
|
56
61
|
);
|
|
57
62
|
const serverUrl = await prompt(
|
|
58
|
-
|
|
63
|
+
terminal,
|
|
59
64
|
"What is your Medplum server URL?",
|
|
60
65
|
"https://api.medplum.com/",
|
|
61
66
|
(url) => URL.canParse(url),
|
|
62
67
|
"Please enter a valid URL"
|
|
63
68
|
);
|
|
64
|
-
|
|
69
|
+
terminal.close();
|
|
65
70
|
return { starterProject, projectName, serverUrl };
|
|
66
71
|
}
|
|
67
72
|
async function initializeProject(config) {
|
|
68
73
|
const projectDir = path.join(process.cwd(), config.projectName);
|
|
69
74
|
try {
|
|
70
75
|
console.log("Cloning starter project...");
|
|
71
|
-
execSync(`git clone git@github.com:medplum/${config.starterProject.id} ${config.projectName}`, {
|
|
76
|
+
cp.execSync(`git clone git@github.com:medplum/${config.starterProject.id} ${config.projectName}`, {
|
|
72
77
|
stdio: "inherit"
|
|
73
78
|
});
|
|
74
|
-
rmSync(path.join(projectDir, ".git"), { recursive: true, force: true });
|
|
79
|
+
fs.rmSync(path.join(projectDir, ".git"), { recursive: true, force: true });
|
|
75
80
|
const configPath = path.join(projectDir, "src", "config.ts");
|
|
76
|
-
if (existsSync(configPath)) {
|
|
77
|
-
let configContent = readFileSync(configPath, "utf8");
|
|
81
|
+
if (fs.existsSync(configPath)) {
|
|
82
|
+
let configContent = fs.readFileSync(configPath, "utf8");
|
|
78
83
|
configContent = configContent.replace(/baseUrl:.*$/m, `baseUrl: '${config.serverUrl}',`);
|
|
79
|
-
writeFileSync(configPath, configContent);
|
|
84
|
+
fs.writeFileSync(configPath, configContent);
|
|
80
85
|
}
|
|
81
86
|
console.log("Initializing new git repository...");
|
|
82
|
-
execSync("git init", { cwd: projectDir, stdio: "inherit" });
|
|
83
|
-
execSync("git add .", { cwd: projectDir, stdio: "inherit" });
|
|
84
|
-
execSync('git commit -m "Initial commit from Medplum initializer"', {
|
|
87
|
+
cp.execSync("git init", { cwd: projectDir, stdio: "inherit" });
|
|
88
|
+
cp.execSync("git add .", { cwd: projectDir, stdio: "inherit" });
|
|
89
|
+
cp.execSync('git commit -m "Initial commit from Medplum initializer"', {
|
|
85
90
|
cwd: projectDir,
|
|
86
91
|
stdio: "inherit"
|
|
87
92
|
});
|
|
88
93
|
console.log("Installing dependencies...");
|
|
89
|
-
execSync("npm install", { cwd: projectDir, stdio: "inherit" });
|
|
94
|
+
cp.execSync("npm install", { cwd: projectDir, stdio: "inherit" });
|
|
90
95
|
console.log(`Successfully created project ${config.projectName}!`);
|
|
91
96
|
console.log(`Next steps:`);
|
|
92
97
|
console.log(` cd ${config.projectName}`);
|
|
93
98
|
console.log(" npm start");
|
|
94
99
|
} catch (error) {
|
|
95
100
|
console.error("Error initializing project:", error);
|
|
96
|
-
if (existsSync(projectDir)) {
|
|
97
|
-
rmSync(projectDir, { recursive: true, force: true });
|
|
101
|
+
if (fs.existsSync(projectDir)) {
|
|
102
|
+
fs.rmSync(projectDir, { recursive: true, force: true });
|
|
98
103
|
}
|
|
99
104
|
throw error;
|
|
100
105
|
}
|
|
101
106
|
}
|
|
102
107
|
async function main() {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
+
console.log("Welcome to Medplum project initializer!");
|
|
109
|
+
const config = await promptForConfig();
|
|
110
|
+
await initializeProject(config);
|
|
111
|
+
}
|
|
112
|
+
if (process.env.NODE_ENV !== "test") {
|
|
113
|
+
main().catch((error) => {
|
|
108
114
|
console.error("Unexpected error:", error);
|
|
109
115
|
process.exit(1);
|
|
110
|
-
}
|
|
116
|
+
});
|
|
111
117
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
});
|
|
118
|
+
export {
|
|
119
|
+
main
|
|
120
|
+
};
|
|
116
121
|
//# sourceMappingURL=index.mjs.map
|
package/dist/esm/index.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/main.ts"],
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n\nimport
|
|
5
|
-
"mappings": ";;;AAEA,
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n\nimport cp from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport readline from 'node:readline/promises';\n\ninterface StarterProject {\n id: string;\n name: string;\n description: string;\n}\n\ninterface ProjectConfig {\n starterProject: StarterProject;\n projectName: string;\n serverUrl: string;\n}\n\nconst STARTER_PROJECTS: StarterProject[] = [\n {\n id: 'medplum-hello-world',\n name: 'Hello World',\n description: 'Minimal starter application showing basic Medplum integration',\n },\n {\n id: 'foomedical',\n name: 'Foo Medical',\n description: 'Full featured patient portal with open registration',\n },\n {\n id: 'medplum-provider',\n name: 'Provider',\n description: 'Simple EHR application with patient and encounter management',\n },\n];\n\nasync function prompt(\n terminal: readline.Interface,\n question: string,\n defaultValue: string,\n validationFunc: (str: string) => boolean | string,\n validationMessage: string\n): Promise<string> {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const defaultPrompt = defaultValue ? ` (${defaultValue})` : '';\n const answer = (await terminal.question(`${question}${defaultPrompt}: `)) || defaultValue;\n if (validationFunc(answer)) {\n return answer;\n }\n console.log(validationMessage);\n }\n}\n\nasync function promptForConfig(): Promise<ProjectConfig> {\n const terminal = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n // Display the list of starter projects\n console.log('Which starter project would you like to use?');\n for (let i = 0; i < STARTER_PROJECTS.length; i++) {\n console.log(`${i + 1}) ${STARTER_PROJECTS[i].name} - ${STARTER_PROJECTS[i].description}`);\n }\n\n // Prompt the user to select a project\n const answer = await prompt(\n terminal,\n 'Enter number',\n '1',\n (str) => {\n const num = parseInt(str, 10);\n return num >= 1 && num <= STARTER_PROJECTS.length;\n },\n 'Please enter a number between 1 and ' + STARTER_PROJECTS.length\n );\n const starterProject = STARTER_PROJECTS[parseInt(answer, 10) - 1];\n\n // Prompt the user for the project name\n const projectName = await prompt(\n terminal,\n 'What is your project name?',\n starterProject.id,\n (name) => name && /^[a-zA-Z0-9-_]+$/.test(name),\n 'Project name may only include letters, numbers, dashes, and underscores'\n );\n\n // Prompt the user for the server URL\n const serverUrl = await prompt(\n terminal,\n 'What is your Medplum server URL?',\n 'https://api.medplum.com/',\n (url) => URL.canParse(url),\n 'Please enter a valid URL'\n );\n\n // Cleanup\n terminal.close();\n\n return { starterProject, projectName, serverUrl };\n}\n\nasync function initializeProject(config: ProjectConfig): Promise<void> {\n const projectDir = path.join(process.cwd(), config.projectName);\n\n try {\n // Clone the repository\n console.log('Cloning starter project...');\n cp.execSync(`git clone git@github.com:medplum/${config.starterProject.id} ${config.projectName}`, {\n stdio: 'inherit',\n });\n\n // Remove .git directory\n fs.rmSync(path.join(projectDir, '.git'), { recursive: true, force: true });\n\n // Update configuration\n const configPath = path.join(projectDir, 'src', 'config.ts');\n if (fs.existsSync(configPath)) {\n let configContent = fs.readFileSync(configPath, 'utf8');\n configContent = configContent.replace(/baseUrl:.*$/m, `baseUrl: '${config.serverUrl}',`);\n fs.writeFileSync(configPath, configContent);\n }\n\n // Initialize new git repository\n console.log('Initializing new git repository...');\n cp.execSync('git init', { cwd: projectDir, stdio: 'inherit' });\n cp.execSync('git add .', { cwd: projectDir, stdio: 'inherit' });\n cp.execSync('git commit -m \"Initial commit from Medplum initializer\"', {\n cwd: projectDir,\n stdio: 'inherit',\n });\n\n // Install dependencies\n console.log('Installing dependencies...');\n cp.execSync('npm install', { cwd: projectDir, stdio: 'inherit' });\n\n console.log(`Successfully created project ${config.projectName}!`);\n console.log(`Next steps:`);\n console.log(` cd ${config.projectName}`);\n console.log(' npm start');\n } catch (error) {\n console.error('Error initializing project:', error);\n // Clean up on failure\n if (fs.existsSync(projectDir)) {\n fs.rmSync(projectDir, { recursive: true, force: true });\n }\n throw error;\n }\n}\n\nexport async function main(): Promise<void> {\n console.log('Welcome to Medplum project initializer!');\n const config = await promptForConfig();\n await initializeProject(config);\n}\n\nif (process.env.NODE_ENV !== 'test') {\n main().catch((error) => {\n console.error('Unexpected error:', error);\n process.exit(1);\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/types/main.d.ts
CHANGED
package/dist/types/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":";AAwJA,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAI1C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.test.d.ts","sourceRoot":"","sources":["../../src/main.test.ts"],"names":[],"mappings":"AAEA,OAAO,QAAQ,MAAM,wBAAwB,CAAC;AA+D9C,wBAAgB,YAAY,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC,SAAS,CAYrE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-medplum",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.2.28",
|
|
4
4
|
"description": "Medplum NPM Initializer",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"medplum",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"test": "jest"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@types/node": "22.10.
|
|
46
|
+
"@types/node": "22.10.6"
|
|
47
47
|
},
|
|
48
48
|
"engines": {
|
|
49
49
|
"node": ">=18.0.0"
|