@common-stack/generate-plugin 6.0.8-alpha.5 → 6.0.8-alpha.50

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.
Files changed (85) hide show
  1. package/CHANGELOG.md +184 -4
  2. package/lib/common/package-releases/package.json +26 -0
  3. package/lib/common/package-releases/package.json.cjs +33 -0
  4. package/lib/common/package-releases/package.json.cjs.map +1 -0
  5. package/lib/common/package-releases/package.json.mjs +33 -0
  6. package/lib/common/package-releases/package.json.mjs.map +1 -0
  7. package/lib/generators/add-backend/files/Dockerfile +2 -0
  8. package/lib/generators/add-backend/files/package.json +4 -2
  9. package/lib/generators/add-backend/files/webpack.config.js +3 -1
  10. package/lib/generators/add-frontend/frameworks/antui/src/context.tsx.template +8 -0
  11. package/lib/generators/add-frontend/frameworks/antui/{entry.client.tsx.template → src/entry.client.tsx.template} +12 -12
  12. package/{src/generators/add-frontend/frameworks/antui → lib/generators/add-frontend/frameworks/antui/src}/entry.server.tsx.template +61 -51
  13. package/{src/generators/add-frontend/frameworks/antui → lib/generators/add-frontend/frameworks/antui/src}/root.tsx.template +6 -15
  14. package/lib/generators/add-frontend/frameworks/chakraui/{context.tsx.template → src/context.tsx.template} +6 -0
  15. package/lib/generators/add-frontend/frameworks/chakraui/{entry.client.tsx.template → src/entry.client.tsx.template} +21 -18
  16. package/{src/generators/add-frontend/frameworks/chakraui → lib/generators/add-frontend/frameworks/chakraui/src}/entry.server.tsx.template +33 -30
  17. package/lib/generators/add-frontend/frameworks/chakraui/{root.tsx.template → src/root.tsx.template} +8 -4
  18. package/{src/generators/add-frontend/frameworks/tailwindui → lib/generators/add-frontend/frameworks/tailwindui/src}/entry.client.tsx.template +3 -10
  19. package/lib/generators/add-frontend/generator.cjs +83 -36
  20. package/lib/generators/add-frontend/generator.cjs.map +1 -1
  21. package/lib/generators/add-frontend/generator.mjs +83 -36
  22. package/lib/generators/add-frontend/generator.mjs.map +1 -1
  23. package/lib/generators/add-frontend/templates/Dockerfile +4 -0
  24. package/lib/generators/add-frontend/templates/package.json +7 -3
  25. package/lib/generators/add-frontend/templates/vite.config.ts.template +18 -1
  26. package/lib/generators/add-fullstack/files/Jenkinsfile +2 -2
  27. package/lib/generators/add-fullstack/files/cdecode-config.json +126 -0
  28. package/lib/generators/add-fullstack/files/package.json +31 -18
  29. package/lib/generators/add-fullstack/files/rollup.config.base.mjs +17 -95
  30. package/lib/generators/add-fullstack/files/tools/codegenGenerator.mjs +36 -0
  31. package/lib/generators/add-fullstack/generator.cjs +8 -4
  32. package/lib/generators/add-fullstack/generator.cjs.map +1 -1
  33. package/lib/generators/add-fullstack/generator.mjs +8 -4
  34. package/lib/generators/add-fullstack/generator.mjs.map +1 -1
  35. package/lib/generators/add-fullstack/schema.json +1 -1
  36. package/lib/generators/add-moleculer/files/Dockerfile +2 -0
  37. package/lib/generators/add-moleculer/files/config.json +5 -0
  38. package/lib/generators/add-moleculer/files/package.json +10 -6
  39. package/lib/generators/add-moleculer/files/rollup.config.mjs +14 -1
  40. package/package.json +3 -3
  41. package/rollup.config.mjs +3 -0
  42. package/src/common/package-releases/package.json +26 -0
  43. package/src/generators/add-frontend/__snapshots__/generator.test.ts.snap +33 -0
  44. package/src/generators/add-frontend/frameworks/antui/src/context.tsx.template +8 -0
  45. package/src/generators/add-frontend/frameworks/antui/{entry.client.tsx.template → src/entry.client.tsx.template} +12 -12
  46. package/{lib/generators/add-frontend/frameworks/antui → src/generators/add-frontend/frameworks/antui/src}/entry.server.tsx.template +61 -51
  47. package/{lib/generators/add-frontend/frameworks/antui → src/generators/add-frontend/frameworks/antui/src}/root.tsx.template +6 -15
  48. package/src/generators/add-frontend/frameworks/chakraui/{context.tsx.template → src/context.tsx.template} +6 -0
  49. package/src/generators/add-frontend/frameworks/chakraui/{entry.client.tsx.template → src/entry.client.tsx.template} +21 -18
  50. package/{lib/generators/add-frontend/frameworks/chakraui → src/generators/add-frontend/frameworks/chakraui/src}/entry.server.tsx.template +33 -30
  51. package/src/generators/add-frontend/frameworks/chakraui/{root.tsx.template → src/root.tsx.template} +8 -4
  52. package/src/generators/add-frontend/frameworks/tailwindui/postcss.config.js +6 -0
  53. package/{lib/generators/add-frontend/frameworks/tailwindui → src/generators/add-frontend/frameworks/tailwindui/src}/entry.client.tsx.template +3 -10
  54. package/src/generators/add-frontend/frameworks/tailwindui/tailwind.config.ts.template +12 -0
  55. package/src/generators/add-frontend/generator.test.ts +79 -0
  56. package/src/generators/add-frontend/generator.ts +109 -44
  57. package/src/generators/add-fullstack/files/Jenkinsfile +2 -2
  58. package/src/generators/add-fullstack/files/cdecode-config.json +126 -0
  59. package/src/generators/add-fullstack/files/package.json +31 -18
  60. package/src/generators/add-fullstack/files/rollup.config.base.mjs +17 -95
  61. package/src/generators/add-fullstack/files/tools/codegenGenerator.mjs +36 -0
  62. package/src/generators/add-fullstack/generator.ts +8 -4
  63. package/src/generators/add-fullstack/schema.json +1 -1
  64. package/src/generators/add-moleculer/files/.dockerignore +2 -1
  65. package/src/generators/add-moleculer/files/Dockerfile +2 -0
  66. package/src/generators/add-moleculer/files/config.json +5 -0
  67. package/src/generators/add-moleculer/files/package.json +10 -6
  68. package/src/generators/add-moleculer/files/rollup.config.mjs +14 -1
  69. package/tsconfig.spec.json +9 -0
  70. package/docker-releases/backend/package.json +0 -134
  71. package/docker-releases/frontend/antd/package.json +0 -121
  72. package/lib/generators/add-fullstack/files/codegen.yml +0 -47
  73. package/lib/generators/add-moleculer/files/src/modules/module.ts.template +0 -31
  74. package/src/generators/add-frontend/generator.spec.ts +0 -20
  75. package/src/generators/add-fullstack/files/codegen.yml +0 -47
  76. package/src/generators/add-moleculer/files/src/modules/module.ts.template +0 -31
  77. /package/lib/generators/add-frontend/{templates → frameworks/tailwindui}/postcss.config.js +0 -0
  78. /package/lib/generators/add-frontend/frameworks/tailwindui/{entry.server.tsx.template → src/entry.server.tsx.template} +0 -0
  79. /package/lib/generators/add-frontend/frameworks/tailwindui/{root.tsx.template → src/root.tsx.template} +0 -0
  80. /package/lib/generators/add-frontend/frameworks/tailwindui/{tailwind.css → src/tailwind.css} +0 -0
  81. /package/lib/generators/add-frontend/{templates → frameworks/tailwindui}/tailwind.config.ts.template +0 -0
  82. /package/lib/generators/add-frontend/{generator.spec.d.ts → generator.test.d.ts} +0 -0
  83. /package/src/generators/add-frontend/frameworks/tailwindui/{entry.server.tsx.template → src/entry.server.tsx.template} +0 -0
  84. /package/src/generators/add-frontend/frameworks/tailwindui/{root.tsx.template → src/root.tsx.template} +0 -0
  85. /package/src/generators/add-frontend/frameworks/tailwindui/{tailwind.css → src/tailwind.css} +0 -0
@@ -6,8 +6,6 @@ import { ApolloProvider } from '@apollo/client/index.js';
6
6
  import { SlotFillProvider, removeUniversalPortals } from '@common-stack/components-pro';
7
7
  import { InversifyProvider, PluginArea } from '@common-stack/client-react';
8
8
  import { Provider as ReduxProvider } from 'react-redux';
9
- import { PersistGate } from 'redux-persist/integration/react';
10
- import { persistStore } from 'redux-persist';
11
9
  import { CacheProvider } from '@emotion/react';
12
10
 
13
11
  // @ts-ignore
@@ -27,12 +25,10 @@ import Backend from 'i18next-http-backend';
27
25
  import { getInitialNamespaces } from 'remix-i18next/client';
28
26
  import config from '@app/cde-webconfig.json';
29
27
  // @ts-ignore
30
- // import { ClientStyleContext } from '@app/frontend-stack-react/entries/chakraui/context.js';
31
- import { ClientStyleContext } from './context';
28
+ import { ClientStyleContext, LocaleContext } from './context';
32
29
 
33
30
  const { apolloClient: client, container, serviceFunc } = createClientContainer();
34
31
  const { store } = createReduxStore(client, serviceFunc(), container);
35
- const persistor = persistStore(store);
36
32
 
37
33
  (window as any).__remixStore = store;
38
34
  removeUniversalPortals((window as any).__SLOT_FILLS__ || []);
@@ -60,6 +56,13 @@ function ClientCacheProvider({ children }: ClientCacheProviderProps) {
60
56
  );
61
57
  }
62
58
 
59
+ function LocaleProvider({ children }: ClientCacheProviderProps) {
60
+ const el = (document as any).querySelector('html');
61
+ const locale = el?.getAttribute('lng') || '';
62
+
63
+ return <LocaleContext.Provider value={locale}>{children}</LocaleContext.Provider>;
64
+ }
65
+
63
66
  async function hydrate() {
64
67
  if (!i18next.isInitialized && config.i18n.enabled) {
65
68
  await i18next
@@ -83,19 +86,19 @@ async function hydrate() {
83
86
  document.getElementById('root')!,
84
87
  // <StrictMode>
85
88
  <I18nextProvider i18n={i18next}>
86
- <ClientCacheProvider>
87
- <ApolloProvider client={client}>
88
- <ReduxProvider store={store}>
89
- <SlotFillProvider>
90
- <InversifyProvider container={container} modules={clientModules}>
91
- <PersistGate loading={null} persistor={persistor}>
92
- {() => <RemixBrowser />}
93
- </PersistGate>
94
- </InversifyProvider>
95
- </SlotFillProvider>
96
- </ReduxProvider>
97
- </ApolloProvider>
98
- </ClientCacheProvider>
89
+ <LocaleProvider>
90
+ <ClientCacheProvider>
91
+ <ApolloProvider client={client}>
92
+ <ReduxProvider store={store}>
93
+ <SlotFillProvider>
94
+ <InversifyProvider container={container} modules={clientModules}>
95
+ <RemixBrowser />
96
+ </InversifyProvider>
97
+ </SlotFillProvider>
98
+ </ReduxProvider>
99
+ </ApolloProvider>
100
+ </ClientCacheProvider>
101
+ </LocaleProvider>
99
102
  </I18nextProvider>,
100
103
  // </StrictMode>,
101
104
  );
@@ -36,8 +36,7 @@ import config from '@app/cde-webconfig.json';
36
36
 
37
37
  import { Head } from './root';
38
38
  import type { IAppLoadContext } from '@common-stack/client-core';
39
- // import { ServerStyleContext } from '@app/frontend-stack-react/entries/chakraui/context.js';
40
- import { ServerStyleContext } from './context';
39
+ import { ServerStyleContext, LocaleContext } from './context';
41
40
  import { i18nextInstance as i18next } from '@app/frontend-stack-react/i18n-localization/i18next.server.js';
42
41
 
43
42
  const { extractCriticalToChunks } = createEmotionServer(defaultCache);
@@ -149,17 +148,19 @@ async function handleBrowserRequest(
149
148
 
150
149
  const html = renderToString(
151
150
  <I18nextProvider i18n={instance}>
152
- <CacheProvider value={defaultCache}>
153
- <ApolloProvider client={client}>
154
- <ReduxProvider store={store}>
155
- <SlotFillProvider context={slotFillContext}>
156
- <InversifyProvider container={container} modules={clientModules}>
157
- <RemixServer context={remixContext} url={request.url} />
158
- </InversifyProvider>
159
- </SlotFillProvider>
160
- </ReduxProvider>
161
- </ApolloProvider>
162
- </CacheProvider>
151
+ <LocaleContext.Provider value={lng}>
152
+ <CacheProvider value={defaultCache}>
153
+ <ApolloProvider client={client}>
154
+ <ReduxProvider store={store}>
155
+ <SlotFillProvider context={slotFillContext}>
156
+ <InversifyProvider container={container} modules={clientModules}>
157
+ <RemixServer context={remixContext} url={request.url} />
158
+ </InversifyProvider>
159
+ </SlotFillProvider>
160
+ </ReduxProvider>
161
+ </ApolloProvider>
162
+ </CacheProvider>
163
+ </LocaleContext.Provider>
163
164
  </I18nextProvider>,
164
165
  );
165
166
 
@@ -177,23 +178,25 @@ async function handleBrowserRequest(
177
178
  const { pipe, abort } = renderToPipeableStream(
178
179
  (
179
180
  <I18nextProvider i18n={instance}>
180
- <ServerStyleContext.Provider value={chunks.styles}>
181
- <CacheProvider value={defaultCache}>
182
- <ApolloProvider client={client}>
183
- <ReduxProvider store={store}>
184
- <SlotFillProvider context={slotFillContext}>
185
- <InversifyProvider container={container} modules={clientModules}>
186
- <RemixServer
187
- context={remixContext}
188
- url={request.url}
189
- abortDelay={ABORT_DELAY}
190
- />
191
- </InversifyProvider>
192
- </SlotFillProvider>
193
- </ReduxProvider>
194
- </ApolloProvider>
195
- </CacheProvider>
196
- </ServerStyleContext.Provider>
181
+ <LocaleContext.Provider value={lng}>
182
+ <ServerStyleContext.Provider value={chunks.styles}>
183
+ <CacheProvider value={defaultCache}>
184
+ <ApolloProvider client={client}>
185
+ <ReduxProvider store={store}>
186
+ <SlotFillProvider context={slotFillContext}>
187
+ <InversifyProvider container={container} modules={clientModules}>
188
+ <RemixServer
189
+ context={remixContext}
190
+ url={request.url}
191
+ abortDelay={ABORT_DELAY}
192
+ />
193
+ </InversifyProvider>
194
+ </SlotFillProvider>
195
+ </ReduxProvider>
196
+ </ApolloProvider>
197
+ </CacheProvider>
198
+ </ServerStyleContext.Provider>
199
+ </LocaleContext.Provider>
197
200
  </I18nextProvider>
198
201
  ) as any,
199
202
  {
@@ -11,7 +11,7 @@ import { ApplicationErrorHandler } from '@admin-layout/chakra-ui';
11
11
  import clientModules, { plugins } from '@app/frontend-stack-react/modules.js';
12
12
  import { createHead } from 'remix-island';
13
13
  import { useContext } from 'react';
14
- import { ServerStyleContext, ClientStyleContext } from './context';
14
+ import { ServerStyleContext, ClientStyleContext, LocaleContext } from './context';
15
15
  import { withEmotionCache } from '@emotion/react';
16
16
  import { useChangeLanguage } from 'remix-i18next/react';
17
17
  import { i18nextInstance as i18next } from '@app/frontend-stack-react/i18n-localization/i18next.server.js';
@@ -31,6 +31,9 @@ export const Head = createHead(() => (
31
31
  export const Document = withEmotionCache(({ children }: DocumentProps, emotionCache) => {
32
32
  const serverStyleData = useContext(ServerStyleContext);
33
33
  const clientStyleData = useContext(ClientStyleContext);
34
+ const locale = useContext(LocaleContext);
35
+
36
+ useChangeLanguage(locale);
34
37
 
35
38
  React.useEffect(() => {
36
39
  // re-link sheet container
@@ -64,12 +67,12 @@ export const Document = withEmotionCache(({ children }: DocumentProps, emotionCa
64
67
  </>
65
68
  );
66
69
  });
67
-
70
+ /*
68
71
  export let loader = async ({ request }) => {
69
72
  let locale = await i18next.getLocale(request);
70
73
  return json({ locale });
71
74
  };
72
-
75
+ */
73
76
  export let handle = {
74
77
  i18n: 'common',
75
78
  };
@@ -79,11 +82,12 @@ export function shouldRevalidate(params: any) {
79
82
  }
80
83
 
81
84
  export default function App() {
85
+ /*
82
86
  const data = useRouteLoaderData<{ locale: any }>('root');
83
87
  const locale = data?.locale;
84
88
 
85
89
  useChangeLanguage(locale);
86
-
90
+ */
87
91
  React.useEffect(() => {
88
92
  subscribeReduxRouter({ store: window.__remixStore, router: window.__remixRouter } as any);
89
93
  }, []);
@@ -0,0 +1,6 @@
1
+ export default {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ }
@@ -12,8 +12,6 @@ import { ApolloProvider } from '@apollo/client/index.js';
12
12
  import { SlotFillProvider, removeUniversalPortals } from '@common-stack/components-pro';
13
13
  import { InversifyProvider } from '@common-stack/client-react';
14
14
  import { Provider as ReduxProvider } from 'react-redux';
15
- import { PersistGate } from 'redux-persist/integration/react';
16
- import { persistStore } from 'redux-persist';
17
15
  import i18next from 'i18next';
18
16
  import { I18nextProvider, initReactI18next } from 'react-i18next';
19
17
  import LanguageDetector from 'i18next-browser-languagedetector';
@@ -31,7 +29,6 @@ import config from '@app/cde-webconfig.json';
31
29
 
32
30
  const { apolloClient: client, container, serviceFunc } = createClientContainer();
33
31
  const { store } = createReduxStore(client, serviceFunc(), container);
34
- const persistor = persistStore(store);
35
32
 
36
33
  (window as any).__remixStore = store;
37
34
  removeUniversalPortals((window as any).__SLOT_FILLS__ || []);
@@ -64,13 +61,9 @@ async function hydrate() {
64
61
  <ReduxProvider store={store}>
65
62
  <SlotFillProvider>
66
63
  <InversifyProvider container={container} modules={clientModules}>
67
- <PersistGate loading={null} persistor={persistor}>
68
- {() => (
69
- <ApolloProvider client={client}>
70
- <RemixBrowser />
71
- </ApolloProvider>
72
- )}
73
- </PersistGate>
64
+ <ApolloProvider client={client}>
65
+ <RemixBrowser />
66
+ </ApolloProvider>
74
67
  </InversifyProvider>
75
68
  </SlotFillProvider>
76
69
  </ReduxProvider>
@@ -0,0 +1,12 @@
1
+ import type { Config } from 'tailwindcss'
2
+
3
+ export default {
4
+ content: [
5
+ "./src/**/{**,.client,.server}/**/*.{js,jsx,ts,tsx}",
6
+ ],
7
+ theme: {
8
+ extend: {},
9
+ },
10
+ plugins: [],
11
+ } satisfies Config
12
+
@@ -0,0 +1,79 @@
1
+ /* eslint-disable jest/no-hooks */
2
+ /* eslint-disable import/no-extraneous-dependencies */
3
+ import { beforeEach, describe, expect, it, jest } from '@jest/globals';
4
+ import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
5
+ import { readJson, Tree, writeJson } from '@nx/devkit';
6
+ import * as devkit from '@nx/devkit';
7
+ import { addFrontendGenerator } from './generator';
8
+ import { FRAMEWORK_ANTUI } from '../../common/constants';
9
+
10
+ describe('addFrontendGenerator', () => {
11
+ let tree: Tree;
12
+ const options = { name: 'demo', framework: FRAMEWORK_ANTUI, ns: '', directory: '' };
13
+
14
+ const projectRoot = 'frontend-demo-server';
15
+
16
+ beforeEach(() => {
17
+ // Create an in-memory workspace
18
+ tree = createTreeWithEmptyWorkspace();
19
+
20
+ // Stub out generateFiles so we don't trigger file reading from the real templates folders.
21
+ jest.spyOn(devkit, 'generateFiles').mockImplementation(() => {});
22
+ });
23
+
24
+ it('should add missing dependencies and update config.json for antui', async () => {
25
+ // Simulate an existing package.json with no dependencies.
26
+ writeJson(tree, `${projectRoot}/package.json`, {
27
+ name: 'demo',
28
+ dependencies: {},
29
+ });
30
+ // Simulate an existing config.json with an empty modules array.
31
+ writeJson(tree, `${projectRoot}/config.json`, {
32
+ modules: [],
33
+ });
34
+
35
+ await addFrontendGenerator(tree, options);
36
+
37
+ // Read and verify package.json updates.
38
+ const pkg = readJson(tree, `${projectRoot}/package.json`);
39
+
40
+ expect(pkg.name).toBe('frontend-demo-server');
41
+ // Check that the key dependency is added.
42
+ expect(pkg.dependencies['@admin-layout/ant-design-pro']).toBeDefined();
43
+ expect(pkg.dependencies['@ant-design/static-style-extract']).toBeDefined();
44
+ expect(pkg.dependencies['@emotion/react']).toBeDefined();
45
+ expect(pkg.dependencies['antd']).toBeDefined();
46
+ expect(pkg).toMatchSnapshot();
47
+
48
+ // Read and verify config.json updates.
49
+ const config = readJson(tree, `${projectRoot}/config.json`);
50
+
51
+ expect(config.uiFramework).toBe(FRAMEWORK_ANTUI);
52
+ // Ensure that the module is added only once.
53
+ expect(config.modules.includes('@admin-layout/ant-design-pro')).toBeTruthy();
54
+ });
55
+
56
+ it('should not override an already existing dependency version', async () => {
57
+ // Create an initial package.json that already defines a version for a dependency.
58
+ writeJson(tree, `${projectRoot}/package.json`, {
59
+ name: 'demo',
60
+ dependencies: {
61
+ antd: '1.0.0', // Already defined version
62
+ },
63
+ });
64
+ // Create a minimal config.json.
65
+ writeJson(tree, `${projectRoot}/config.json`, {
66
+ modules: [],
67
+ });
68
+
69
+ await addFrontendGenerator(tree, options);
70
+
71
+ const pkg = readJson(tree, `${projectRoot}/package.json`);
72
+
73
+ // Make sure the dependency already there was not overridden.
74
+ expect(pkg.dependencies.antd).toEqual('1.0.0');
75
+ // Ensure other expected dependencies have been added.
76
+ expect(pkg.dependencies['@admin-layout/ant-design-pro']).toBeDefined();
77
+ expect(pkg).toMatchSnapshot();
78
+ });
79
+ });
@@ -1,18 +1,88 @@
1
- import { addProjectConfiguration, formatFiles, generateFiles, Tree, updateJson } from '@nx/devkit';
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ /* eslint-disable no-param-reassign */
3
+ /* eslint-disable no-use-before-define */
4
+ import { formatFiles, generateFiles, Tree, updateJson } from '@nx/devkit';
2
5
  import * as path from 'path';
3
6
  import * as fs from 'node:fs';
4
7
  import { deepMerge } from '@common-stack/rollup-vite-utils/lib/utils/setupConfig.cjs';
5
8
  import { AddFrontendGeneratorSchema } from './schema';
6
9
  import { isValid, getValid } from '../../utils';
7
10
  import { FRAMEWORK_ANTUI, FRAMEWORK_CHAKRAUI, FRAMEWORK_TAILWINDUI } from '../../common/constants';
11
+ import pluginPkg from '../../common/package-releases/package.json' assert { type: 'json' };
8
12
 
9
13
  const DEFAULT_FRAMEWORK = FRAMEWORK_ANTUI;
10
14
  const DEFAULT_SERVER_NAME = 'frontend-server';
11
15
 
16
+ /**
17
+ * Helper to retrieve a package version from pluginPkg.
18
+ * Throws an error if a version for packageName is not defined.
19
+ */
20
+ function getPackageVersion(packageName: string): string {
21
+ // Read the generator's package.json. This file is updated using ncu,
22
+ // so the generator always picks up the latest dependency versions.
23
+ // const pluginPkgPath = path.resolve(__dirname, '../../common/package-releases/package.json');
24
+ // const pluginPkg = JSON.parse(fs.readFileSync(pluginPkgPath, 'utf-8'));
25
+
26
+ const version =
27
+ (pluginPkg.dependencies && pluginPkg.dependencies[packageName]) ||
28
+ (pluginPkg.devDependencies && pluginPkg.devDependencies[packageName]);
29
+
30
+ if (!version) {
31
+ throw new Error(`Version for package "${packageName}" not found in plugin package.json.`);
32
+ }
33
+ return version;
34
+ }
35
+
36
+ /**
37
+ * Helper to map an array of dependency names to an object where each key is a dependency
38
+ * and its value is obtained via getPackageVersion().
39
+ */
40
+ function mapDependencies(depNames: string[]): Record<string, string> {
41
+ return depNames.reduce(
42
+ (acc, name) => {
43
+ acc[name] = getPackageVersion(name);
44
+ return acc;
45
+ },
46
+ {} as Record<string, string>,
47
+ );
48
+ }
49
+
50
+ /**
51
+ * A mapping of frameworks to dependency definitions.
52
+ * Each dependency's version is obtained dynamically from pluginPkg using a helper.
53
+ */
54
+ const frameworkDependencyMap: {
55
+ [key: string]: { dependencies?: Record<string, string>; devDependencies?: Record<string, string> };
56
+ } = {
57
+ [FRAMEWORK_ANTUI]: {
58
+ dependencies: mapDependencies([
59
+ '@admin-layout/ant-design-pro',
60
+ '@ant-design/static-style-extract',
61
+ '@emotion/react',
62
+ '@emotion/server',
63
+ '@emotion/css',
64
+ '@emotion/styled',
65
+ 'antd',
66
+ ]),
67
+ },
68
+ [FRAMEWORK_CHAKRAUI]: {
69
+ dependencies: mapDependencies([
70
+ '@chakra-ui/react',
71
+ 'framer-motion',
72
+ '@emotion/react',
73
+ '@emotion/server',
74
+ '@emotion/css',
75
+ '@emotion/styled',
76
+ ]),
77
+ },
78
+ [FRAMEWORK_TAILWINDUI]: {
79
+ devDependencies: mapDependencies(['tailwindcss', 'postcss', 'autoprefixer']),
80
+ },
81
+ };
82
+
12
83
  export async function addFrontendGenerator(tree: Tree, options: AddFrontendGeneratorSchema) {
13
84
  const projectName = isValid(options.name) ? `frontend-${getValid(options.name)}-server` : DEFAULT_SERVER_NAME;
14
- const configs: any = {...options, name: projectName};
15
-
85
+ const configs: any = { ...options, name: projectName };
16
86
  return await generateFrontend(tree, configs);
17
87
  }
18
88
 
@@ -20,65 +90,60 @@ export const generateFrontend = async (tree: Tree, options: any) => {
20
90
  let projectName = getValid(options.name) ?? DEFAULT_SERVER_NAME;
21
91
  const projectRoot = isValid(options.directory) ? `${getValid(options.directory)}/${projectName}` : projectName;
22
92
  projectName = isValid(options.ns) ? `${getValid(options.ns)}-${projectName}` : projectName;
23
- const projectSrc = `${projectRoot}/src`;
24
-
93
+
25
94
  const framework = getValid(options.framework) ?? DEFAULT_FRAMEWORK;
26
95
  console.log('UI framework specified: ', framework);
27
-
28
- // resetProject(`${basePath}/${projectRoot}`);
29
-
30
- // addProjectConfiguration(tree, framework, {
31
- // root: projectRoot,
32
- // projectType: 'library',
33
- // sourceRoot: projectSrc,
34
- // targets: {},
35
- // });
36
-
96
+
37
97
  generateFiles(tree, path.join(__dirname, 'templates'), projectRoot, {});
38
- generateFiles(tree, path.join(__dirname, 'frameworks', framework), projectSrc, options);
98
+ generateFiles(tree, path.join(__dirname, 'frameworks', framework), projectRoot, options);
99
+
39
100
  updateJson(tree, `${projectRoot}/package.json`, (packageJson) => {
40
- packageJson['name'] = projectName;
41
- if (framework === FRAMEWORK_ANTUI) {
42
- packageJson['dependencies']["@admin-layout/ant-design-pro"] = "latest";
43
- packageJson['dependencies']["@ant-design/static-style-extract"] = "^1.0.2";
44
- packageJson['dependencies']["@emotion/react"] = "^11.10.0";
45
- packageJson['dependencies']["@emotion/server"] = "^11.10.0";
46
- packageJson['dependencies']["@emotion/css"] = "^11.10.0";
47
- packageJson['dependencies']["@emotion/styled"] = "^11.10.4";
48
- packageJson['dependencies']["antd"] = "^5.14.0";
49
- } else if (framework === FRAMEWORK_CHAKRAUI) {
50
- packageJson['dependencies']["@chakra-ui/react"] = "^2.8.2";
51
- packageJson['dependencies']["framer-motion"] = "^11.5.4";
52
- packageJson['dependencies']["@emotion/react"] = "^11.10.0";
53
- packageJson['dependencies']["@emotion/server"] = "^11.10.0";
54
- packageJson['dependencies']["@emotion/css"] = "^11.10.0";
55
- packageJson['dependencies']["@emotion/styled"] = "^11.10.4";
56
-
57
- } else if (framework === FRAMEWORK_TAILWINDUI) {
58
- packageJson['devDependencies']["tailwindcss"] = "^3.4.10";
59
- packageJson['devDependencies']["postcss"] = "^8.4.41";
60
- packageJson['devDependencies']["autoprefixer"] = "^10.4.20";
101
+ packageJson.name = projectName;
102
+ packageJson.dependencies = packageJson.dependencies || {};
103
+ packageJson.devDependencies = packageJson.devDependencies || {};
104
+
105
+ const dependencyOverrides = frameworkDependencyMap[framework] || {};
106
+
107
+ if (dependencyOverrides.dependencies) {
108
+ Object.entries(dependencyOverrides.dependencies).forEach(([pkg, version]) => {
109
+ if (!packageJson.dependencies[pkg]) {
110
+ packageJson.dependencies[pkg] = version;
111
+ }
112
+ });
61
113
  }
62
-
114
+
115
+ if (dependencyOverrides.devDependencies) {
116
+ Object.entries(dependencyOverrides.devDependencies).forEach(([pkg, version]) => {
117
+ if (!packageJson.devDependencies[pkg]) {
118
+ packageJson.devDependencies[pkg] = version;
119
+ }
120
+ });
121
+ }
122
+
63
123
  return packageJson;
64
124
  });
125
+
65
126
  updateJson(tree, `${projectRoot}/config.json`, (configJson) => {
66
- configJson['uiFramework'] = framework;
127
+ configJson.uiFramework = framework;
67
128
  if (framework === FRAMEWORK_ANTUI) {
68
- configJson['modules'].push("@admin-layout/ant-design-pro");
129
+ if (!configJson.modules.includes('@admin-layout/ant-design-pro')) {
130
+ configJson.modules.push('@admin-layout/ant-design-pro');
131
+ }
69
132
  } else if (framework === FRAMEWORK_CHAKRAUI) {
70
- configJson['modules'].push("@admin-layout/chakra-design-pro");
133
+ if (!configJson.modules.includes('@admin-layout/chakra-design-pro')) {
134
+ configJson.modules.push('@admin-layout/chakra-design-pro');
135
+ }
71
136
  }
72
137
 
73
138
  if (options['config.json']) {
74
- const addtionalConfigs = options['config.json'];
75
- configJson = deepMerge(configJson, addtionalConfigs);
139
+ const additionalConfigs = options['config.json'];
140
+ configJson = deepMerge(configJson, additionalConfigs);
76
141
  }
77
142
 
78
143
  return configJson;
79
144
  });
80
145
 
81
146
  await formatFiles(tree);
82
- }
147
+ };
83
148
 
84
149
  export default addFrontendGenerator;
@@ -29,7 +29,7 @@ pipeline {
29
29
  // by default first value of the choice will be choosen
30
30
  choice choices: ['auto', 'force'], description: 'Choose merge strategy', name: 'NPM_PUBLISH_STRATEGY'
31
31
  choice choices: ['yarn', 'npm'], description: 'Choose build strategy', name: 'BUILD_STRATEGY'
32
- choice choices: ['0.7.11','0.7.9', '0.6.0'], description: 'Choose Idestack chart version', name: 'IDESTACK_CHART_VERSION'
32
+ choice choices: ['0.7.12','0.7.11', '0.6.0'], description: 'Choose Idestack chart version', name: 'IDESTACK_CHART_VERSION'
33
33
  choice choices: ['nodejs20', 'nodejs18', 'nodejs22'], description: 'Choose NodeJS version', name: 'NODEJS_TOOL_VERSION'
34
34
  choice choices: ['buildOnly', 'buildAndTest', 'buildAndPublish', 'mobileBuild', 'mobilePreview', 'mobilePreviewLocal', 'mobilePreviewSubmit', 'mobileProd', 'mobileProdSubmit', 'devDeployOnly', 'stageDeploy', 'stageDeployOnly', 'prodDeploy', 'prodDeployOnly', 'allenv'], description: 'Where to deploy micro services?', name: 'ENV_CHOICE'
35
35
  choice choices: ['all', 'ios', 'android' ], description: 'Mobile type if it is mobile build?', name: 'MOBILE_CHOICE'
@@ -646,7 +646,7 @@ def buildAndPushDockerImage(server, name, version) {
646
646
  } else {
647
647
  sh """
648
648
  npx lerna exec --scope=*${server} ${params.BUILD_STRATEGY} run ${env.BUILD_COMMAND};
649
-
649
+ npx lerna exec --scope=*${server} ${params.BUILD_STRATEGY} copycommon
650
650
  docker buildx create --name ${server} --driver docker-container --use
651
651
  docker buildx inspect ${server} --bootstrap
652
652