@ronas-it/nx-generators 0.13.5 → 0.15.0-alpha.0
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 +4 -0
- package/generators.json +10 -0
- package/package.json +1 -1
- package/src/generators/dockerfile/files/Dockerfile.template +74 -0
- package/src/generators/dockerfile/generator.d.ts +2 -0
- package/src/generators/dockerfile/generator.js +25 -0
- package/src/generators/dockerfile/generator.js.map +1 -0
- package/src/generators/dockerfile/schema.d.ts +3 -0
- package/src/generators/dockerfile/schema.json +8 -0
- package/src/generators/expo-app/generator.js +4 -0
- package/src/generators/expo-app/generator.js.map +1 -1
- package/src/generators/next-app/generator.js +4 -0
- package/src/generators/next-app/generator.js.map +1 -1
- package/src/shared/generators/index.d.ts +1 -0
- package/src/shared/generators/index.js +1 -0
- package/src/shared/generators/index.js.map +1 -1
- package/src/shared/generators/navigation-utils/common-lib-files/shared/utils/navigation/src/index.ts.template +1 -0
- package/src/shared/generators/navigation-utils/common-lib-files/shared/utils/navigation/src/lib/config.ts.template +5 -0
- package/src/shared/generators/navigation-utils/common-lib-files/shared/utils/navigation/src/lib/index.ts.template +2 -0
- package/src/shared/generators/navigation-utils/common-lib-files/shared/utils/navigation/src/lib/utils/get-link-builder.ts.template +38 -0
- package/src/shared/generators/navigation-utils/common-lib-files/shared/utils/navigation/src/lib/utils/get-resource-path.ts.template +28 -0
- package/src/shared/generators/navigation-utils/common-lib-files/shared/utils/navigation/src/lib/utils/index.ts.template +2 -0
- package/src/shared/generators/navigation-utils/generator.d.ts +4 -0
- package/src/shared/generators/navigation-utils/generator.js +31 -0
- package/src/shared/generators/navigation-utils/generator.js.map +1 -0
- package/src/shared/generators/navigation-utils/index.d.ts +1 -0
- package/src/shared/generators/navigation-utils/index.js +5 -0
- package/src/shared/generators/navigation-utils/index.js.map +1 -0
- package/src/shared/generators/navigation-utils/next-app-lib-files/shared/utils/navigation/src/lib/hooks/index.ts.template +1 -0
- package/src/shared/generators/navigation-utils/next-app-lib-files/shared/utils/navigation/src/lib/hooks/use-filtering-search-params.ts.template +61 -0
- package/src/shared/generators/navigation-utils/next-app-lib-files/shared/utils/navigation/src/lib/types/filtering-search-params.ts.template +4 -0
- package/src/shared/generators/navigation-utils/next-app-lib-files/shared/utils/navigation/src/lib/types/index.ts.template +1 -0
- package/src/shared/generators/navigation-utils/schema.d.ts +6 -0
- package/src/shared/generators/navigation-utils/schema.json +27 -0
package/README.md
CHANGED
|
@@ -300,3 +300,7 @@ Creates [Sentry](https://sentry.io/) integration for Expo/Next application.
|
|
|
300
300
|
1. `directory` (optional) - the application directory that uses Sentry
|
|
301
301
|
|
|
302
302
|
2. `dsn` (optional) - [Data Source Name](https://docs.sentry.io/concepts/key-terms/dsn-explainer/) of your Sentry project
|
|
303
|
+
|
|
304
|
+
### 14. `dockerfile`
|
|
305
|
+
|
|
306
|
+
Generates a deployment-ready Dockerfile for Next.js applications in the monorepo.
|
package/generators.json
CHANGED
|
@@ -79,6 +79,16 @@
|
|
|
79
79
|
"factory": "./src/shared/generators/auth/generator",
|
|
80
80
|
"schema": "./src/shared/generators/auth/schema.json",
|
|
81
81
|
"description": "Creates auth related api libs and configures redux store "
|
|
82
|
+
},
|
|
83
|
+
"dockerfile": {
|
|
84
|
+
"factory": "./src/generators/dockerfile/generator",
|
|
85
|
+
"schema": "./src/generators/dockerfile/schema.json",
|
|
86
|
+
"description": "Generates dockerfile"
|
|
87
|
+
},
|
|
88
|
+
"navigationUtils": {
|
|
89
|
+
"factory": "./src/shared/generators/navigation-utils/generator",
|
|
90
|
+
"schema": "./src/shared/generators/navigation-utils/schema.json",
|
|
91
|
+
"description": "Creates basic utilities for navigation"
|
|
82
92
|
}
|
|
83
93
|
}
|
|
84
94
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Builder stage
|
|
2
|
+
FROM node:22-alpine AS builder
|
|
3
|
+
|
|
4
|
+
ARG CI_COMMIT_REF_SLUG=development
|
|
5
|
+
ARG CI_NX_APP_NAME
|
|
6
|
+
ARG CI_TARGET_BRANCH_NAME
|
|
7
|
+
|
|
8
|
+
RUN if [ -z "$CI_COMMIT_REF_SLUG" ]; then echo "CI_COMMIT_REF_SLUG is not set"; exit 1; fi
|
|
9
|
+
RUN if [ -z "$CI_NX_APP_NAME" ]; then echo "CI_NX_APP_NAME is not set"; exit 1; fi
|
|
10
|
+
RUN echo "CI_COMMIT_REF_SLUG: $CI_COMMIT_REF_SLUG"
|
|
11
|
+
RUN echo "CI_NX_APP_NAME: $CI_NX_APP_NAME"
|
|
12
|
+
RUN echo "CI_TARGET_BRANCH_NAME: $CI_TARGET_BRANCH_NAME"
|
|
13
|
+
|
|
14
|
+
ENV CI_COMMIT_REF_SLUG=${CI_COMMIT_REF_SLUG}
|
|
15
|
+
ENV CI_NX_APP_NAME=${CI_NX_APP_NAME}
|
|
16
|
+
ENV NEXT_TELEMETRY_DISABLED=1
|
|
17
|
+
|
|
18
|
+
WORKDIR /app
|
|
19
|
+
|
|
20
|
+
# Copy package.json and package-lock.json (if available)
|
|
21
|
+
COPY package*.json ./
|
|
22
|
+
|
|
23
|
+
# Install all dependencies, including devDependencies
|
|
24
|
+
RUN npm ci
|
|
25
|
+
|
|
26
|
+
# Copy the rest of the application
|
|
27
|
+
COPY . .
|
|
28
|
+
|
|
29
|
+
ENV NEXT_SHARP_PATH=/app/node_modules/sharp
|
|
30
|
+
|
|
31
|
+
RUN if [ "$CI_COMMIT_REF_SLUG" != "production" ]; then \
|
|
32
|
+
if [ -n "$CI_TARGET_BRANCH_NAME" ] && [ -f "/app/apps/${CI_NX_APP_NAME}/.env.${CI_TARGET_BRANCH_NAME}" ]; then \
|
|
33
|
+
cp "/app/apps/${CI_NX_APP_NAME}/.env.${CI_TARGET_BRANCH_NAME}" "/app/apps/${CI_NX_APP_NAME}/.env.production"; \
|
|
34
|
+
elif [ -f "/app/apps/${CI_NX_APP_NAME}/.env.${CI_COMMIT_REF_SLUG}" ]; then \
|
|
35
|
+
cp "/app/apps/${CI_NX_APP_NAME}/.env.${CI_COMMIT_REF_SLUG}" "/app/apps/${CI_NX_APP_NAME}/.env.production"; \
|
|
36
|
+
fi \
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
RUN npx nx build ${CI_NX_APP_NAME} -c ${CI_COMMIT_REF_SLUG} --skip-nx-cache
|
|
40
|
+
|
|
41
|
+
# Runner stage
|
|
42
|
+
FROM node:22-alpine AS runner
|
|
43
|
+
|
|
44
|
+
ARG CI_COMMIT_REF_SLUG=development
|
|
45
|
+
ARG CI_NX_APP_NAME
|
|
46
|
+
|
|
47
|
+
RUN if [ -z "$CI_COMMIT_REF_SLUG" ]; then echo "CI_COMMIT_REF_SLUG is not set"; exit 1; fi
|
|
48
|
+
RUN if [ -z "$CI_NX_APP_NAME" ]; then echo "CI_NX_APP_NAME is not set"; exit 1; fi
|
|
49
|
+
RUN echo "CI_COMMIT_REF_SLUG: $CI_COMMIT_REF_SLUG"
|
|
50
|
+
RUN echo "CI_NX_APP_NAME: $CI_NX_APP_NAME"
|
|
51
|
+
|
|
52
|
+
ENV CI_COMMIT_REF_SLUG=${CI_COMMIT_REF_SLUG}
|
|
53
|
+
ENV CI_NX_APP_NAME=${CI_NX_APP_NAME}
|
|
54
|
+
ENV NODE_ENV=${CI_COMMIT_REF_SLUG}
|
|
55
|
+
ENV NEXT_TELEMETRY_DISABLED=1
|
|
56
|
+
ENV PORT=3000
|
|
57
|
+
|
|
58
|
+
WORKDIR /app
|
|
59
|
+
|
|
60
|
+
RUN addgroup --system --gid 1001 nodejs && \
|
|
61
|
+
adduser --system --uid 1001 nextjs
|
|
62
|
+
|
|
63
|
+
# Copy only the built application and necessary files
|
|
64
|
+
COPY --from=builder --chown=nextjs:nodejs /app/apps/${CI_NX_APP_NAME}/.next/standalone ./
|
|
65
|
+
COPY --from=builder --chown=nextjs:nodejs /app/apps/${CI_NX_APP_NAME}/.next/static ./apps/${CI_NX_APP_NAME}/.next/static/
|
|
66
|
+
COPY --from=builder --chown=nextjs:nodejs /app/apps/${CI_NX_APP_NAME}/public ./apps/${CI_NX_APP_NAME}/public
|
|
67
|
+
|
|
68
|
+
RUN chown -R nextjs:nodejs ./apps/${CI_NX_APP_NAME}/public
|
|
69
|
+
|
|
70
|
+
USER nextjs
|
|
71
|
+
|
|
72
|
+
EXPOSE 3000
|
|
73
|
+
|
|
74
|
+
CMD ["sh", "-c", "node apps/$CI_NX_APP_NAME/server.js"]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const devkit_1 = require("@nx/devkit");
|
|
6
|
+
function default_1(tree) {
|
|
7
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
8
|
+
const projectRoot = `.`;
|
|
9
|
+
const dockerfilePath = (0, devkit_1.joinPathFragments)(projectRoot, 'Dockerfile');
|
|
10
|
+
if (tree.exists(dockerfilePath)) {
|
|
11
|
+
tree.delete(dockerfilePath);
|
|
12
|
+
console.log(`Removed existing Dockerfile`);
|
|
13
|
+
}
|
|
14
|
+
const templateSource = path.join(__dirname, 'files');
|
|
15
|
+
(0, devkit_1.generateFiles)(tree, templateSource, projectRoot, {
|
|
16
|
+
tmpl: '',
|
|
17
|
+
});
|
|
18
|
+
yield (0, devkit_1.formatFiles)(tree);
|
|
19
|
+
return () => {
|
|
20
|
+
(0, devkit_1.installPackagesTask)(tree);
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
exports.default = default_1;
|
|
25
|
+
//# sourceMappingURL=generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../plugin/src/generators/dockerfile/generator.ts"],"names":[],"mappings":";;;AAAA,6BAA6B;AAC7B,uCAAsG;AAEtG,mBAA+B,IAAU;;QACvC,MAAM,WAAW,GAAG,GAAG,CAAC;QACxB,MAAM,cAAc,GAAG,IAAA,0BAAiB,EAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QAEpE,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;QAC7C,CAAC;QAED,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAErD,IAAA,sBAAa,EAAC,IAAI,EAAE,cAAc,EAAE,WAAW,EAAE;YAC/C,IAAI,EAAE,EAAE;SACT,CAAC,CAAC;QAEH,MAAM,IAAA,oBAAW,EAAC,IAAI,CAAC,CAAC;QAExB,OAAO,GAAS,EAAE;YAChB,IAAA,4BAAmB,EAAC,IAAI,CAAC,CAAC;QAC5B,CAAC,CAAC;IACJ,CAAC;CAAA;AApBD,4BAoBC"}
|
|
@@ -34,6 +34,10 @@ function expoAppGenerator(tree, options) {
|
|
|
34
34
|
yield (0, generators_1.runAppEnvGenerator)(tree, Object.assign(Object.assign({}, options), { baseGeneratorType: enums_1.BaseGeneratorType.EXPO_APP }));
|
|
35
35
|
yield (0, generators_1.runStorageGenerator)(tree, options);
|
|
36
36
|
yield (0, generators_1.runRNStylesGenerator)(tree, options);
|
|
37
|
+
yield (0, generators_1.runNavigationUtilsGenerator)(tree, {
|
|
38
|
+
appDirectory: options.directory,
|
|
39
|
+
baseGeneratorType: enums_1.BaseGeneratorType.EXPO_APP,
|
|
40
|
+
});
|
|
37
41
|
if (options.withStore) {
|
|
38
42
|
yield (0, generators_1.runStoreGenerator)(tree, Object.assign(Object.assign({}, options), { baseGeneratorType: enums_1.BaseGeneratorType.EXPO_APP }));
|
|
39
43
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../plugin/src/generators/expo-app/generator.ts"],"names":[],"mappings":";;;;AAAA,iDAAyC;AACzC,2BAAwC;AACxC,6BAA6B;AAC7B,uCAUoB;AACpB,4DAA0E;AAC1E,8CAAuD;AACvD,
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../plugin/src/generators/expo-app/generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,6 +26,10 @@ function nextAppGenerator(tree, options) {
|
|
|
26
26
|
}
|
|
27
27
|
yield (0, generators_1.runAppEnvGenerator)(tree, Object.assign(Object.assign({}, options), { baseGeneratorType: enums_1.BaseGeneratorType.NEXT_APP }));
|
|
28
28
|
yield (0, generators_1.runI18nNextGenerator)(tree, options);
|
|
29
|
+
yield (0, generators_1.runNavigationUtilsGenerator)(tree, {
|
|
30
|
+
appDirectory: options.directory,
|
|
31
|
+
baseGeneratorType: enums_1.BaseGeneratorType.NEXT_APP,
|
|
32
|
+
});
|
|
29
33
|
if (options.withStore) {
|
|
30
34
|
yield (0, generators_1.runStoreGenerator)(tree, Object.assign(Object.assign({}, options), { baseGeneratorType: enums_1.BaseGeneratorType.NEXT_APP }));
|
|
31
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../plugin/src/generators/next-app/generator.ts"],"names":[],"mappings":";;;;AAAA,iDAAyC;AACzC,2BAAgC;AAChC,6BAA6B;AAC7B,uCAQoB;AACpB,mCAAmC;AACnC,4DAA0E;AAC1E,8CAAuD;AACvD,
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../plugin/src/generators/next-app/generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,4 +10,5 @@ tslib_1.__exportStar(require("./rn-styles"), exports);
|
|
|
10
10
|
tslib_1.__exportStar(require("./ui-kitten"), exports);
|
|
11
11
|
tslib_1.__exportStar(require("./form-utils"), exports);
|
|
12
12
|
tslib_1.__exportStar(require("./i18n-next"), exports);
|
|
13
|
+
tslib_1.__exportStar(require("./navigation-utils"), exports);
|
|
13
14
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../plugin/src/shared/generators/index.ts"],"names":[],"mappings":";;;AAAA,kDAAwB;AACxB,oDAA0B;AAC1B,uDAA6B;AAC7B,iDAAuB;AACvB,oDAA0B;AAC1B,sDAA4B;AAC5B,sDAA4B;AAC5B,uDAA6B;AAC7B,sDAA4B"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../plugin/src/shared/generators/index.ts"],"names":[],"mappings":";;;AAAA,kDAAwB;AACxB,oDAA0B;AAC1B,uDAA6B;AAC7B,iDAAuB;AACvB,oDAA0B;AAC1B,sDAA4B;AAC5B,sDAA4B;AAC5B,uDAA6B;AAC7B,sDAA4B;AAC5B,6DAAmC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './lib';
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { isNil } from 'lodash-es';
|
|
2
|
+
|
|
3
|
+
export type LinkBuilder<TRootParams extends object = never> = keyof TRootParams extends never
|
|
4
|
+
? () => string
|
|
5
|
+
: (args?: TRootParams) => string;
|
|
6
|
+
|
|
7
|
+
export const getLinkBuilder = <TRootParams extends object = never>(
|
|
8
|
+
basePath: string
|
|
9
|
+
): LinkBuilder<TRootParams> => {
|
|
10
|
+
return ((args?: TRootParams) => {
|
|
11
|
+
if (!args || Object.keys(args).length === 0) {
|
|
12
|
+
return basePath;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const resultBasePath = basePath.replace(/\[(\w+)]/g, (match, paramName) => {
|
|
16
|
+
return paramName in args ? String(args[paramName as keyof TRootParams]) : match;
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const searchParams = new URLSearchParams();
|
|
20
|
+
|
|
21
|
+
for (const [key, value] of Object.entries(args)) {
|
|
22
|
+
if (isNil(value) || basePath.includes(`[${key}]`)) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (Array.isArray(value)) {
|
|
27
|
+
const uniqueValues = Array.from(new Set(value));
|
|
28
|
+
uniqueValues.forEach((value) => searchParams.append(key, String(value)));
|
|
29
|
+
} else {
|
|
30
|
+
searchParams.append(key, String(value));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const queryString = searchParams.toString();
|
|
35
|
+
|
|
36
|
+
return `${resultBasePath}${queryString ? `?${queryString}` : ''}`;
|
|
37
|
+
}) as LinkBuilder<TRootParams>;
|
|
38
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { getLinkBuilder, LinkBuilder } from './get-link-builder';
|
|
2
|
+
|
|
3
|
+
interface ResourcePaths<TRootParams extends object = never> {
|
|
4
|
+
list: LinkBuilder<TRootParams>;
|
|
5
|
+
create?: string;
|
|
6
|
+
view: (id: number) => string;
|
|
7
|
+
edit?: (id: number) => string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const getResourcePaths = <TRootParams extends object = never>(
|
|
11
|
+
basePath: string,
|
|
12
|
+
options?: { withCreation?: boolean; withEditing?: boolean }
|
|
13
|
+
): ResourcePaths<TRootParams> => {
|
|
14
|
+
const paths: ResourcePaths<TRootParams> = {
|
|
15
|
+
list: getLinkBuilder<TRootParams>(basePath),
|
|
16
|
+
view: (id: number) => `${basePath}/${id}`
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
if (options?.withCreation) {
|
|
20
|
+
paths.create = `${basePath}/create`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (options?.withEditing) {
|
|
24
|
+
paths.edit = (id: number) => `${basePath}/${id}/edit`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return paths;
|
|
28
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runNavigationUtilsGenerator = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const child_process_1 = require("child_process");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
const devkit_1 = require("@nx/devkit");
|
|
8
|
+
const enums_1 = require("../../enums");
|
|
9
|
+
const utils_1 = require("../../utils");
|
|
10
|
+
function runNavigationUtilsGenerator(tree, options) {
|
|
11
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
12
|
+
const libRoot = `libs/${options.appDirectory}`;
|
|
13
|
+
// Generate shared libs
|
|
14
|
+
(0, child_process_1.execSync)(`npx nx g react-lib --app=${options.appDirectory} --scope=shared --type=utils --name=navigation`, {
|
|
15
|
+
stdio: 'inherit',
|
|
16
|
+
});
|
|
17
|
+
// Remove unnecessary files and files that will be replaced
|
|
18
|
+
const libPath = `${libRoot}/shared/utils/navigation/src`;
|
|
19
|
+
tree.delete(`${libPath}/index.ts`);
|
|
20
|
+
// Add lib files
|
|
21
|
+
(0, devkit_1.generateFiles)(tree, path.join(__dirname, '/common-lib-files'), libRoot, {});
|
|
22
|
+
if (options.baseGeneratorType === enums_1.BaseGeneratorType.NEXT_APP) {
|
|
23
|
+
(0, devkit_1.generateFiles)(tree, path.join(__dirname, '/next-app-lib-files'), libRoot, {});
|
|
24
|
+
const newIndexContent = `export * from './hooks';\nexport * from './types';`;
|
|
25
|
+
(0, utils_1.appendFileContent)(`${libPath}/lib/index.ts`, newIndexContent, tree);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
exports.runNavigationUtilsGenerator = runNavigationUtilsGenerator;
|
|
30
|
+
exports.default = runNavigationUtilsGenerator;
|
|
31
|
+
//# sourceMappingURL=generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../plugin/src/shared/generators/navigation-utils/generator.ts"],"names":[],"mappings":";;;;AAAA,iDAAyC;AACzC,6BAA6B;AAC7B,uCAAiD;AACjD,uCAAgD;AAChD,uCAAgD;AAGhD,SAAsB,2BAA2B,CAAC,IAAU,EAAE,OAAuC;;QACnG,MAAM,OAAO,GAAG,QAAQ,OAAO,CAAC,YAAY,EAAE,CAAC;QAE/C,uBAAuB;QACvB,IAAA,wBAAQ,EAAC,4BAA4B,OAAO,CAAC,YAAY,gDAAgD,EAAE;YACzG,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;QAEH,2DAA2D;QAC3D,MAAM,OAAO,GAAG,GAAG,OAAO,8BAA8B,CAAC;QACzD,IAAI,CAAC,MAAM,CAAC,GAAG,OAAO,WAAW,CAAC,CAAC;QAEnC,gBAAgB;QAChB,IAAA,sBAAa,EAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;QAE5E,IAAI,OAAO,CAAC,iBAAiB,KAAK,yBAAiB,CAAC,QAAQ,EAAE,CAAC;YAC7D,IAAA,sBAAa,EAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,qBAAqB,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;YAE9E,MAAM,eAAe,GAAG,oDAAoD,CAAC;YAC7E,IAAA,yBAAiB,EAAC,GAAG,OAAO,eAAe,EAAE,eAAe,EAAE,IAAI,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;CAAA;AArBD,kEAqBC;AAED,kBAAe,2BAA2B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './generator';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../plugin/src/shared/generators/navigation-utils/index.ts"],"names":[],"mappings":";;;AAAA,sDAA4B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './use-filtering-search-params';
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { ClassConstructor, instanceToPlain, plainToInstance } from 'class-transformer';
|
|
2
|
+
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
|
|
3
|
+
import { useCallback, useRef } from 'react';
|
|
4
|
+
import { FilteringSearchParams } from '../types';
|
|
5
|
+
|
|
6
|
+
interface FilteringSearchParamsConfig<TParams> {
|
|
7
|
+
searchParamsConstructor: ClassConstructor<TParams>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const useFilteringSearchParams = <TParams extends FilteringSearchParams>({
|
|
11
|
+
searchParamsConstructor
|
|
12
|
+
}: FilteringSearchParamsConfig<TParams>): typeof result => {
|
|
13
|
+
const initialParams = useRef<TParams | null>(null);
|
|
14
|
+
const searchParams = useSearchParams();
|
|
15
|
+
const router = useRouter();
|
|
16
|
+
const pathname = usePathname();
|
|
17
|
+
|
|
18
|
+
const getSearchParams = useCallback((): TParams => {
|
|
19
|
+
const initialParams = {} as Record<string, any>;
|
|
20
|
+
searchParams.forEach((value, key) => {
|
|
21
|
+
try {
|
|
22
|
+
initialParams[key] = JSON.parse(value);
|
|
23
|
+
} catch {
|
|
24
|
+
initialParams[key] = value;
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
return plainToInstance(searchParamsConstructor, initialParams, {
|
|
29
|
+
excludeExtraneousValues: true,
|
|
30
|
+
exposeUnsetFields: false
|
|
31
|
+
});
|
|
32
|
+
}, [searchParams]);
|
|
33
|
+
|
|
34
|
+
const setSearchParams = useCallback(
|
|
35
|
+
(params: TParams): void => {
|
|
36
|
+
const newSearchParams = new URLSearchParams();
|
|
37
|
+
const plainParams = instanceToPlain(params, { exposeUnsetFields: false });
|
|
38
|
+
|
|
39
|
+
Object.keys(plainParams).forEach((field) => {
|
|
40
|
+
const value = plainParams[field];
|
|
41
|
+
|
|
42
|
+
if (value !== null && value !== undefined && !(Array.isArray(value) && value.length === 0)) {
|
|
43
|
+
newSearchParams.set(field, JSON.stringify(value));
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const newParamsString = newSearchParams.toString();
|
|
48
|
+
router.replace(`${pathname}${newParamsString ? `?${newParamsString}` : ''}`);
|
|
49
|
+
},
|
|
50
|
+
[pathname],
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
initialParams.current = getSearchParams();
|
|
54
|
+
|
|
55
|
+
const result = {
|
|
56
|
+
initialSearchParams: initialParams.current,
|
|
57
|
+
setSearchParams
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
return result;
|
|
61
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './filtering-search-params';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/schema",
|
|
3
|
+
"$id": "Navigation utils",
|
|
4
|
+
"title": "",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"appDirectory": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "Directory of the app (folder inside apps/)",
|
|
10
|
+
"default": "",
|
|
11
|
+
"$default": {
|
|
12
|
+
"$source": "argv",
|
|
13
|
+
"index": 0
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"baseGeneratorType": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"description": "Base generator type (Expo or Next.js)",
|
|
19
|
+
"default": "",
|
|
20
|
+
"$default": {
|
|
21
|
+
"$source": "argv",
|
|
22
|
+
"index": 1
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"required": []
|
|
27
|
+
}
|