Skip to content

Commit 4cf31b5

Browse files
committed
feat(tools-forecast-plugins-entity-fields): Added the name type options to allow custom field names
The options `idName`, `createdByName`, `createdAtName`, `updatedByName`, `updatedAtName`, and `sequenceName` to allow users to specify custom data model field names
1 parent 63b5696 commit 4cf31b5

File tree

5 files changed

+89
-253
lines changed

5 files changed

+89
-253
lines changed

libs/contact/typescript/server/attachment/schema.4cast

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ generator js {
1111

1212
plugin entityFields {
1313
provider = "@stormstack/tools-forecast-plugins-entity-fields"
14+
idFormat = "snowflake"
1415
}
1516

1617
plugin crud {

tools/forecast/codegen/src/cli/plugin-manager.ts

Lines changed: 4 additions & 225 deletions
Original file line numberDiff line numberDiff line change
@@ -178,191 +178,6 @@ export class PluginManager {
178178
);
179179
}
180180
}
181-
182-
/*for (const pluginInfo of this._plugins) {
183-
let pluginModule: PluginModule;
184-
try {
185-
pluginModule = require(pluginModulePath);
186-
} catch (err) {
187-
ConsoleLogger.error(
188-
`Unable to load plugin module ${pluginProvider}: ${pluginModulePath}, ${err}`
189-
);
190-
throw new ProcessingError(
191-
`Unable to load plugin module ${pluginProvider}`
192-
);
193-
}
194-
195-
if (!pluginModule) {
196-
ConsoleLogger.error(`Plugin provider ${pluginProvider} is missing`);
197-
throw new ProcessingError(
198-
`Plugin provider ${pluginProvider} is missing`
199-
);
200-
}
201-
if (!pluginModule.generator) {
202-
ConsoleLogger.error(
203-
`Plugin provider ${pluginProvider} is missing a "generator" export`
204-
);
205-
throw new ProcessingError(
206-
`Plugin provider ${pluginProvider} is missing a "generator" export`
207-
);
208-
}
209-
if (!pluginModule.runner) {
210-
ConsoleLogger.error(
211-
`Plugin provider ${pluginProvider} is missing a "runner" export`
212-
);
213-
throw new ProcessingError(
214-
`Plugin provider ${pluginProvider} is missing a "runner" export`
215-
);
216-
}
217-
218-
const dependencies = this.getPluginDependencies(pluginModule);
219-
const pluginName = this.getPluginName(pluginModule, pluginProvider);
220-
const options: PluginOptions = {
221-
schemaPath: context.schemaPath,
222-
name: pluginName
223-
};
224-
225-
ConsoleLogger.debug(
226-
`Preparing to load plugin:
227-
${JSON.stringify(options)}`
228-
);
229-
230-
pluginDecl.fields.forEach(f => {
231-
const value = getLiteral(f.value) ?? getLiteralArray(f.value);
232-
if (value === undefined) {
233-
throw new ProcessingError(
234-
`${pluginName} Plugin: Invalid option value for ${f.name}`
235-
);
236-
}
237-
options[f.name] = value;
238-
});
239-
240-
const plugin = {
241-
name: pluginName,
242-
provider: pluginProvider,
243-
dependencies,
244-
options,
245-
run: pluginModule.default as PluginFunction,
246-
module: pluginModule
247-
};
248-
249-
ConsoleLogger.debug(
250-
`Loading plugin:
251-
${JSON.stringify(plugin)}`
252-
);
253-
254-
plugins.push(plugin);
255-
256-
if (
257-
pluginProvider === "@core/prisma" &&
258-
typeof options.output === "string"
259-
) {
260-
// record custom prisma output path
261-
prismaOutput = resolvePath(options.output, options);
262-
}
263-
}
264-
265-
// make sure prerequisites are included
266-
const corePlugins: Array<{
267-
provider: string;
268-
options?: Record<string, unknown>;
269-
}> = [
270-
{ provider: "@core/prisma" },
271-
{ provider: "@core/model-meta" },
272-
{ provider: "@core/access-policy" }
273-
];
274-
275-
if (
276-
getDataModels(context.schema).some(model =>
277-
hasValidationAttributes(model)
278-
)
279-
) {
280-
// '@core/zod' plugin is auto-enabled if there're validation rules
281-
corePlugins.push({
282-
provider: "@plugins/zod",
283-
options: { modelOnly: true }
284-
});
285-
}
286-
287-
// core plugins introduced by dependencies
288-
plugins
289-
.flatMap(p => p.dependencies)
290-
.forEach(dep => {
291-
if (dep.startsWith("@core/")) {
292-
const existing = corePlugins.find(p => p.provider === dep);
293-
if (existing) {
294-
// reset options to default
295-
existing.options = undefined;
296-
} else {
297-
// add core dependency
298-
corePlugins.push({ provider: dep });
299-
}
300-
}
301-
});
302-
303-
for (const corePlugin of corePlugins.reverse()) {
304-
const existingIdx = plugins.findIndex(
305-
p => p.provider === corePlugin.provider
306-
);
307-
if (existingIdx >= 0) {
308-
// shift the plugin to the front
309-
const existing = plugins[existingIdx];
310-
plugins.splice(existingIdx, 1);
311-
plugins.unshift(existing);
312-
} else {
313-
// synthesize a plugin and insert front
314-
const pluginModule = require(this.getPluginModulePath(
315-
corePlugin.provider
316-
));
317-
const pluginName = this.getPluginName(
318-
pluginModule,
319-
corePlugin.provider
320-
);
321-
plugins.unshift({
322-
name: pluginName,
323-
provider: corePlugin.provider,
324-
dependencies: [],
325-
options: {
326-
schemaPath: context.schemaPath,
327-
name: pluginName,
328-
...corePlugin.options
329-
},
330-
run: pluginModule.default,
331-
module: pluginModule
332-
});
333-
}
334-
}
335-
336-
// check dependencies
337-
for (const plugin of plugins) {
338-
for (const dep of plugin.dependencies) {
339-
if (!plugins.find(p => p.provider === dep)) {
340-
ConsoleLogger.error(
341-
`Plugin ${plugin.provider} depends on "${dep}" but it's not declared`
342-
);
343-
throw new ProcessingError(
344-
`Plugin ${plugin.name}: ${plugin.provider} depends on "${dep}" but it's not declared`
345-
);
346-
}
347-
}
348-
}
349-
350-
let dmmf: DMMF.Document | undefined = undefined;
351-
for (const { name, provider, run, options } of plugins) {
352-
const start = Date.now();
353-
await this.runPlugin(name, run, context, options, dmmf, warnings);
354-
ConsoleLogger.log(
355-
`✅ Plugin ${chalk.bold(name)} (${provider}) completed in ${
356-
Date.now() - start
357-
}ms`
358-
);
359-
if (provider === "@core/prisma") {
360-
// load prisma DMMF
361-
dmmf = await getDMMF({
362-
datamodel: fs.readFileSync(prismaOutput, { encoding: "utf-8" })
363-
});
364-
}
365-
}*/
366181
} else {
367182
ConsoleLogger.warn(
368183
"No plugins specified for this model. No processing will be performed (please ensure this is expected)."
@@ -400,31 +215,6 @@ ${JSON.stringify(plugin)}`
400215
return getLiteral<string>(providerField?.value);
401216
}
402217

403-
/*private async runPlugin(
404-
name: string,
405-
run: PluginFunction,
406-
context: Context,
407-
options: PluginOptions,
408-
dmmf: DMMF.Document | undefined,
409-
warnings: string[]
410-
) {
411-
ConsoleLogger.info(`Executing plugin ${chalk.bold.cyan(name)}`);
412-
413-
try {
414-
const result = Promise.resolve(run(context.model, options, dmmf, config));
415-
if (Array.isArray(result)) {
416-
warnings.push(...result);
417-
}
418-
419-
ConsoleLogger.success("Plugin completed successfully");
420-
} catch (err) {
421-
ConsoleLogger.error("Plugin failed to complete");
422-
ConsoleLogger.error(err);
423-
424-
throw err;
425-
}
426-
}*/
427-
428218
private getPluginModulePath(provider: string) {
429219
let pluginModulePath = provider;
430220
if (pluginModulePath.startsWith("@stormstack/")) {
@@ -437,19 +227,6 @@ ${JSON.stringify(plugin)}`
437227
)}`;
438228
}
439229

440-
/*if (pluginModulePath.startsWith("@core/")) {
441-
pluginModulePath = pluginModulePath.replace(
442-
/^@core\//,
443-
path.join(__dirname, "../../../forecast/plugins/")
444-
);
445-
}*/
446-
/*if (pluginModulePath.startsWith("@plugins/")) {
447-
pluginModulePath = pluginModulePath.replace(
448-
/^@plugins\//,
449-
path.join(__dirname, "../../../forecast/plugins/")
450-
);
451-
}*/
452-
453230
return pluginModulePath;
454231
}
455232

@@ -495,8 +272,10 @@ ${JSON.stringify(plugin)}`
495272
}
496273

497274
if (!pluginModule) {
498-
ConsoleLogger.error(`Plugin provider ${pluginProvider} is missing`);
499-
throw new ProcessingError(`Plugin provider ${pluginProvider} is missing`);
275+
ConsoleLogger.error(`Plugin provider ${pluginProvider} cannot be found`);
276+
throw new ProcessingError(
277+
`Plugin provider ${pluginProvider} cannot be found`
278+
);
500279
}
501280

502281
if (!pluginModule.name) {

tools/forecast/plugins/drizzle/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ export const generator = new TemplateGenerator<DrizzlePluginOptions>();
1313
export const handle: PluginHandler<DrizzlePluginOptions> =
1414
createTemplatePluginHandler(
1515
{
16-
templatePath: "templates/**",
1716
dataModelTemplatePath: "templates/schemas/**",
1817
enumTemplatePath: "templates/enums/**"
1918
},

tools/forecast/plugins/entity-fields/src/index.ts

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,42 @@ import {
1717
import {
1818
ENTITY_CLASS_FIELDS,
1919
EntityFieldsPluginOptions,
20-
IdentityFieldGenerator
20+
IdFieldFormat
2121
} from "./types";
2222

2323
export const name = "Entity Fields Extension";
2424

2525
export const options = {
26-
identityGenerator: IdentityFieldGenerator.SNOWFLAKE
26+
idName: "id",
27+
idFormat: IdFieldFormat.UUID,
28+
createdAtName: "createdAt",
29+
createdByName: "createdBy",
30+
updatedAtName: "updatedAt",
31+
updatedByName: "updatedBy",
32+
sequenceName: "sequence"
2733
};
2834

2935
export const extend: PluginExtend<EntityFieldsPluginOptions> = async (
30-
options: EntityFieldsPluginOptions,
36+
{
37+
idName,
38+
idFormat,
39+
createdAtName,
40+
createdByName,
41+
updatedAtName,
42+
updatedByName,
43+
sequenceName
44+
}: EntityFieldsPluginOptions,
3145
context: Context
3246
): Promise<Model> => {
3347
const model = context.model;
3448

3549
getDataModels(model).forEach(dataModel => {
3650
let idField: DataModelField = dataModel.fields.find(
37-
field => field.name?.toLowerCase() === "id".toLowerCase()
51+
field => field.name?.toLowerCase() === idName.toLowerCase()
3852
);
3953
if (!idField) {
4054
idField = {
41-
name: "id",
55+
name: idName,
4256
$container: dataModel,
4357
$type: "DataModelField",
4458
attributes: [],
@@ -104,17 +118,17 @@ export const extend: PluginExtend<EntityFieldsPluginOptions> = async (
104118
addDefaultValue(
105119
model,
106120
idField,
107-
options.identityGenerator ?? IdentityFieldGenerator.SNOWFLAKE,
121+
idFormat ?? IdFieldFormat.UUID,
108122
"FunctionDecl"
109123
);
110124
}
111125

112126
let createdAtField: DataModelField = dataModel.fields.find(
113-
field => field.name?.toLowerCase() === "createdAt".toLowerCase()
127+
field => field.name?.toLowerCase() === createdAtName.toLowerCase()
114128
);
115129
if (!createdAtField) {
116130
createdAtField = {
117-
name: "createdAt",
131+
name: createdAtName,
118132
$container: dataModel,
119133
$type: "DataModelField",
120134
attributes: [],
@@ -133,11 +147,11 @@ export const extend: PluginExtend<EntityFieldsPluginOptions> = async (
133147
}
134148

135149
let createdByField: DataModelField = dataModel.fields.find(
136-
field => field.name?.toLowerCase() === "createdBy".toLowerCase()
150+
field => field.name?.toLowerCase() === createdByName.toLowerCase()
137151
);
138152
if (!createdByField) {
139153
createdByField = {
140-
name: "createdBy",
154+
name: createdByName,
141155
$container: dataModel,
142156
$type: "DataModelField",
143157
attributes: [],
@@ -154,11 +168,11 @@ export const extend: PluginExtend<EntityFieldsPluginOptions> = async (
154168
}
155169

156170
let updatedAtField: DataModelField = dataModel.fields.find(
157-
field => field.name?.toLowerCase() === "updatedAt".toLowerCase()
171+
field => field.name?.toLowerCase() === updatedAtName.toLowerCase()
158172
);
159173
if (!updatedAtField) {
160174
updatedAtField = {
161-
name: "updatedAt",
175+
name: updatedAtName,
162176
$container: dataModel,
163177
$type: "DataModelField",
164178
attributes: [],
@@ -177,11 +191,11 @@ export const extend: PluginExtend<EntityFieldsPluginOptions> = async (
177191
}
178192

179193
let updatedByField: DataModelField = dataModel.fields.find(
180-
field => field.name?.toLowerCase() === "updatedBy".toLowerCase()
194+
field => field.name?.toLowerCase() === updatedByName.toLowerCase()
181195
);
182196
if (!updatedByField) {
183197
updatedByField = {
184-
name: "updatedBy",
198+
name: updatedByName,
185199
$container: dataModel,
186200
$type: "DataModelField",
187201
attributes: [],
@@ -198,11 +212,11 @@ export const extend: PluginExtend<EntityFieldsPluginOptions> = async (
198212
}
199213

200214
let sequenceField: DataModelField = dataModel.fields.find(
201-
field => field.name?.toLowerCase() === "sequence".toLowerCase()
215+
field => field.name?.toLowerCase() === sequenceName.toLowerCase()
202216
);
203217
if (!sequenceField) {
204218
sequenceField = {
205-
name: "sequence",
219+
name: sequenceName,
206220
$container: dataModel,
207221
$type: "DataModelField",
208222
attributes: [],

0 commit comments

Comments
 (0)