@carlonicora/nextjs-jsonapi 1.50.0 → 1.52.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/dist/{BlockNoteEditor-LENHWRS2.js → BlockNoteEditor-KQPSJCYG.js} +6 -6
- package/dist/{BlockNoteEditor-LENHWRS2.js.map → BlockNoteEditor-KQPSJCYG.js.map} +1 -1
- package/dist/{BlockNoteEditor-WLS36QIF.mjs → BlockNoteEditor-WUVRCTQI.mjs} +2 -2
- package/dist/billing/index.js +299 -299
- package/dist/billing/index.mjs +1 -1
- package/dist/{chunk-VQ35TGD7.mjs → chunk-BTLJZIDS.mjs} +2612 -2269
- package/dist/chunk-BTLJZIDS.mjs.map +1 -0
- package/dist/{chunk-KWAUWJYX.js → chunk-YKPIFJOB.js} +544 -201
- package/dist/chunk-YKPIFJOB.js.map +1 -0
- package/dist/client/index.js +2 -2
- package/dist/client/index.mjs +1 -1
- package/dist/components/index.d.mts +44 -4
- package/dist/components/index.d.ts +44 -4
- package/dist/components/index.js +38 -2
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +37 -1
- package/dist/contexts/index.js +2 -2
- package/dist/contexts/index.mjs +1 -1
- package/dist/scripts/generate-web-module/generator.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/generator.js +62 -4
- package/dist/scripts/generate-web-module/generator.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/container.template.js +12 -43
- package/dist/scripts/generate-web-module/templates/components/container.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/details.template.js +7 -5
- package/dist/scripts/generate-web-module/templates/components/details.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/editor.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/editor.template.js +28 -17
- package/dist/scripts/generate-web-module/templates/components/editor.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/list.template.js +4 -3
- package/dist/scripts/generate-web-module/templates/components/list.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/multi-selector.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/multi-selector.template.js +6 -4
- package/dist/scripts/generate-web-module/templates/components/multi-selector.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/selector.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/components/selector.template.js +8 -5
- package/dist/scripts/generate-web-module/templates/components/selector.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/context.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/context.template.js +8 -6
- package/dist/scripts/generate-web-module/templates/context.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/data/aliases.template.d.ts +15 -0
- package/dist/scripts/generate-web-module/templates/data/aliases.template.d.ts.map +1 -0
- package/dist/scripts/generate-web-module/templates/data/aliases.template.js +31 -0
- package/dist/scripts/generate-web-module/templates/data/aliases.template.js.map +1 -0
- package/dist/scripts/generate-web-module/templates/data/fields.template.js +2 -2
- package/dist/scripts/generate-web-module/templates/data/fields.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/data/index.d.ts +1 -0
- package/dist/scripts/generate-web-module/templates/data/index.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/data/index.js +1 -0
- package/dist/scripts/generate-web-module/templates/data/index.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/data/interface.template.js +11 -5
- package/dist/scripts/generate-web-module/templates/data/interface.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/data/model.template.js +25 -16
- package/dist/scripts/generate-web-module/templates/data/model.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/data/service.template.js +5 -1
- package/dist/scripts/generate-web-module/templates/data/service.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/index.d.ts +1 -1
- package/dist/scripts/generate-web-module/templates/index.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/index.js +2 -1
- package/dist/scripts/generate-web-module/templates/index.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/pages/detail-page.template.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/templates/pages/detail-page.template.js +6 -7
- package/dist/scripts/generate-web-module/templates/pages/detail-page.template.js.map +1 -1
- package/dist/scripts/generate-web-module/templates/pages/list-page.template.js +3 -3
- package/dist/scripts/generate-web-module/templates/pages/list-page.template.js.map +1 -1
- package/dist/scripts/generate-web-module/transformers/field-mapper.js +5 -5
- package/dist/scripts/generate-web-module/transformers/field-mapper.js.map +1 -1
- package/dist/scripts/generate-web-module/transformers/i18n-generator.js +2 -2
- package/dist/scripts/generate-web-module/transformers/i18n-generator.js.map +1 -1
- package/dist/scripts/generate-web-module/transformers/import-resolver.d.ts +1 -0
- package/dist/scripts/generate-web-module/transformers/import-resolver.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/transformers/import-resolver.js +1 -0
- package/dist/scripts/generate-web-module/transformers/import-resolver.js.map +1 -1
- package/dist/scripts/generate-web-module/transformers/relationship-resolver.d.ts +3 -3
- package/dist/scripts/generate-web-module/transformers/relationship-resolver.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/transformers/relationship-resolver.js +19 -13
- package/dist/scripts/generate-web-module/transformers/relationship-resolver.js.map +1 -1
- package/dist/scripts/generate-web-module/types/field-mapping.types.d.ts +4 -2
- package/dist/scripts/generate-web-module/types/field-mapping.types.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/types/field-mapping.types.js +23 -7
- package/dist/scripts/generate-web-module/types/field-mapping.types.js.map +1 -1
- package/dist/scripts/generate-web-module/types/template-data.interface.d.ts +2 -0
- package/dist/scripts/generate-web-module/types/template-data.interface.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/utils/bootstrapper-updater.js +2 -2
- package/dist/scripts/generate-web-module/utils/bootstrapper-updater.js.map +1 -1
- package/dist/scripts/generate-web-module/utils/file-writer.d.ts +6 -0
- package/dist/scripts/generate-web-module/utils/file-writer.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/utils/file-writer.js +22 -0
- package/dist/scripts/generate-web-module/utils/file-writer.js.map +1 -1
- package/dist/scripts/generate-web-module/utils/i18n-updater.js +13 -13
- package/dist/scripts/generate-web-module/utils/i18n-updater.js.map +1 -1
- package/dist/scripts/generate-web-module/utils/index.d.ts +1 -1
- package/dist/scripts/generate-web-module/utils/index.d.ts.map +1 -1
- package/dist/scripts/generate-web-module/utils/index.js +2 -1
- package/dist/scripts/generate-web-module/utils/index.js.map +1 -1
- package/package.json +2 -2
- package/scripts/generate-web-module/generator.ts +70 -5
- package/scripts/generate-web-module/templates/components/container.template.ts +12 -43
- package/scripts/generate-web-module/templates/components/details.template.ts +7 -5
- package/scripts/generate-web-module/templates/components/editor.template.ts +27 -17
- package/scripts/generate-web-module/templates/components/list.template.ts +4 -3
- package/scripts/generate-web-module/templates/components/multi-selector.template.ts +6 -4
- package/scripts/generate-web-module/templates/components/selector.template.ts +8 -5
- package/scripts/generate-web-module/templates/context.template.ts +8 -6
- package/scripts/generate-web-module/templates/data/aliases.template.ts +33 -0
- package/scripts/generate-web-module/templates/data/fields.template.ts +2 -2
- package/scripts/generate-web-module/templates/data/index.ts +1 -0
- package/scripts/generate-web-module/templates/data/interface.template.ts +10 -5
- package/scripts/generate-web-module/templates/data/model.template.ts +24 -16
- package/scripts/generate-web-module/templates/data/service.template.ts +6 -1
- package/scripts/generate-web-module/templates/index.ts +1 -0
- package/scripts/generate-web-module/templates/pages/detail-page.template.ts +6 -7
- package/scripts/generate-web-module/templates/pages/list-page.template.ts +3 -3
- package/scripts/generate-web-module/transformers/field-mapper.ts +5 -5
- package/scripts/generate-web-module/transformers/i18n-generator.ts +2 -2
- package/scripts/generate-web-module/transformers/import-resolver.ts +2 -0
- package/scripts/generate-web-module/transformers/relationship-resolver.ts +19 -13
- package/scripts/generate-web-module/types/field-mapping.types.ts +19 -6
- package/scripts/generate-web-module/types/template-data.interface.ts +2 -0
- package/scripts/generate-web-module/utils/bootstrapper-updater.ts +2 -2
- package/scripts/generate-web-module/utils/file-writer.ts +21 -0
- package/scripts/generate-web-module/utils/i18n-updater.ts +13 -13
- package/scripts/generate-web-module/utils/index.ts +1 -1
- package/src/components/containers/RoundPageContainer.tsx +80 -0
- package/src/components/containers/RoundPageContainerTitle.tsx +60 -0
- package/src/components/containers/index.ts +2 -0
- package/src/components/navigations/Header.tsx +3 -2
- package/src/shadcnui/index.ts +1 -0
- package/src/shadcnui/ui/command.tsx +2 -2
- package/dist/chunk-KWAUWJYX.js.map +0 -1
- package/dist/chunk-VQ35TGD7.mjs.map +0 -1
- /package/dist/{BlockNoteEditor-WLS36QIF.mjs.map → BlockNoteEditor-WUVRCTQI.mjs.map} +0 -0
|
@@ -40,9 +40,11 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
40
40
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
41
|
exports.writeFile = writeFile;
|
|
42
42
|
exports.writeFiles = writeFiles;
|
|
43
|
+
exports.formatFiles = formatFiles;
|
|
43
44
|
exports.printResults = printResults;
|
|
44
45
|
const fs = __importStar(require("fs"));
|
|
45
46
|
const path = __importStar(require("path"));
|
|
47
|
+
const child_process_1 = require("child_process");
|
|
46
48
|
/**
|
|
47
49
|
* Write a single file to disk
|
|
48
50
|
*
|
|
@@ -91,6 +93,26 @@ function writeFile(file, options = {}) {
|
|
|
91
93
|
function writeFiles(files, options = {}) {
|
|
92
94
|
return files.map((file) => writeFile(file, options));
|
|
93
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Format files with Prettier
|
|
98
|
+
*
|
|
99
|
+
* @param filePaths - Absolute paths of files to format
|
|
100
|
+
*/
|
|
101
|
+
function formatFiles(filePaths) {
|
|
102
|
+
if (filePaths.length === 0)
|
|
103
|
+
return;
|
|
104
|
+
console.info(`\n💅 Formatting ${filePaths.length} files with Prettier...`);
|
|
105
|
+
try {
|
|
106
|
+
(0, child_process_1.execSync)(`npx prettier --write ${filePaths.map((p) => `"${p}"`).join(" ")}`, {
|
|
107
|
+
stdio: "pipe",
|
|
108
|
+
cwd: process.cwd(),
|
|
109
|
+
});
|
|
110
|
+
console.info(` ✅ Formatted successfully`);
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
console.warn(` ⚠️ Prettier formatting failed — files were written but may need manual formatting`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
94
116
|
/**
|
|
95
117
|
* Print write results to console
|
|
96
118
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-writer.js","sourceRoot":"","sources":["../../../../scripts/generate-web-module/utils/file-writer.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"file-writer.js","sourceRoot":"","sources":["../../../../scripts/generate-web-module/utils/file-writer.ts"],"names":[],"mappings":"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"}
|
|
@@ -75,35 +75,35 @@ function updateI18n(data, webBasePath, language = "en", dryRun = false) {
|
|
|
75
75
|
// Build the i18n messages for this module
|
|
76
76
|
const moduleMessages = (0, i18n_generator_1.buildI18nMessages)(i18nKeys);
|
|
77
77
|
const lowercaseModuleName = names.camelCase.toLowerCase();
|
|
78
|
-
// Always ensure
|
|
79
|
-
let
|
|
80
|
-
if (!messages.
|
|
81
|
-
messages.
|
|
78
|
+
// Always ensure entities section is updated (even if features already exist)
|
|
79
|
+
let entitiesUpdated = false;
|
|
80
|
+
if (!messages.entities) {
|
|
81
|
+
messages.entities = {};
|
|
82
82
|
}
|
|
83
|
-
const
|
|
83
|
+
const entitiesKey = Object.keys(moduleMessages.entities)[0];
|
|
84
84
|
const lowercasePluralKey = names.pluralCamel.toLowerCase();
|
|
85
|
-
if (
|
|
86
|
-
messages.
|
|
87
|
-
|
|
85
|
+
if (entitiesKey && !messages.entities[lowercasePluralKey]) {
|
|
86
|
+
messages.entities[lowercasePluralKey] = moduleMessages.entities[entitiesKey];
|
|
87
|
+
entitiesUpdated = true;
|
|
88
88
|
}
|
|
89
89
|
// Check if module already exists in features
|
|
90
90
|
const featuresAlreadyExist = messages.features && messages.features[lowercaseModuleName];
|
|
91
91
|
if (featuresAlreadyExist) {
|
|
92
|
-
// Features exist, but we may have added
|
|
93
|
-
if (
|
|
92
|
+
// Features exist, but we may have added entities
|
|
93
|
+
if (entitiesUpdated) {
|
|
94
94
|
if (dryRun) {
|
|
95
95
|
return {
|
|
96
96
|
success: true,
|
|
97
|
-
message: `[DRY RUN] Module ${names.camelCase} exists, would add
|
|
97
|
+
message: `[DRY RUN] Module ${names.camelCase} exists, would add entities.${lowercasePluralKey}`,
|
|
98
98
|
alreadyExists: true,
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
|
-
// Write updated content (
|
|
101
|
+
// Write updated content (entities were added)
|
|
102
102
|
const updatedContent = JSON.stringify(messages, null, 2);
|
|
103
103
|
fs.writeFileSync(messagesPath, updatedContent, "utf-8");
|
|
104
104
|
return {
|
|
105
105
|
success: true,
|
|
106
|
-
message: `Module ${names.camelCase} exists, added
|
|
106
|
+
message: `Module ${names.camelCase} exists, added entities.${lowercasePluralKey}`,
|
|
107
107
|
alreadyExists: true,
|
|
108
108
|
};
|
|
109
109
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n-updater.js","sourceRoot":"","sources":["../../../../scripts/generate-web-module/utils/i18n-updater.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqBH,gCAkGC;AAQD,kDAGC;AAhID,uCAAyB;AAEzB,mEAAmE;AAQnE;;;;;;;;GAQG;AACH,SAAgB,UAAU,CACxB,IAA0B,EAC1B,WAAmB,EACnB,WAAmB,IAAI,EACvB,SAAkB,KAAK;IAEvB,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IACjC,MAAM,YAAY,GAAG,GAAG,WAAW,sBAAsB,QAAQ,OAAO,CAAC;IAEzE,uBAAuB;IACvB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO;YACL,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,8BAA8B,YAAY,EAAE;SACtD,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACvD,IAAI,QAA6B,CAAC;IAElC,IAAI,CAAC;QACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO;YACL,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,4BAA4B,QAAQ,UAAU,CAAC,EAAE;SAC3D,CAAC;IACJ,CAAC;IAED,0CAA0C;IAC1C,MAAM,cAAc,GAAG,IAAA,kCAAiB,EAAC,QAAQ,CAAC,CAAC;IACnD,MAAM,mBAAmB,GAAG,KAAK,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;IAE1D,
|
|
1
|
+
{"version":3,"file":"i18n-updater.js","sourceRoot":"","sources":["../../../../scripts/generate-web-module/utils/i18n-updater.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqBH,gCAkGC;AAQD,kDAGC;AAhID,uCAAyB;AAEzB,mEAAmE;AAQnE;;;;;;;;GAQG;AACH,SAAgB,UAAU,CACxB,IAA0B,EAC1B,WAAmB,EACnB,WAAmB,IAAI,EACvB,SAAkB,KAAK;IAEvB,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IACjC,MAAM,YAAY,GAAG,GAAG,WAAW,sBAAsB,QAAQ,OAAO,CAAC;IAEzE,uBAAuB;IACvB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO;YACL,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,8BAA8B,YAAY,EAAE;SACtD,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACvD,IAAI,QAA6B,CAAC;IAElC,IAAI,CAAC;QACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO;YACL,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,4BAA4B,QAAQ,UAAU,CAAC,EAAE;SAC3D,CAAC;IACJ,CAAC;IAED,0CAA0C;IAC1C,MAAM,cAAc,GAAG,IAAA,kCAAiB,EAAC,QAAQ,CAAC,CAAC;IACnD,MAAM,mBAAmB,GAAG,KAAK,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;IAE1D,6EAA6E;IAC7E,IAAI,eAAe,GAAG,KAAK,CAAC;IAC5B,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACvB,QAAQ,CAAC,QAAQ,GAAG,EAAE,CAAC;IACzB,CAAC;IACD,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5D,MAAM,kBAAkB,GAAG,KAAK,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;IAC3D,IAAI,WAAW,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC1D,QAAQ,CAAC,QAAQ,CAAC,kBAAkB,CAAC,GAAG,cAAc,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAC7E,eAAe,GAAG,IAAI,CAAC;IACzB,CAAC;IAED,6CAA6C;IAC7C,MAAM,oBAAoB,GAAG,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC;IAEzF,IAAI,oBAAoB,EAAE,CAAC;QACzB,iDAAiD;QACjD,IAAI,eAAe,EAAE,CAAC;YACpB,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,OAAO,EAAE,oBAAoB,KAAK,CAAC,SAAS,+BAA+B,kBAAkB,EAAE;oBAC/F,aAAa,EAAE,IAAI;iBACpB,CAAC;YACJ,CAAC;YAED,8CAA8C;YAC9C,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACzD,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;YAExD,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,UAAU,KAAK,CAAC,SAAS,2BAA2B,kBAAkB,EAAE;gBACjF,aAAa,EAAE,IAAI;aACpB,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,UAAU,KAAK,CAAC,SAAS,+BAA+B,QAAQ,OAAO;YAChF,aAAa,EAAE,IAAI;SACpB,CAAC;IACJ,CAAC;IAED,uCAAuC;IACvC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACvB,QAAQ,CAAC,QAAQ,GAAG,EAAE,CAAC;IACzB,CAAC;IACD,QAAQ,CAAC,QAAQ,CAAC,mBAAmB,CAAC,GAAG,cAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAEtF,IAAI,MAAM,EAAE,CAAC;QACX,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,mCAAmC,QAAQ,cAAc,KAAK,CAAC,SAAS,eAAe;SACjG,CAAC;IACJ,CAAC;IAED,+CAA+C;IAC/C,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACzD,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;IAExD,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,oBAAoB,QAAQ,cAAc,KAAK,CAAC,SAAS,eAAe;KAClF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,mBAAmB,CAAC,IAA0B;IAC5D,MAAM,cAAc,GAAG,IAAA,kCAAiB,EAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxD,OAAO,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACjD,CAAC"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Exports all utility functions.
|
|
5
5
|
*/
|
|
6
|
-
export { writeFile, writeFiles, printResults, type WriteOptions, type WriteResult } from "./file-writer";
|
|
6
|
+
export { writeFile, writeFiles, formatFiles, printResults, type WriteOptions, type WriteResult } from "./file-writer";
|
|
7
7
|
export { updateBootstrapper, generateImportStatement, generateModuleEntry, type BootstrapperUpdateResult } from "./bootstrapper-updater";
|
|
8
8
|
export { updateI18n, previewI18nMessages, type I18nUpdateResult } from "./i18n-updater";
|
|
9
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../scripts/generate-web-module/utils/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../scripts/generate-web-module/utils/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AACtH,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,KAAK,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AACzI,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
* Exports all utility functions.
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.previewI18nMessages = exports.updateI18n = exports.generateModuleEntry = exports.generateImportStatement = exports.updateBootstrapper = exports.printResults = exports.writeFiles = exports.writeFile = void 0;
|
|
8
|
+
exports.previewI18nMessages = exports.updateI18n = exports.generateModuleEntry = exports.generateImportStatement = exports.updateBootstrapper = exports.printResults = exports.formatFiles = exports.writeFiles = exports.writeFile = void 0;
|
|
9
9
|
var file_writer_1 = require("./file-writer");
|
|
10
10
|
Object.defineProperty(exports, "writeFile", { enumerable: true, get: function () { return file_writer_1.writeFile; } });
|
|
11
11
|
Object.defineProperty(exports, "writeFiles", { enumerable: true, get: function () { return file_writer_1.writeFiles; } });
|
|
12
|
+
Object.defineProperty(exports, "formatFiles", { enumerable: true, get: function () { return file_writer_1.formatFiles; } });
|
|
12
13
|
Object.defineProperty(exports, "printResults", { enumerable: true, get: function () { return file_writer_1.printResults; } });
|
|
13
14
|
var bootstrapper_updater_1 = require("./bootstrapper-updater");
|
|
14
15
|
Object.defineProperty(exports, "updateBootstrapper", { enumerable: true, get: function () { return bootstrapper_updater_1.updateBootstrapper; } });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../scripts/generate-web-module/utils/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../scripts/generate-web-module/utils/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH,6CAAsH;AAA7G,wGAAA,SAAS,OAAA;AAAE,yGAAA,UAAU,OAAA;AAAE,0GAAA,WAAW,OAAA;AAAE,2GAAA,YAAY,OAAA;AACzD,+DAAyI;AAAhI,0HAAA,kBAAkB,OAAA;AAAE,+HAAA,uBAAuB,OAAA;AAAE,2HAAA,mBAAmB,OAAA;AACzE,+CAAwF;AAA/E,0GAAA,UAAU,OAAA;AAAE,mHAAA,mBAAmB,OAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carlonicora/nextjs-jsonapi",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.52.0",
|
|
4
4
|
"description": "Next.js JSON:API client with server/client support and caching",
|
|
5
5
|
"author": "Carlo Nicora",
|
|
6
6
|
"license": "GPL-3.0-or-later",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
58
|
"build": "NODE_OPTIONS='--max-old-space-size=8192' tsup && tsc -p scripts/generate-web-module/tsconfig.json",
|
|
59
|
-
"dev": "tsup --watch",
|
|
59
|
+
"dev": "NODE_OPTIONS='--max-old-space-size=8192' tsup --watch --no-dts",
|
|
60
60
|
"clean": "rm -rf dist",
|
|
61
61
|
"lint": "eslint \"src/**/*.ts\" \"src/**/*.tsx\" --fix",
|
|
62
62
|
"format": "prettier --write \"src/**/*.ts\"",
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
generateDetailsTemplate,
|
|
16
16
|
generateEditorTemplate,
|
|
17
17
|
generateFieldsTemplate,
|
|
18
|
+
generateAliasesTemplate,
|
|
18
19
|
generateInterfaceTemplate,
|
|
19
20
|
generateListContainerTemplate,
|
|
20
21
|
generateListPageTemplate,
|
|
@@ -33,7 +34,7 @@ import { toCamelCase, transformNames } from "./transformers/name-transformer";
|
|
|
33
34
|
import { detectExtendsContent } from "./transformers/parent-detector";
|
|
34
35
|
import { generateServiceMethods, resolveRelationships } from "./transformers/relationship-resolver";
|
|
35
36
|
import { FrontendTemplateData, GeneratedFile, GenerateWebModuleOptions, JsonModuleDefinition } from "./types";
|
|
36
|
-
import { printResults, updateBootstrapper, updateI18n, writeFiles } from "./utils";
|
|
37
|
+
import { formatFiles, printResults, updateBootstrapper, updateI18n, writeFiles } from "./utils";
|
|
37
38
|
import { parseAndValidate, validationPassed } from "./validators/json-schema-validator";
|
|
38
39
|
|
|
39
40
|
/**
|
|
@@ -78,6 +79,10 @@ export async function generateWebModule(options: GenerateWebModuleOptions): Prom
|
|
|
78
79
|
}
|
|
79
80
|
console.info(` Web base path: ${webBasePath}`);
|
|
80
81
|
|
|
82
|
+
// Build target hasName map from all structure files for cross-module awareness
|
|
83
|
+
const structureDir = path.dirname(jsonPath);
|
|
84
|
+
const targetHasNameMap = buildTargetHasNameMap(structureDir);
|
|
85
|
+
|
|
81
86
|
for (let i = 0; i < total; i++) {
|
|
82
87
|
const schema = schemas[i];
|
|
83
88
|
console.info(`\n📦 Processing module ${i + 1}/${total}: ${schema.moduleName}`);
|
|
@@ -85,7 +90,7 @@ export async function generateWebModule(options: GenerateWebModuleOptions): Prom
|
|
|
85
90
|
|
|
86
91
|
// Step 2: Build template data
|
|
87
92
|
console.info("🔨 Building template data...");
|
|
88
|
-
const templateData = buildTemplateData(schema);
|
|
93
|
+
const templateData = buildTemplateData(schema, targetHasNameMap);
|
|
89
94
|
console.info(` Module: ${templateData.names.pascalCase}`);
|
|
90
95
|
console.info(` Target: ${templateData.targetDir}`);
|
|
91
96
|
console.info(` Extends Content: ${templateData.extendsContent}`);
|
|
@@ -102,6 +107,12 @@ export async function generateWebModule(options: GenerateWebModuleOptions): Prom
|
|
|
102
107
|
const results = writeFiles(files, { dryRun, force });
|
|
103
108
|
printResults(results);
|
|
104
109
|
|
|
110
|
+
// Step 5b: Format files with Prettier
|
|
111
|
+
if (!dryRun) {
|
|
112
|
+
const writtenPaths = results.filter((r) => r.status === "created" || r.status === "updated").map((r) => r.path);
|
|
113
|
+
formatFiles(writtenPaths);
|
|
114
|
+
}
|
|
115
|
+
|
|
105
116
|
// Step 6: Update Bootstrapper (unless --no-register)
|
|
106
117
|
if (!noRegister) {
|
|
107
118
|
console.info("\n🔧 Updating Bootstrapper.ts...");
|
|
@@ -134,10 +145,37 @@ export async function generateWebModule(options: GenerateWebModuleOptions): Prom
|
|
|
134
145
|
return true;
|
|
135
146
|
}
|
|
136
147
|
|
|
148
|
+
/**
|
|
149
|
+
* Build a map of moduleName → hasNameField by scanning all structure files.
|
|
150
|
+
* Foundation entities (User, Company, etc.) always have name, so default to true for unknowns.
|
|
151
|
+
*/
|
|
152
|
+
function buildTargetHasNameMap(structureDir: string): Map<string, boolean> {
|
|
153
|
+
const map = new Map<string, boolean>();
|
|
154
|
+
|
|
155
|
+
if (!fs.existsSync(structureDir)) return map;
|
|
156
|
+
|
|
157
|
+
const files = fs.readdirSync(structureDir).filter((f) => f.endsWith(".json"));
|
|
158
|
+
for (const file of files) {
|
|
159
|
+
try {
|
|
160
|
+
const content = fs.readFileSync(path.join(structureDir, file), "utf-8");
|
|
161
|
+
const schemas: JsonModuleDefinition[] = JSON.parse(content);
|
|
162
|
+
for (const schema of schemas) {
|
|
163
|
+
const hasName =
|
|
164
|
+
schema.extendsContent === true || schema.fields.some((f) => f.name === "name");
|
|
165
|
+
map.set(schema.moduleName, hasName);
|
|
166
|
+
}
|
|
167
|
+
} catch {
|
|
168
|
+
// Skip invalid files
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return map;
|
|
173
|
+
}
|
|
174
|
+
|
|
137
175
|
/**
|
|
138
176
|
* Build template data from JSON schema
|
|
139
177
|
*/
|
|
140
|
-
function buildTemplateData(schema: JsonModuleDefinition): FrontendTemplateData {
|
|
178
|
+
function buildTemplateData(schema: JsonModuleDefinition, targetHasNameMap?: Map<string, boolean>): FrontendTemplateData {
|
|
141
179
|
const names = transformNames(schema.moduleName, schema.endpointName);
|
|
142
180
|
// Keep original targetDir for file path generation (buildFilePaths handles stripping)
|
|
143
181
|
const targetDir = schema.targetDir;
|
|
@@ -154,8 +192,25 @@ function buildTemplateData(schema: JsonModuleDefinition): FrontendTemplateData {
|
|
|
154
192
|
const fields = filterInheritedFields(allFields, inheritedFields);
|
|
155
193
|
|
|
156
194
|
// Resolve relationships
|
|
157
|
-
const relationships = resolveRelationships(schema.relationships);
|
|
158
|
-
|
|
195
|
+
const relationships = resolveRelationships(schema.relationships, targetHasNameMap);
|
|
196
|
+
|
|
197
|
+
// Determine which aliases conflict (multiple aliases targeting the same entity)
|
|
198
|
+
const entityAliasNames = new Map<string, string[]>();
|
|
199
|
+
for (const rel of relationships) {
|
|
200
|
+
if (rel.alias) {
|
|
201
|
+
const key = rel.name;
|
|
202
|
+
if (!entityAliasNames.has(key)) entityAliasNames.set(key, []);
|
|
203
|
+
entityAliasNames.get(key)!.push(rel.alias);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
const conflictingAliases = new Set<string>();
|
|
207
|
+
for (const aliases of entityAliasNames.values()) {
|
|
208
|
+
if (aliases.length > 1) {
|
|
209
|
+
for (const alias of aliases) conflictingAliases.add(alias);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const relationshipServiceMethods = generateServiceMethods(relationships, conflictingAliases);
|
|
159
214
|
|
|
160
215
|
// Build imports
|
|
161
216
|
const imports = buildImportStatements(relationships, extendsContent);
|
|
@@ -241,6 +296,16 @@ function generateAllFiles(data: FrontendTemplateData, schema: JsonModuleDefiniti
|
|
|
241
296
|
type: "data",
|
|
242
297
|
});
|
|
243
298
|
|
|
299
|
+
// Aliases file (only when module has aliased relationships)
|
|
300
|
+
const aliasesContent = generateAliasesTemplate(data);
|
|
301
|
+
if (aliasesContent) {
|
|
302
|
+
files.push({
|
|
303
|
+
path: paths.aliases,
|
|
304
|
+
content: aliasesContent,
|
|
305
|
+
type: "data",
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
|
|
244
309
|
// Form components (4 files)
|
|
245
310
|
files.push({
|
|
246
311
|
path: paths.editor,
|
|
@@ -36,47 +36,18 @@ import ${names.pascalCase}Content from "@/features/${data.importTargetDir}/${nam
|
|
|
36
36
|
import ${names.pascalCase}Details from "@/features/${data.importTargetDir}/${names.kebabCase}/components/details/${names.pascalCase}Details";
|
|
37
37
|
import { use${names.pascalCase}Context } from "@/features/${data.importTargetDir}/${names.kebabCase}/contexts/${names.pascalCase}Context";
|
|
38
38
|
import { ${names.pascalCase}Interface } from "@/features/${data.importTargetDir}/${names.kebabCase}/data/${names.pascalCase}Interface";
|
|
39
|
-
import {
|
|
40
|
-
|
|
41
|
-
PageContentContainer,
|
|
42
|
-
RelevantContentsList,
|
|
43
|
-
RelevantUsersList,
|
|
44
|
-
} from "@carlonicora/nextjs-jsonapi/components";
|
|
45
|
-
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@carlonicora/nextjs-jsonapi/components";
|
|
46
|
-
import { useTranslations } from "next-intl";
|
|
39
|
+
import { RoundPageContainer } from "@carlonicora/nextjs-jsonapi/components";
|
|
40
|
+
import { Modules } from "@carlonicora/nextjs-jsonapi/core";
|
|
47
41
|
|
|
48
42
|
type ${names.pascalCase}ContainerProps = {
|
|
49
43
|
${names.camelCase}: ${names.pascalCase}Interface;
|
|
50
44
|
};
|
|
51
45
|
|
|
52
46
|
function ${names.pascalCase}ContainerInternal({ ${names.camelCase} }: ${names.pascalCase}ContainerProps) {
|
|
53
|
-
const t = useTranslations();
|
|
54
|
-
|
|
55
47
|
return (
|
|
56
|
-
<
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
<AllowedUsersDetails showTitle content={${names.camelCase}} />
|
|
60
|
-
}
|
|
61
|
-
content={
|
|
62
|
-
<Tabs defaultValue={\`${names.camelCase}\`}>
|
|
63
|
-
<TabsList className="mb-4">
|
|
64
|
-
<TabsTrigger value="${names.camelCase}">{t(\`types.${names.pluralCamel}\`, { count: 1 })}</TabsTrigger>
|
|
65
|
-
<TabsTrigger value="contents">{t(\`generic.relevant\`)}</TabsTrigger>
|
|
66
|
-
<TabsTrigger value="users">{t(\`generic.relevant_users\`)}</TabsTrigger>
|
|
67
|
-
</TabsList>
|
|
68
|
-
<TabsContent value="${names.camelCase}">
|
|
69
|
-
<${names.pascalCase}Content />
|
|
70
|
-
</TabsContent>
|
|
71
|
-
<TabsContent value="contents">
|
|
72
|
-
<RelevantContentsList id={${names.camelCase}.id} />
|
|
73
|
-
</TabsContent>
|
|
74
|
-
<TabsContent value="users">
|
|
75
|
-
<RelevantUsersList id={${names.camelCase}.id} />
|
|
76
|
-
</TabsContent>
|
|
77
|
-
</Tabs>
|
|
78
|
-
}
|
|
79
|
-
/>
|
|
48
|
+
<RoundPageContainer module={Modules.${names.pascalCase}} details={<${names.pascalCase}Details />}>
|
|
49
|
+
<${names.pascalCase}Content />
|
|
50
|
+
</RoundPageContainer>
|
|
80
51
|
);
|
|
81
52
|
}
|
|
82
53
|
|
|
@@ -100,7 +71,8 @@ function generateSimpleContainerTemplate(data: FrontendTemplateData): string {
|
|
|
100
71
|
import ${names.pascalCase}Details from "@/features/${data.importTargetDir}/${names.kebabCase}/components/details/${names.pascalCase}Details";
|
|
101
72
|
import { use${names.pascalCase}Context } from "@/features/${data.importTargetDir}/${names.kebabCase}/contexts/${names.pascalCase}Context";
|
|
102
73
|
import { ${names.pascalCase}Interface } from "@/features/${data.importTargetDir}/${names.kebabCase}/data/${names.pascalCase}Interface";
|
|
103
|
-
import {
|
|
74
|
+
import { RoundPageContainer } from "@carlonicora/nextjs-jsonapi/components";
|
|
75
|
+
import { Modules } from "@carlonicora/nextjs-jsonapi/core";
|
|
104
76
|
|
|
105
77
|
type ${names.pascalCase}ContainerProps = {
|
|
106
78
|
${names.camelCase}: ${names.pascalCase}Interface;
|
|
@@ -108,14 +80,11 @@ type ${names.pascalCase}ContainerProps = {
|
|
|
108
80
|
|
|
109
81
|
function ${names.pascalCase}ContainerInternal({ ${names.camelCase} }: ${names.pascalCase}ContainerProps) {
|
|
110
82
|
return (
|
|
111
|
-
<
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
</div>
|
|
117
|
-
}
|
|
118
|
-
/>
|
|
83
|
+
<RoundPageContainer module={Modules.${names.pascalCase}} details={<${names.pascalCase}Details />}>
|
|
84
|
+
<div className="flex w-full flex-col gap-y-4">
|
|
85
|
+
{/* Add custom content sections here */}
|
|
86
|
+
</div>
|
|
87
|
+
</RoundPageContainer>
|
|
119
88
|
);
|
|
120
89
|
}
|
|
121
90
|
|
|
@@ -91,20 +91,22 @@ function generateAttributeElements(data: FrontendTemplateData): string {
|
|
|
91
91
|
relationships
|
|
92
92
|
.filter((rel) => rel.variant !== "Author") // Skip author, usually shown in title
|
|
93
93
|
.forEach((rel) => {
|
|
94
|
+
const displayProp = rel.targetHasName ? "name" : "id";
|
|
94
95
|
if (rel.single) {
|
|
95
|
-
const propName = toCamelCase(rel.variant || rel.name);
|
|
96
|
+
const propName = toCamelCase(rel.alias || rel.variant || rel.name);
|
|
96
97
|
elements.push(` {${names.camelCase}.${propName} && (
|
|
97
98
|
<AttributeElement
|
|
98
99
|
title={t(\`generic.relationships.${propName}.label\`)}
|
|
99
|
-
value={${names.camelCase}.${propName}
|
|
100
|
+
value={${names.camelCase}.${propName}.${displayProp}}
|
|
100
101
|
/>
|
|
101
102
|
)}`);
|
|
102
103
|
} else {
|
|
103
|
-
const
|
|
104
|
+
const effectiveMany = rel.alias || rel.name;
|
|
105
|
+
const propName = pluralize(toCamelCase(effectiveMany));
|
|
104
106
|
elements.push(` {${names.camelCase}.${propName} && ${names.camelCase}.${propName}.length > 0 && (
|
|
105
107
|
<AttributeElement
|
|
106
|
-
title={t(\`
|
|
107
|
-
value={${names.camelCase}.${propName}.map((item) => item
|
|
108
|
+
title={t(\`entities.${pluralize(rel.name.toLowerCase())}\`, { count: 2 })}
|
|
109
|
+
value={${names.camelCase}.${propName}.map((item) => item.${displayProp}).join(", ")}
|
|
108
110
|
/>
|
|
109
111
|
)}`);
|
|
110
112
|
}
|
|
@@ -24,6 +24,8 @@ import {
|
|
|
24
24
|
*/
|
|
25
25
|
export function generateEditorTemplate(data: FrontendTemplateData): string {
|
|
26
26
|
const { names, fields, relationships, extendsContent } = data;
|
|
27
|
+
const hasNameField = extendsContent || fields.some((f) => f.name === "name");
|
|
28
|
+
const i18nKey = names.pluralCamel.toLowerCase();
|
|
27
29
|
|
|
28
30
|
const imports = generateImports(data);
|
|
29
31
|
const propsType = generatePropsType(data);
|
|
@@ -122,7 +124,7 @@ ${onSubmit}
|
|
|
122
124
|
<DialogContent
|
|
123
125
|
className="flex max-h-[70vh] max-w-3xl flex-col overflow-y-auto"
|
|
124
126
|
>
|
|
125
|
-
<CommonEditorHeader type={t(\`
|
|
127
|
+
<CommonEditorHeader type={t(\`entities.${i18nKey}\`, { count: 1 })}${hasNameField ? ` name={${names.camelCase}?.name}` : ""} />
|
|
126
128
|
<Form {...form}>
|
|
127
129
|
<form onSubmit={form.handleSubmit(onSubmit)} className="flex w-full flex-col gap-y-4">
|
|
128
130
|
<div className="flex flex-col justify-between gap-x-4">
|
|
@@ -159,17 +161,23 @@ function generateImports(data: FrontendTemplateData): string {
|
|
|
159
161
|
`import { ${names.pascalCase}Service } from "@/features/${data.importTargetDir}/${names.kebabCase}/data/${names.pascalCase}Service";`,
|
|
160
162
|
);
|
|
161
163
|
|
|
162
|
-
// Relationship selector imports
|
|
164
|
+
// Relationship selector imports (deduplicated - multiple aliases may target the same entity)
|
|
163
165
|
const hasAuthor = relationships.some((r) => r.variant === AUTHOR_VARIANT);
|
|
166
|
+
const seenImports = new Set<string>();
|
|
164
167
|
|
|
165
168
|
relationships.forEach((rel) => {
|
|
166
169
|
if (rel.variant === AUTHOR_VARIANT) {
|
|
167
|
-
|
|
170
|
+
if (!seenImports.has("UserInterface")) {
|
|
171
|
+
seenImports.add("UserInterface");
|
|
172
|
+
imports.push(`import { UserInterface } from "@/features/foundations/user/data/UserInterface";`);
|
|
173
|
+
}
|
|
168
174
|
} else {
|
|
169
175
|
// Foundation components use MultiSelect, generated modules use MultiSelector
|
|
170
176
|
const componentName = rel.single
|
|
171
177
|
? `${rel.name}Selector`
|
|
172
178
|
: (rel.isFoundation ? `${rel.name}MultiSelect` : `${rel.name}MultiSelector`);
|
|
179
|
+
if (seenImports.has(componentName)) return;
|
|
180
|
+
seenImports.add(componentName);
|
|
173
181
|
if (rel.isFoundation) {
|
|
174
182
|
// Foundation entities use named imports from the package
|
|
175
183
|
imports.push(`import { ${componentName} } from "${FOUNDATION_COMPONENTS_PACKAGE}";`);
|
|
@@ -291,7 +299,7 @@ function generateFormSchema(data: FrontendTemplateData): string {
|
|
|
291
299
|
}
|
|
292
300
|
|
|
293
301
|
fieldsToInclude.forEach((field) => {
|
|
294
|
-
if (field.
|
|
302
|
+
if (field.isContentField) {
|
|
295
303
|
schemaFields.push(` ${field.name}: z.any(),`);
|
|
296
304
|
} else if (field.type === "string") {
|
|
297
305
|
if (field.nullable) {
|
|
@@ -308,7 +316,7 @@ function generateFormSchema(data: FrontendTemplateData): string {
|
|
|
308
316
|
|
|
309
317
|
// Relationship fields
|
|
310
318
|
relationships.forEach((rel) => {
|
|
311
|
-
const fieldId = toCamelCase(rel.variant || rel.name);
|
|
319
|
+
const fieldId = toCamelCase(rel.alias || rel.variant || rel.name);
|
|
312
320
|
const fieldIdLower = fieldId.toLowerCase();
|
|
313
321
|
if (rel.variant === AUTHOR_VARIANT) {
|
|
314
322
|
schemaFields.push(` ${fieldId}: userObjectSchema.refine((data) => data.id && data.id.length > 0, {
|
|
@@ -335,7 +343,7 @@ function generateFormSchema(data: FrontendTemplateData): string {
|
|
|
335
343
|
break;
|
|
336
344
|
case "date":
|
|
337
345
|
case "datetime":
|
|
338
|
-
schemaFields.push(` ${field.name}: z.
|
|
346
|
+
schemaFields.push(` ${field.name}: z.date()${optional},`);
|
|
339
347
|
break;
|
|
340
348
|
case "any":
|
|
341
349
|
schemaFields.push(` ${field.name}: z.any()${optional},`);
|
|
@@ -378,7 +386,7 @@ function generateDefaultValues(data: FrontendTemplateData): string {
|
|
|
378
386
|
: fields;
|
|
379
387
|
|
|
380
388
|
fieldsToInclude.forEach((field) => {
|
|
381
|
-
if (field.
|
|
389
|
+
if (field.isContentField) {
|
|
382
390
|
defaults.push(` ${field.name}: ${names.camelCase}?.${field.name} || [],`);
|
|
383
391
|
} else if (field.type === "string") {
|
|
384
392
|
defaults.push(` ${field.name}: ${names.camelCase}?.${field.name} || "",`);
|
|
@@ -393,17 +401,18 @@ function generateDefaultValues(data: FrontendTemplateData): string {
|
|
|
393
401
|
|
|
394
402
|
// Relationship defaults
|
|
395
403
|
relationships.forEach((rel) => {
|
|
396
|
-
const fieldId = toCamelCase(rel.variant || rel.name);
|
|
397
|
-
const propertyName = rel.variant ? toCamelCase(rel.variant) : toCamelCase(rel.name);
|
|
398
|
-
const pluralPropertyName = pluralize(toCamelCase(rel.name));
|
|
404
|
+
const fieldId = toCamelCase(rel.alias || rel.variant || rel.name);
|
|
405
|
+
const propertyName = rel.alias ? toCamelCase(rel.alias) : rel.variant ? toCamelCase(rel.variant) : toCamelCase(rel.name);
|
|
406
|
+
const pluralPropertyName = pluralize(toCamelCase(rel.alias || rel.name));
|
|
399
407
|
|
|
400
408
|
if (rel.variant === AUTHOR_VARIANT) {
|
|
401
409
|
defaults.push(` ${fieldId}: ${names.camelCase}?.${propertyName}
|
|
402
410
|
? { id: ${names.camelCase}.${propertyName}.id, name: ${names.camelCase}.${propertyName}.name, avatar: ${names.camelCase}.${propertyName}.avatar }
|
|
403
411
|
: undefined,`);
|
|
404
412
|
} else if (rel.single) {
|
|
413
|
+
const displayProp = rel.targetHasName ? "name" : "id";
|
|
405
414
|
defaults.push(` ${fieldId}: ${names.camelCase}?.${propertyName}
|
|
406
|
-
? { id: ${names.camelCase}.${propertyName}.id, name: ${names.camelCase}.${propertyName}
|
|
415
|
+
? { id: ${names.camelCase}.${propertyName}.id, name: ${names.camelCase}.${propertyName}.${displayProp} }
|
|
407
416
|
: undefined,`);
|
|
408
417
|
// Add relationship property field defaults
|
|
409
418
|
if (rel.fields && rel.fields.length > 0) {
|
|
@@ -428,8 +437,9 @@ function generateDefaultValues(data: FrontendTemplateData): string {
|
|
|
428
437
|
});
|
|
429
438
|
}
|
|
430
439
|
} else {
|
|
440
|
+
const displayProp = rel.targetHasName ? "name" : "id";
|
|
431
441
|
defaults.push(` ${fieldId}: ${names.camelCase}?.${pluralPropertyName}
|
|
432
|
-
? ${names.camelCase}.${pluralPropertyName}.map((item) => ({ id: item.id, name: item
|
|
442
|
+
? ${names.camelCase}.${pluralPropertyName}.map((item) => ({ id: item.id, name: item.${displayProp} }))
|
|
433
443
|
: [],`);
|
|
434
444
|
}
|
|
435
445
|
});
|
|
@@ -465,8 +475,8 @@ function generateOnSubmit(data: FrontendTemplateData): string {
|
|
|
465
475
|
|
|
466
476
|
// Relationships
|
|
467
477
|
relationships.forEach((rel) => {
|
|
468
|
-
const fieldId = toCamelCase(rel.variant || rel.name);
|
|
469
|
-
const payloadKey = rel.single ? `${fieldId}Id` : `${toCamelCase(rel.name)}Ids`;
|
|
478
|
+
const fieldId = toCamelCase(rel.alias || rel.variant || rel.name);
|
|
479
|
+
const payloadKey = rel.single ? `${fieldId}Id` : `${toCamelCase(rel.alias || rel.name)}Ids`;
|
|
470
480
|
|
|
471
481
|
if (rel.single) {
|
|
472
482
|
payloadFields.push(` ${payloadKey}: values.${fieldId}?.id,`);
|
|
@@ -529,7 +539,7 @@ function generateFormFields(data: FrontendTemplateData): string {
|
|
|
529
539
|
: fields;
|
|
530
540
|
|
|
531
541
|
fieldsToInclude.forEach((field) => {
|
|
532
|
-
if (field.
|
|
542
|
+
if (field.isContentField) {
|
|
533
543
|
formElements.push(` <BlockNoteEditorContainer
|
|
534
544
|
id={form.getValues("id")}
|
|
535
545
|
type="${names.camelCase}"
|
|
@@ -567,7 +577,7 @@ function generateFormFields(data: FrontendTemplateData): string {
|
|
|
567
577
|
return;
|
|
568
578
|
}
|
|
569
579
|
|
|
570
|
-
const fieldId = toCamelCase(rel.variant || rel.name);
|
|
580
|
+
const fieldId = toCamelCase(rel.alias || rel.variant || rel.name);
|
|
571
581
|
const fieldIdLower = fieldId.toLowerCase();
|
|
572
582
|
|
|
573
583
|
if (rel.single) {
|
|
@@ -625,7 +635,7 @@ function generateFormFields(data: FrontendTemplateData): string {
|
|
|
625
635
|
formElements.push(` <${multiComponentName}
|
|
626
636
|
id="${fieldId}"
|
|
627
637
|
form={form}
|
|
628
|
-
label={t(\`
|
|
638
|
+
label={t(\`entities.${pluralize(rel.name.toLowerCase())}\`, { count: 2 })}
|
|
629
639
|
/>`);
|
|
630
640
|
}
|
|
631
641
|
});
|
|
@@ -49,7 +49,7 @@ export default function ${names.pascalCase}List() {
|
|
|
49
49
|
fields={[${displayFields}]}
|
|
50
50
|
tableGeneratorType={Modules.${names.pascalCase}}
|
|
51
51
|
functions={functions}
|
|
52
|
-
title={t(\`
|
|
52
|
+
title={t(\`entities.${names.pluralCamel.toLowerCase()}\`, { count: 2 })}
|
|
53
53
|
/>
|
|
54
54
|
);
|
|
55
55
|
}
|
|
@@ -78,9 +78,10 @@ function buildDisplayFields(data: FrontendTemplateData): string {
|
|
|
78
78
|
// Add first non-author relationship
|
|
79
79
|
const otherRel = relationships.find((r) => r.variant !== "Author");
|
|
80
80
|
if (otherRel) {
|
|
81
|
+
const effectiveName = otherRel.alias || otherRel.variant || otherRel.name;
|
|
81
82
|
const relFieldName = otherRel.single
|
|
82
|
-
? toCamelCase(
|
|
83
|
-
: pluralize(toCamelCase(
|
|
83
|
+
? toCamelCase(effectiveName)
|
|
84
|
+
: pluralize(toCamelCase(effectiveName));
|
|
84
85
|
displayFields.push(`${names.pascalCase}Fields.${relFieldName}`);
|
|
85
86
|
}
|
|
86
87
|
|
|
@@ -13,7 +13,9 @@ import { FrontendTemplateData } from "../../types/template-data.interface";
|
|
|
13
13
|
* @returns Generated file content
|
|
14
14
|
*/
|
|
15
15
|
export function generateMultiSelectorTemplate(data: FrontendTemplateData): string {
|
|
16
|
-
const { names } = data;
|
|
16
|
+
const { names, fields, extendsContent } = data;
|
|
17
|
+
const hasNameField = extendsContent || fields.some((f) => f.name === "name");
|
|
18
|
+
const displayProp = hasNameField ? "name" : "id";
|
|
17
19
|
|
|
18
20
|
return `"use client";
|
|
19
21
|
|
|
@@ -91,7 +93,7 @@ export default function ${names.pascalCase}MultiSelector({
|
|
|
91
93
|
const filtered${names.pluralPascal} = ${names.pluralCamel}.filter((${names.camelCase}) => ${names.camelCase}.id !== current${names.pascalCase}?.id);
|
|
92
94
|
|
|
93
95
|
const options: ${names.pascalCase}Option[] = filtered${names.pluralPascal}.map((${names.camelCase}) => ({
|
|
94
|
-
label: ${names.camelCase}
|
|
96
|
+
label: ${names.camelCase}.${displayProp},
|
|
95
97
|
value: ${names.camelCase}.id,
|
|
96
98
|
${names.camelCase}Data: ${names.camelCase},
|
|
97
99
|
}));
|
|
@@ -101,7 +103,7 @@ export default function ${names.pascalCase}MultiSelector({
|
|
|
101
103
|
const missingOptions: ${names.pascalCase}Option[] = selected${names.pluralPascal}
|
|
102
104
|
.filter((${names.camelCase}) => !existingOptionIds.has(${names.camelCase}.id))
|
|
103
105
|
.map((${names.camelCase}) => ({
|
|
104
|
-
label: ${names.camelCase}
|
|
106
|
+
label: ${names.camelCase}.${displayProp},
|
|
105
107
|
value: ${names.camelCase}.id,
|
|
106
108
|
${names.camelCase}Data: ${names.camelCase} as unknown as ${names.pascalCase}Interface,
|
|
107
109
|
}));
|
|
@@ -114,7 +116,7 @@ export default function ${names.pascalCase}MultiSelector({
|
|
|
114
116
|
const selectedOptions = useMemo(() => {
|
|
115
117
|
return selected${names.pluralPascal}.map((${names.camelCase}) => ({
|
|
116
118
|
value: ${names.camelCase}.id,
|
|
117
|
-
label: ${names.camelCase}
|
|
119
|
+
label: ${names.camelCase}.${displayProp},
|
|
118
120
|
}));
|
|
119
121
|
}, [selected${names.pluralPascal}]);
|
|
120
122
|
|