@fabricorg/gen-prisma 0.2.0 → 1.0.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/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - Require Platform 0.12 and Compiler 1.0 generated-artifact contracts.
8
+
9
+ ## 0.2.1
10
+
11
+ ### Patch Changes
12
+
13
+ - Close final uplift audit gaps: align Host 2.x documentation and migration evidence, surface every
14
+ compiler/generator API to LLM consumers, make memory outbox egress directly usable, sanitize relay
15
+ failures, validate complete archetype state maps, support recursive JSON Schema generation, reject
16
+ cross-platform path traversal, synchronize artifact version stamps, and include package licenses.
17
+ - Escape mapped field names and reject normalized property/relation or cross-module model collisions.
18
+ - Consume Platform as a peer dependency so applications keep a single copy of the public contracts.
19
+ - Updated dependencies
20
+ - @fabricorg/platform@0.11.1
21
+ - @fabricorg/compiler@0.2.1
22
+
3
23
  ## 0.2.0
4
24
 
5
25
  ### Minor Changes
package/dist/index.cjs CHANGED
@@ -39,11 +39,17 @@ var identifier = (value) => {
39
39
  };
40
40
  var prismaGenerator = {
41
41
  name: "@fabricorg/gen-prisma",
42
- version: "0.1.0",
42
+ version: "1.0.0",
43
43
  generate(ir) {
44
+ const modelNames = ir.modules.flatMap((module2) => module2.objectTypes.map((objectType) => `${pascal(module2.namespace)}${objectType.type}`));
45
+ if (new Set(modelNames).size !== modelNames.length) throw new Error("Manifest produces colliding Prisma model names across modules.");
44
46
  const models = ir.modules.flatMap((module2) => module2.objectTypes.map((objectType) => {
45
47
  const required = new Set(objectType.schema?.required ?? []);
46
- const fields = Object.entries(objectType.schema?.properties ?? {}).filter(([name]) => !["id", "tenantId", "spaceId"].includes(name)).map(([name, schema]) => ` ${identifier(name)} ${scalar(schema)}${required.has(name) ? "" : "?"}${identifier(name) === name ? "" : ` @map("${name}")`}`);
48
+ const properties = Object.entries(objectType.schema?.properties ?? {}).filter(([name]) => !["id", "tenantId", "spaceId"].includes(name));
49
+ const identifiers = properties.map(([name]) => identifier(name));
50
+ const relationIdentifiers = (objectType.relations ?? []).map((relation) => `${relation.name}Ids`);
51
+ if ((/* @__PURE__ */ new Set([...identifiers, ...relationIdentifiers])).size !== identifiers.length + relationIdentifiers.length) throw new Error(`Object "${module2.namespace}.${objectType.type}" produces colliding Prisma field names.`);
52
+ const fields = properties.map(([name, schema]) => ` ${identifier(name)} ${scalar(schema)}${required.has(name) ? "" : "?"}${identifier(name) === name ? "" : ` @map(${JSON.stringify(name)})`}`);
47
53
  const relations = (objectType.relations ?? []).map((relation) => ` ${relation.name}Ids String${relation.cardinality === "many" ? "[]" : relation.required ? "" : "?"} // ${relation.semantics} -> ${relation.target}`);
48
54
  return [`model ${pascal(module2.namespace)}${objectType.type} {`, " id String @id", " tenantId String", " spaceId String", ...fields, ...relations, "", " @@index([tenantId, spaceId])", ` @@map("${module2.namespace}_${objectType.type}")`, "}"].join("\n");
49
55
  }));
@@ -1 +1 @@
1
- {"version":3,"sources":["../index.ts"],"sourcesContent":["import type { GeneratorTarget } from \"@fabricorg/compiler\";\nimport type { PortableJsonSchema } from \"@fabricorg/platform\";\n\nconst scalar = (schema: PortableJsonSchema): string => {\n\tconst type = Array.isArray(schema.type) ? schema.type.find((item) => item !== \"null\") : schema.type;\n\tif (type === \"string\") return \"String\";\n\tif (type === \"integer\") return \"Int\";\n\tif (type === \"number\") return \"Float\";\n\tif (type === \"boolean\") return \"Boolean\";\n\tif (type === \"array\" || type === \"object\") return \"Json\";\n\treturn \"Json\";\n};\nconst pascal = (value: string): string => value.split(/[-._/]/).filter(Boolean).map((part) => part[0]?.toUpperCase() + part.slice(1)).join(\"\");\nconst identifier = (value: string): string => {\n\tconst normalized = value.replace(/[^a-zA-Z0-9_]/g, \"_\");\n\treturn /^[a-zA-Z]/.test(normalized) ? normalized : `field_${normalized}`;\n};\n\nexport const prismaGenerator: GeneratorTarget = {\n\tname: \"@fabricorg/gen-prisma\", version: \"0.1.0\",\n\tgenerate(ir) {\n\t\tconst models = ir.modules.flatMap((module) => module.objectTypes.map((objectType) => {\n\t\t\tconst required = new Set(objectType.schema?.required ?? []);\n\t\t\tconst fields = Object.entries(objectType.schema?.properties ?? {})\n\t\t\t\t.filter(([name]) => ![\"id\", \"tenantId\", \"spaceId\"].includes(name))\n\t\t\t\t.map(([name, schema]) => ` ${identifier(name)} ${scalar(schema)}${required.has(name) ? \"\" : \"?\"}${identifier(name) === name ? \"\" : ` @map(\"${name}\")`}`);\n\t\t\tconst relations = (objectType.relations ?? []).map((relation) => ` ${relation.name}Ids String${relation.cardinality === \"many\" ? \"[]\" : relation.required ? \"\" : \"?\"} // ${relation.semantics} -> ${relation.target}`);\n\t\t\treturn [`model ${pascal(module.namespace)}${objectType.type} {`, \" id String @id\", \" tenantId String\", \" spaceId String\", ...fields, ...relations, \"\", \" @@index([tenantId, spaceId])\", ` @@map(\"${module.namespace}_${objectType.type}\")`, \"}\"].join(\"\\n\");\n\t\t}));\n\t\tconst content = [`// Generated by ${prismaGenerator.name}@${prismaGenerator.version}`, `// Manifest digest: ${ir.manifestDigest}`, \"generator client {\\n provider = \\\"prisma-client-js\\\"\\n}\", \"datasource db {\\n provider = \\\"postgresql\\\"\\n url = env(\\\"DATABASE_URL\\\")\\n}\", \"\", ...models, \"\"].join(\"\\n\\n\");\n\t\treturn [{ path: \"prisma/schema.prisma\", content }, { path: \"prisma/compatibility.json\", content: JSON.stringify({ manifestDigest: ir.manifestDigest, automaticMigration: false, reviewRequired: true }, null, 2) }];\n\t},\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,IAAM,SAAS,CAAC,WAAuC;AACtD,QAAM,OAAO,MAAM,QAAQ,OAAO,IAAI,IAAI,OAAO,KAAK,KAAK,CAAC,SAAS,SAAS,MAAM,IAAI,OAAO;AAC/F,MAAI,SAAS,SAAU,QAAO;AAC9B,MAAI,SAAS,UAAW,QAAO;AAC/B,MAAI,SAAS,SAAU,QAAO;AAC9B,MAAI,SAAS,UAAW,QAAO;AAC/B,MAAI,SAAS,WAAW,SAAS,SAAU,QAAO;AAClD,SAAO;AACR;AACA,IAAM,SAAS,CAAC,UAA0B,MAAM,MAAM,QAAQ,EAAE,OAAO,OAAO,EAAE,IAAI,CAAC,SAAS,KAAK,CAAC,GAAG,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE;AAC7I,IAAM,aAAa,CAAC,UAA0B;AAC7C,QAAM,aAAa,MAAM,QAAQ,kBAAkB,GAAG;AACtD,SAAO,YAAY,KAAK,UAAU,IAAI,aAAa,SAAS,UAAU;AACvE;AAEO,IAAM,kBAAmC;AAAA,EAC/C,MAAM;AAAA,EAAyB,SAAS;AAAA,EACxC,SAAS,IAAI;AACZ,UAAM,SAAS,GAAG,QAAQ,QAAQ,CAACA,YAAWA,QAAO,YAAY,IAAI,CAAC,eAAe;AACpF,YAAM,WAAW,IAAI,IAAI,WAAW,QAAQ,YAAY,CAAC,CAAC;AAC1D,YAAM,SAAS,OAAO,QAAQ,WAAW,QAAQ,cAAc,CAAC,CAAC,EAC/D,OAAO,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,MAAM,YAAY,SAAS,EAAE,SAAS,IAAI,CAAC,EAChE,IAAI,CAAC,CAAC,MAAM,MAAM,MAAM,KAAK,WAAW,IAAI,CAAC,IAAI,OAAO,MAAM,CAAC,GAAG,SAAS,IAAI,IAAI,IAAI,KAAK,GAAG,GAAG,WAAW,IAAI,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI,EAAE;AACzJ,YAAM,aAAa,WAAW,aAAa,CAAC,GAAG,IAAI,CAAC,aAAa,KAAK,SAAS,IAAI,aAAa,SAAS,gBAAgB,SAAS,OAAO,SAAS,WAAW,KAAK,GAAG,OAAO,SAAS,SAAS,OAAO,SAAS,MAAM,EAAE;AACtN,aAAO,CAAC,SAAS,OAAOA,QAAO,SAAS,CAAC,GAAG,WAAW,IAAI,MAAM,mBAAmB,qBAAqB,oBAAoB,GAAG,QAAQ,GAAG,WAAW,IAAI,kCAAkC,YAAYA,QAAO,SAAS,IAAI,WAAW,IAAI,MAAM,GAAG,EAAE,KAAK,IAAI;AAAA,IAChQ,CAAC,CAAC;AACF,UAAM,UAAU,CAAC,mBAAmB,gBAAgB,IAAI,IAAI,gBAAgB,OAAO,IAAI,uBAAuB,GAAG,cAAc,IAAI,0DAA4D,mFAAuF,IAAI,GAAG,QAAQ,EAAE,EAAE,KAAK,MAAM;AACpT,WAAO,CAAC,EAAE,MAAM,wBAAwB,QAAQ,GAAG,EAAE,MAAM,6BAA6B,SAAS,KAAK,UAAU,EAAE,gBAAgB,GAAG,gBAAgB,oBAAoB,OAAO,gBAAgB,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC;AAAA,EACnN;AACD;","names":["module"]}
1
+ {"version":3,"sources":["../index.ts"],"sourcesContent":["import type { GeneratorTarget } from \"@fabricorg/compiler\";\nimport type { PortableJsonSchema } from \"@fabricorg/platform\";\n\nconst scalar = (schema: PortableJsonSchema): string => {\n\tconst type = Array.isArray(schema.type) ? schema.type.find((item) => item !== \"null\") : schema.type;\n\tif (type === \"string\") return \"String\";\n\tif (type === \"integer\") return \"Int\";\n\tif (type === \"number\") return \"Float\";\n\tif (type === \"boolean\") return \"Boolean\";\n\tif (type === \"array\" || type === \"object\") return \"Json\";\n\treturn \"Json\";\n};\nconst pascal = (value: string): string => value.split(/[-._/]/).filter(Boolean).map((part) => part[0]?.toUpperCase() + part.slice(1)).join(\"\");\nconst identifier = (value: string): string => {\n\tconst normalized = value.replace(/[^a-zA-Z0-9_]/g, \"_\");\n\treturn /^[a-zA-Z]/.test(normalized) ? normalized : `field_${normalized}`;\n};\n\nexport const prismaGenerator: GeneratorTarget = {\n\tname: \"@fabricorg/gen-prisma\", version: \"1.0.0\",\n\tgenerate(ir) {\n\t\tconst modelNames = ir.modules.flatMap((module) => module.objectTypes.map((objectType) => `${pascal(module.namespace)}${objectType.type}`));\n\t\tif (new Set(modelNames).size !== modelNames.length) throw new Error(\"Manifest produces colliding Prisma model names across modules.\");\n\t\tconst models = ir.modules.flatMap((module) => module.objectTypes.map((objectType) => {\n\t\t\tconst required = new Set(objectType.schema?.required ?? []);\n\t\t\tconst properties = Object.entries(objectType.schema?.properties ?? {}).filter(([name]) => ![\"id\", \"tenantId\", \"spaceId\"].includes(name));\n\t\t\tconst identifiers = properties.map(([name]) => identifier(name));\n\t\t\tconst relationIdentifiers = (objectType.relations ?? []).map((relation) => `${relation.name}Ids`);\n\t\t\tif (new Set([...identifiers, ...relationIdentifiers]).size !== identifiers.length + relationIdentifiers.length) throw new Error(`Object \"${module.namespace}.${objectType.type}\" produces colliding Prisma field names.`);\n\t\t\tconst fields = properties.map(([name, schema]) => ` ${identifier(name)} ${scalar(schema)}${required.has(name) ? \"\" : \"?\"}${identifier(name) === name ? \"\" : ` @map(${JSON.stringify(name)})`}`);\n\t\t\tconst relations = (objectType.relations ?? []).map((relation) => ` ${relation.name}Ids String${relation.cardinality === \"many\" ? \"[]\" : relation.required ? \"\" : \"?\"} // ${relation.semantics} -> ${relation.target}`);\n\t\t\treturn [`model ${pascal(module.namespace)}${objectType.type} {`, \" id String @id\", \" tenantId String\", \" spaceId String\", ...fields, ...relations, \"\", \" @@index([tenantId, spaceId])\", ` @@map(\"${module.namespace}_${objectType.type}\")`, \"}\"].join(\"\\n\");\n\t\t}));\n\t\tconst content = [`// Generated by ${prismaGenerator.name}@${prismaGenerator.version}`, `// Manifest digest: ${ir.manifestDigest}`, \"generator client {\\n provider = \\\"prisma-client-js\\\"\\n}\", \"datasource db {\\n provider = \\\"postgresql\\\"\\n url = env(\\\"DATABASE_URL\\\")\\n}\", \"\", ...models, \"\"].join(\"\\n\\n\");\n\t\treturn [{ path: \"prisma/schema.prisma\", content }, { path: \"prisma/compatibility.json\", content: JSON.stringify({ manifestDigest: ir.manifestDigest, automaticMigration: false, reviewRequired: true }, null, 2) }];\n\t},\n};\n"],"mappings":"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","names":["module"]}
package/dist/index.js CHANGED
@@ -15,11 +15,17 @@ var identifier = (value) => {
15
15
  };
16
16
  var prismaGenerator = {
17
17
  name: "@fabricorg/gen-prisma",
18
- version: "0.1.0",
18
+ version: "1.0.0",
19
19
  generate(ir) {
20
+ const modelNames = ir.modules.flatMap((module) => module.objectTypes.map((objectType) => `${pascal(module.namespace)}${objectType.type}`));
21
+ if (new Set(modelNames).size !== modelNames.length) throw new Error("Manifest produces colliding Prisma model names across modules.");
20
22
  const models = ir.modules.flatMap((module) => module.objectTypes.map((objectType) => {
21
23
  const required = new Set(objectType.schema?.required ?? []);
22
- const fields = Object.entries(objectType.schema?.properties ?? {}).filter(([name]) => !["id", "tenantId", "spaceId"].includes(name)).map(([name, schema]) => ` ${identifier(name)} ${scalar(schema)}${required.has(name) ? "" : "?"}${identifier(name) === name ? "" : ` @map("${name}")`}`);
24
+ const properties = Object.entries(objectType.schema?.properties ?? {}).filter(([name]) => !["id", "tenantId", "spaceId"].includes(name));
25
+ const identifiers = properties.map(([name]) => identifier(name));
26
+ const relationIdentifiers = (objectType.relations ?? []).map((relation) => `${relation.name}Ids`);
27
+ if ((/* @__PURE__ */ new Set([...identifiers, ...relationIdentifiers])).size !== identifiers.length + relationIdentifiers.length) throw new Error(`Object "${module.namespace}.${objectType.type}" produces colliding Prisma field names.`);
28
+ const fields = properties.map(([name, schema]) => ` ${identifier(name)} ${scalar(schema)}${required.has(name) ? "" : "?"}${identifier(name) === name ? "" : ` @map(${JSON.stringify(name)})`}`);
23
29
  const relations = (objectType.relations ?? []).map((relation) => ` ${relation.name}Ids String${relation.cardinality === "many" ? "[]" : relation.required ? "" : "?"} // ${relation.semantics} -> ${relation.target}`);
24
30
  return [`model ${pascal(module.namespace)}${objectType.type} {`, " id String @id", " tenantId String", " spaceId String", ...fields, ...relations, "", " @@index([tenantId, spaceId])", ` @@map("${module.namespace}_${objectType.type}")`, "}"].join("\n");
25
31
  }));
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../index.ts"],"sourcesContent":["import type { GeneratorTarget } from \"@fabricorg/compiler\";\nimport type { PortableJsonSchema } from \"@fabricorg/platform\";\n\nconst scalar = (schema: PortableJsonSchema): string => {\n\tconst type = Array.isArray(schema.type) ? schema.type.find((item) => item !== \"null\") : schema.type;\n\tif (type === \"string\") return \"String\";\n\tif (type === \"integer\") return \"Int\";\n\tif (type === \"number\") return \"Float\";\n\tif (type === \"boolean\") return \"Boolean\";\n\tif (type === \"array\" || type === \"object\") return \"Json\";\n\treturn \"Json\";\n};\nconst pascal = (value: string): string => value.split(/[-._/]/).filter(Boolean).map((part) => part[0]?.toUpperCase() + part.slice(1)).join(\"\");\nconst identifier = (value: string): string => {\n\tconst normalized = value.replace(/[^a-zA-Z0-9_]/g, \"_\");\n\treturn /^[a-zA-Z]/.test(normalized) ? normalized : `field_${normalized}`;\n};\n\nexport const prismaGenerator: GeneratorTarget = {\n\tname: \"@fabricorg/gen-prisma\", version: \"0.1.0\",\n\tgenerate(ir) {\n\t\tconst models = ir.modules.flatMap((module) => module.objectTypes.map((objectType) => {\n\t\t\tconst required = new Set(objectType.schema?.required ?? []);\n\t\t\tconst fields = Object.entries(objectType.schema?.properties ?? {})\n\t\t\t\t.filter(([name]) => ![\"id\", \"tenantId\", \"spaceId\"].includes(name))\n\t\t\t\t.map(([name, schema]) => ` ${identifier(name)} ${scalar(schema)}${required.has(name) ? \"\" : \"?\"}${identifier(name) === name ? \"\" : ` @map(\"${name}\")`}`);\n\t\t\tconst relations = (objectType.relations ?? []).map((relation) => ` ${relation.name}Ids String${relation.cardinality === \"many\" ? \"[]\" : relation.required ? \"\" : \"?\"} // ${relation.semantics} -> ${relation.target}`);\n\t\t\treturn [`model ${pascal(module.namespace)}${objectType.type} {`, \" id String @id\", \" tenantId String\", \" spaceId String\", ...fields, ...relations, \"\", \" @@index([tenantId, spaceId])\", ` @@map(\"${module.namespace}_${objectType.type}\")`, \"}\"].join(\"\\n\");\n\t\t}));\n\t\tconst content = [`// Generated by ${prismaGenerator.name}@${prismaGenerator.version}`, `// Manifest digest: ${ir.manifestDigest}`, \"generator client {\\n provider = \\\"prisma-client-js\\\"\\n}\", \"datasource db {\\n provider = \\\"postgresql\\\"\\n url = env(\\\"DATABASE_URL\\\")\\n}\", \"\", ...models, \"\"].join(\"\\n\\n\");\n\t\treturn [{ path: \"prisma/schema.prisma\", content }, { path: \"prisma/compatibility.json\", content: JSON.stringify({ manifestDigest: ir.manifestDigest, automaticMigration: false, reviewRequired: true }, null, 2) }];\n\t},\n};\n"],"mappings":";AAGA,IAAM,SAAS,CAAC,WAAuC;AACtD,QAAM,OAAO,MAAM,QAAQ,OAAO,IAAI,IAAI,OAAO,KAAK,KAAK,CAAC,SAAS,SAAS,MAAM,IAAI,OAAO;AAC/F,MAAI,SAAS,SAAU,QAAO;AAC9B,MAAI,SAAS,UAAW,QAAO;AAC/B,MAAI,SAAS,SAAU,QAAO;AAC9B,MAAI,SAAS,UAAW,QAAO;AAC/B,MAAI,SAAS,WAAW,SAAS,SAAU,QAAO;AAClD,SAAO;AACR;AACA,IAAM,SAAS,CAAC,UAA0B,MAAM,MAAM,QAAQ,EAAE,OAAO,OAAO,EAAE,IAAI,CAAC,SAAS,KAAK,CAAC,GAAG,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE;AAC7I,IAAM,aAAa,CAAC,UAA0B;AAC7C,QAAM,aAAa,MAAM,QAAQ,kBAAkB,GAAG;AACtD,SAAO,YAAY,KAAK,UAAU,IAAI,aAAa,SAAS,UAAU;AACvE;AAEO,IAAM,kBAAmC;AAAA,EAC/C,MAAM;AAAA,EAAyB,SAAS;AAAA,EACxC,SAAS,IAAI;AACZ,UAAM,SAAS,GAAG,QAAQ,QAAQ,CAAC,WAAW,OAAO,YAAY,IAAI,CAAC,eAAe;AACpF,YAAM,WAAW,IAAI,IAAI,WAAW,QAAQ,YAAY,CAAC,CAAC;AAC1D,YAAM,SAAS,OAAO,QAAQ,WAAW,QAAQ,cAAc,CAAC,CAAC,EAC/D,OAAO,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,MAAM,YAAY,SAAS,EAAE,SAAS,IAAI,CAAC,EAChE,IAAI,CAAC,CAAC,MAAM,MAAM,MAAM,KAAK,WAAW,IAAI,CAAC,IAAI,OAAO,MAAM,CAAC,GAAG,SAAS,IAAI,IAAI,IAAI,KAAK,GAAG,GAAG,WAAW,IAAI,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI,EAAE;AACzJ,YAAM,aAAa,WAAW,aAAa,CAAC,GAAG,IAAI,CAAC,aAAa,KAAK,SAAS,IAAI,aAAa,SAAS,gBAAgB,SAAS,OAAO,SAAS,WAAW,KAAK,GAAG,OAAO,SAAS,SAAS,OAAO,SAAS,MAAM,EAAE;AACtN,aAAO,CAAC,SAAS,OAAO,OAAO,SAAS,CAAC,GAAG,WAAW,IAAI,MAAM,mBAAmB,qBAAqB,oBAAoB,GAAG,QAAQ,GAAG,WAAW,IAAI,kCAAkC,YAAY,OAAO,SAAS,IAAI,WAAW,IAAI,MAAM,GAAG,EAAE,KAAK,IAAI;AAAA,IAChQ,CAAC,CAAC;AACF,UAAM,UAAU,CAAC,mBAAmB,gBAAgB,IAAI,IAAI,gBAAgB,OAAO,IAAI,uBAAuB,GAAG,cAAc,IAAI,0DAA4D,mFAAuF,IAAI,GAAG,QAAQ,EAAE,EAAE,KAAK,MAAM;AACpT,WAAO,CAAC,EAAE,MAAM,wBAAwB,QAAQ,GAAG,EAAE,MAAM,6BAA6B,SAAS,KAAK,UAAU,EAAE,gBAAgB,GAAG,gBAAgB,oBAAoB,OAAO,gBAAgB,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC;AAAA,EACnN;AACD;","names":[]}
1
+ {"version":3,"sources":["../index.ts"],"sourcesContent":["import type { GeneratorTarget } from \"@fabricorg/compiler\";\nimport type { PortableJsonSchema } from \"@fabricorg/platform\";\n\nconst scalar = (schema: PortableJsonSchema): string => {\n\tconst type = Array.isArray(schema.type) ? schema.type.find((item) => item !== \"null\") : schema.type;\n\tif (type === \"string\") return \"String\";\n\tif (type === \"integer\") return \"Int\";\n\tif (type === \"number\") return \"Float\";\n\tif (type === \"boolean\") return \"Boolean\";\n\tif (type === \"array\" || type === \"object\") return \"Json\";\n\treturn \"Json\";\n};\nconst pascal = (value: string): string => value.split(/[-._/]/).filter(Boolean).map((part) => part[0]?.toUpperCase() + part.slice(1)).join(\"\");\nconst identifier = (value: string): string => {\n\tconst normalized = value.replace(/[^a-zA-Z0-9_]/g, \"_\");\n\treturn /^[a-zA-Z]/.test(normalized) ? normalized : `field_${normalized}`;\n};\n\nexport const prismaGenerator: GeneratorTarget = {\n\tname: \"@fabricorg/gen-prisma\", version: \"1.0.0\",\n\tgenerate(ir) {\n\t\tconst modelNames = ir.modules.flatMap((module) => module.objectTypes.map((objectType) => `${pascal(module.namespace)}${objectType.type}`));\n\t\tif (new Set(modelNames).size !== modelNames.length) throw new Error(\"Manifest produces colliding Prisma model names across modules.\");\n\t\tconst models = ir.modules.flatMap((module) => module.objectTypes.map((objectType) => {\n\t\t\tconst required = new Set(objectType.schema?.required ?? []);\n\t\t\tconst properties = Object.entries(objectType.schema?.properties ?? {}).filter(([name]) => ![\"id\", \"tenantId\", \"spaceId\"].includes(name));\n\t\t\tconst identifiers = properties.map(([name]) => identifier(name));\n\t\t\tconst relationIdentifiers = (objectType.relations ?? []).map((relation) => `${relation.name}Ids`);\n\t\t\tif (new Set([...identifiers, ...relationIdentifiers]).size !== identifiers.length + relationIdentifiers.length) throw new Error(`Object \"${module.namespace}.${objectType.type}\" produces colliding Prisma field names.`);\n\t\t\tconst fields = properties.map(([name, schema]) => ` ${identifier(name)} ${scalar(schema)}${required.has(name) ? \"\" : \"?\"}${identifier(name) === name ? \"\" : ` @map(${JSON.stringify(name)})`}`);\n\t\t\tconst relations = (objectType.relations ?? []).map((relation) => ` ${relation.name}Ids String${relation.cardinality === \"many\" ? \"[]\" : relation.required ? \"\" : \"?\"} // ${relation.semantics} -> ${relation.target}`);\n\t\t\treturn [`model ${pascal(module.namespace)}${objectType.type} {`, \" id String @id\", \" tenantId String\", \" spaceId String\", ...fields, ...relations, \"\", \" @@index([tenantId, spaceId])\", ` @@map(\"${module.namespace}_${objectType.type}\")`, \"}\"].join(\"\\n\");\n\t\t}));\n\t\tconst content = [`// Generated by ${prismaGenerator.name}@${prismaGenerator.version}`, `// Manifest digest: ${ir.manifestDigest}`, \"generator client {\\n provider = \\\"prisma-client-js\\\"\\n}\", \"datasource db {\\n provider = \\\"postgresql\\\"\\n url = env(\\\"DATABASE_URL\\\")\\n}\", \"\", ...models, \"\"].join(\"\\n\\n\");\n\t\treturn [{ path: \"prisma/schema.prisma\", content }, { path: \"prisma/compatibility.json\", content: JSON.stringify({ manifestDigest: ir.manifestDigest, automaticMigration: false, reviewRequired: true }, null, 2) }];\n\t},\n};\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fabricorg/gen-prisma",
3
- "version": "0.2.0",
3
+ "version": "1.0.0",
4
4
  "description": "Reference Prisma schema generator for Fabric compiler IR.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -25,14 +25,17 @@
25
25
  "CHANGELOG.md"
26
26
  ],
27
27
  "dependencies": {
28
- "@fabricorg/compiler": "^0.2.0",
29
- "@fabricorg/platform": "^0.11.0"
28
+ "@fabricorg/compiler": "^1.0.0"
29
+ },
30
+ "peerDependencies": {
31
+ "@fabricorg/platform": "^0.12.0"
30
32
  },
31
33
  "devDependencies": {
32
34
  "@types/node": "^22.10.0",
33
35
  "tsup": "^8.5.0",
34
36
  "typescript": "^5.7.3",
35
- "vitest": "^4.1.5"
37
+ "vitest": "^4.1.5",
38
+ "@fabricorg/platform": "^0.12.0"
36
39
  },
37
40
  "engines": {
38
41
  "node": ">=20"