Skip to content

Commit 930c2a8

Browse files
author
Heiner Pöpping
committed
Merge branch 'feature/internal'
2 parents 31ce160 + 896664f commit 930c2a8

File tree

25 files changed

+444
-41
lines changed

25 files changed

+444
-41
lines changed

package-lock.json

Lines changed: 8 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "create-chayns-app",
3-
"version": "1.2.0-beta.0",
3+
"version": "1.2.0-beta.6",
44
"private": false,
55
"description": "Create a new chayns® development project in one command.",
66
"keywords": [
@@ -55,6 +55,7 @@
5555
"ora": "^8.1.1",
5656
"prettier": "^3.4.2",
5757
"prettier-plugin-packagejson": "^2.5.8",
58+
"semver": "^7.7.1",
5859
"validate-npm-package-name": "^6.0.0"
5960
},
6061
"publishConfig": {

src/constants/dependencies.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,8 @@ export const testDevDeps = {
4545
jsdom: 'latest',
4646
vitest: 'latest',
4747
};
48+
49+
export const internalDeps = {
50+
'chayns-logger': 'latest',
51+
'tobit-textstrings': 'latest',
52+
};

src/index.js

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import copyTemplate from './util/copyTemplate.js';
1616
import mapReplace from './util/mapReplace.js';
1717
import { createPackageJson } from './util/packageJson.js';
1818
import toCapitalizedWords from './util/toCapitalizedWords.js';
19+
import { createAppWrapper } from './util/createAppWrapper.js';
1920

2021
const { prompt } = Enquirer;
2122
const program = new Command();
@@ -27,17 +28,29 @@ program
2728
.option('-C, --no-initial-commit', "don't perform an initial commit")
2829
.option('-I, --no-install', "don't install packages after initialization")
2930
.option('-M, --module-federation', 'install to use as module (only internal)')
31+
.option('-T, --tobit-internal', 'includes tobit internal packages (chayns-logger and tobit-textstrings)')
3032
.option(
3133
'-p, --package-manager <manager>',
3234
'specify the package manager to use (`npm` or `yarn`). Defaults to the one used to execute the command.',
3335
)
3436
.action(createChaynsApp)
3537
.parse(process.argv);
3638

37-
async function createChaynsApp({ git, initialCommit, install, packageManager, moduleFederation }) {
39+
async function createChaynsApp({ git, initialCommit, install, packageManager, moduleFederation, tobitInternal }) {
3840
let projectVersion;
3941
let projectType;
4042

43+
if (tobitInternal) {
44+
try {
45+
const res = await fetch(`https://repo.tobit.ag`, { method: 'HEAD', signal: AbortSignal.timeout(3000) });
46+
if (!res.ok) {
47+
tobitInternal = false;
48+
}
49+
} catch {
50+
tobitInternal = false;
51+
}
52+
}
53+
4154
if (!moduleFederation) {
4255
({ projectVersion } = await prompt({
4356
type: 'select',
@@ -96,6 +109,7 @@ async function createChaynsApp({ git, initialCommit, install, packageManager, mo
96109
'install-command': usedPackageManager === 'yarn' ? 'yarn' : 'npm install',
97110
'run-command': usedPackageManager === 'yarn' ? 'yarn' : 'npm run',
98111
'package-name-underscore': projectName.replace('-', '_'),
112+
'logger-import': tobitInternal ? `import './utils/logger';\n` : '',
99113
});
100114
}
101115

@@ -223,6 +237,14 @@ async function createChaynsApp({ git, initialCommit, install, packageManager, mo
223237
getTemplatePath(`../templates/api-v5/shared/ts/.eslintrc`),
224238
path.join(destination, '.eslintrc'),
225239
);
240+
if (tobitInternal) {
241+
const templateInternalPath = `../templates/api-v5/internal/${extension}/src`;
242+
await copyTemplate({
243+
destination: destination + '/src',
244+
projectName,
245+
templateDir: path.join(` ${dirname} `.trim(), templateInternalPath),
246+
});
247+
}
226248
}
227249

228250
// Main template
@@ -244,6 +266,7 @@ async function createChaynsApp({ git, initialCommit, install, packageManager, mo
244266
useRedux,
245267
useTypescript,
246268
useVitest,
269+
tobitInternal,
247270
});
248271

249272
// copy README
@@ -275,9 +298,9 @@ async function createChaynsApp({ git, initialCommit, install, packageManager, mo
275298

276299
await copyFile(
277300
getTemplatePath(
278-
`../templates/api-v5/shared/${extension}/src/constants/server-urls.${extension}`,
301+
`../templates/api-v5/shared/${extension}/src/constants/serverUrls.${extension}`,
279302
),
280-
path.join(destination, `/src/constants/server-urls.${extension}`),
303+
path.join(destination, `/src/constants/serverUrls.${extension}`),
281304
);
282305

283306
// copy tsconfig.json
@@ -314,6 +337,28 @@ async function createChaynsApp({ git, initialCommit, install, packageManager, mo
314337
);
315338
}
316339

340+
if (tobitInternal) {
341+
if (!fs.existsSync(path.join(destination, '/src/utils'))) {
342+
fs.mkdirSync(path.join(destination, '/src/utils'));
343+
}
344+
await copyFile(
345+
getTemplatePath(`../templates/api-v5/internal/${extension}/src/utils/logger.${extension}`),
346+
path.join(destination, `/src/utils/logger.${extension}`),
347+
);
348+
349+
const filePath = path.join(destination, `/src/components/AppWrapper.${extension}x`);
350+
fs.writeFileSync(filePath, createAppWrapper({
351+
useRedux,
352+
useTypescript,
353+
moduleFederation,
354+
tobitInternal,
355+
packageNameUnderscore: projectName.replace('-', '_'),
356+
}));
357+
358+
const npmrcPath = path.join(destination, '.npmrc');
359+
fs.writeFileSync(npmrcPath, 'registry=https://repo.tobit.ag/repository/npm/\n');
360+
}
361+
317362
const fileDestination = path.join(destination, 'toolkit.config.js');
318363
if (moduleFederation) {
319364
const toolkitFileName = `toolkit.config-module.js`;
@@ -380,9 +425,20 @@ async function createChaynsApp({ git, initialCommit, install, packageManager, mo
380425

381426
const runCommand = usedPackageManager === 'yarn' ? 'yarn dev' : 'npm run dev';
382427

383-
console.log(
384-
`Open the created ${chalk.yellowBright(
385-
`./${projectName}/`,
386-
)} folder in your favorite editor and start ${chalk.cyanBright('`' + runCommand + '`')}.\n`,
387-
);
428+
if (tobitInternal) {
429+
console.log(
430+
`Open the created ${chalk.yellowBright(
431+
`./${projectName}/`,
432+
)} folder in your favorite editor.`,
433+
);
434+
console.log(`Initialize ${chalk.yellowBright('tobit-textstrings')} by calling ${chalk.cyanBright('npx tobit-textstrings init')}.`)
435+
console.log(`Search for ${chalk.greenBright('TODO:')} and follow the instructions.`);
436+
console.log(`Start ${chalk.cyanBright('`' + runCommand + '`')}.\n`);
437+
} else {
438+
console.log(
439+
`Open the created ${chalk.yellowBright(
440+
`./${projectName}/`,
441+
)} folder in your favorite editor and start ${chalk.cyanBright('`' + runCommand + '`')}.\n`,
442+
);
443+
}
388444
}

src/util/copyTemplate.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ export default async function copyTemplate({ destination, templateDir, adjustCon
1515
}
1616

1717
const realFileName = filename
18-
.replace('template-gitignore', '.gitignore')
19-
.replace('template-package-redux.json', 'package.json')
20-
.replace('template-package.json', 'package.json');
18+
.replace('template-gitignore', '.gitignore');
2119

2220
const fileDestination = path.join(destination, realFileName);
2321

src/util/createAppWrapper.js

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
2+
export const createAppWrapper = ({ useTypescript, moduleFederation, useRedux, tobitInternal, packageNameUnderscore }) => {
3+
const lines = [];
4+
let indent = 0;
5+
6+
const reactNamedImportsList = [];
7+
if (moduleFederation && useTypescript) {
8+
reactNamedImportsList.push('ComponentPropsWithoutRef');
9+
}
10+
if (tobitInternal) {
11+
reactNamedImportsList.push('Suspense');
12+
}
13+
if (moduleFederation && useRedux) {
14+
reactNamedImportsList.push('useState');
15+
}
16+
const reactNamedImports = reactNamedImportsList.length ? `, { ${reactNamedImportsList.join(', ')} }` : '';
17+
18+
lines.push(`import React${reactNamedImports} from 'react';`);
19+
20+
if (useRedux) {
21+
lines.push(`import { Provider } from 'react-redux';`);
22+
}
23+
24+
lines.push(`import { ChaynsProvider${moduleFederation ? ', withCompatMode' : ''} } from 'chayns-api';`)
25+
lines.push(`import { PageProvider } from '@chayns-components/core';`);
26+
if (tobitInternal) {
27+
lines.push(`import { TextStringProvider } from 'tobit-textstrings';`);
28+
}
29+
lines.push(`import App from './App';`)
30+
if (useRedux) {
31+
lines.push(`import ${moduleFederation ? '{ createStore }' : 'store'} from '../redux-modules';`);
32+
}
33+
if (tobitInternal && moduleFederation) {
34+
lines.push(`import '../utils/logger';`);
35+
}
36+
lines.push('');
37+
if (tobitInternal) {
38+
lines.push('// TODO: insert your libraryName');
39+
lines.push(`const libraries = ['<libraryName>'];`);
40+
lines.push('');
41+
}
42+
43+
if (moduleFederation && useRedux) {
44+
lines.push(`const AppWrapper = (${moduleFederation ? 'props' : ''}${moduleFederation && useTypescript ? ': ComponentPropsWithoutRef<typeof ChaynsProvider>' : ''}) => {`);
45+
indent += 4;
46+
lines.push(`${' '.repeat(indent)}const [store] = useState(createStore);`);
47+
lines.push('');
48+
lines.push(`${' '.repeat(indent)}return (`);
49+
} else {
50+
lines.push(`const AppWrapper = (${moduleFederation ? 'props' : ''}${moduleFederation && useTypescript ? ': ComponentPropsWithoutRef<typeof ChaynsProvider>' : ''}) => (`);
51+
}
52+
indent += 4;
53+
54+
if (moduleFederation) {
55+
lines.push(`${' '.repeat(indent)}<div className="${packageNameUnderscore}">`);
56+
indent += 4;
57+
lines.push(`${' '.repeat(indent)}{/* eslint-disable-next-line react/jsx-props-no-spreading */}`);
58+
}
59+
60+
lines.push(`${' '.repeat(indent)}<ChaynsProvider${moduleFederation ? ' {...props}' : ''}>`);
61+
indent += 4;
62+
63+
if (useRedux) {
64+
lines.push(`${' '.repeat(indent)}<Provider store={store}>`);
65+
indent += 4;
66+
}
67+
68+
lines.push(`${' '.repeat(indent)}<PageProvider>`);
69+
indent += 4;
70+
71+
if (tobitInternal) {
72+
lines.push(`${' '.repeat(indent)}<Suspense>`);
73+
indent += 4;
74+
lines.push(`${' '.repeat(indent)}<TextStringProvider libraries={libraries}>`);
75+
indent += 4;
76+
}
77+
78+
lines.push(`${' '.repeat(indent)}<App />`);
79+
80+
if (tobitInternal) {
81+
indent -= 4;
82+
lines.push(`${' '.repeat(indent)}</TextStringProvider>`);
83+
indent -= 4;
84+
lines.push(`${' '.repeat(indent)}</Suspense>`);
85+
}
86+
87+
indent -= 4;
88+
lines.push(`${' '.repeat(indent)}</PageProvider>`);
89+
90+
if (useRedux) {
91+
indent -= 4;
92+
lines.push(`${' '.repeat(indent)}</Provider>`);
93+
}
94+
95+
indent -= 4;
96+
lines.push(`${' '.repeat(indent)}</ChaynsProvider>`);
97+
98+
if (moduleFederation) {
99+
indent -= 4;
100+
lines.push(`${' '.repeat(indent)}</div>`);
101+
}
102+
103+
if (moduleFederation && useRedux) {
104+
indent -= 4;
105+
lines.push(`${' '.repeat(indent)});`);
106+
lines.push('};');
107+
} else {
108+
lines.push(');');
109+
}
110+
111+
lines.push('');
112+
if (moduleFederation) {
113+
lines.push('export default withCompatMode(AppWrapper);')
114+
} else {
115+
lines.push('export default AppWrapper;');
116+
}
117+
lines.push('');
118+
119+
return lines.join('\n');
120+
}

src/util/packageJson.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
getV5Deps,
77
v5DevDeps,
88
testDevDeps,
9+
internalDeps,
910
} from '../constants/dependencies.js';
1011
import { ProjectVersions } from '../constants/projectTypes.js';
1112
import { resolvePackageVersion } from './resolvePackageVersion.js';
@@ -73,6 +74,7 @@ export const createPackageJson = async ({
7374
projectVersion,
7475
reactVersion,
7576
useRedux,
77+
tobitInternal,
7678
...options
7779
}) => {
7880
const { useTypescript, useVitest } = options;
@@ -97,6 +99,9 @@ export const createPackageJson = async ({
9799
if (useVitest) {
98100
Object.assign(devDependencies, testDevDeps);
99101
}
102+
if (tobitInternal) {
103+
Object.assign(dependencies, internalDeps);
104+
}
100105
content = await buildPackageJson({ ...options, dependencies, devDependencies });
101106
}
102107
spinner.succeed('Resolved latest versions of required dependencies');

0 commit comments

Comments
 (0)