@polyprism/core 0.1.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/LICENSE +21 -0
- package/README.md +32 -0
- package/dist/annotations/enrich.d.ts +5 -0
- package/dist/annotations/enrich.js +40 -0
- package/dist/annotations/enrich.js.map +1 -0
- package/dist/annotations/index.d.ts +3 -0
- package/dist/annotations/index.js +3 -0
- package/dist/annotations/index.js.map +1 -0
- package/dist/annotations/parser.d.ts +9 -0
- package/dist/annotations/parser.js +207 -0
- package/dist/annotations/parser.js.map +1 -0
- package/dist/emitter/emit-enums.d.ts +9 -0
- package/dist/emitter/emit-enums.js +19 -0
- package/dist/emitter/emit-enums.js.map +1 -0
- package/dist/emitter/emit-json-types.d.ts +9 -0
- package/dist/emitter/emit-json-types.js +28 -0
- package/dist/emitter/emit-json-types.js.map +1 -0
- package/dist/emitter/file-writer.d.ts +12 -0
- package/dist/emitter/file-writer.js +25 -0
- package/dist/emitter/file-writer.js.map +1 -0
- package/dist/emitter/format-type.d.ts +3 -0
- package/dist/emitter/format-type.js +162 -0
- package/dist/emitter/format-type.js.map +1 -0
- package/dist/emitter/index.d.ts +10 -0
- package/dist/emitter/index.js +7 -0
- package/dist/emitter/index.js.map +1 -0
- package/dist/emitter/render-enum.d.ts +6 -0
- package/dist/emitter/render-enum.js +56 -0
- package/dist/emitter/render-enum.js.map +1 -0
- package/dist/emitter/render-json-type.d.ts +3 -0
- package/dist/emitter/render-json-type.js +10 -0
- package/dist/emitter/render-json-type.js.map +1 -0
- package/dist/generator/config.d.ts +10 -0
- package/dist/generator/config.js +45 -0
- package/dist/generator/config.js.map +1 -0
- package/dist/generator/context.d.ts +18 -0
- package/dist/generator/context.js +1 -0
- package/dist/generator/context.js.map +1 -0
- package/dist/generator/define.d.ts +24 -0
- package/dist/generator/define.js +23 -0
- package/dist/generator/define.js.map +1 -0
- package/dist/generator/index.d.ts +6 -0
- package/dist/generator/index.js +4 -0
- package/dist/generator/index.js.map +1 -0
- package/dist/generator/json-rpc.d.ts +7 -0
- package/dist/generator/json-rpc.js +59 -0
- package/dist/generator/json-rpc.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/ir/index.d.ts +1 -0
- package/dist/ir/index.js +2 -0
- package/dist/ir/index.js.map +1 -0
- package/dist/ir/types.d.ts +133 -0
- package/dist/ir/types.js +17 -0
- package/dist/ir/types.js.map +1 -0
- package/dist/naming/casing.d.ts +7 -0
- package/dist/naming/casing.js +34 -0
- package/dist/naming/casing.js.map +1 -0
- package/dist/naming/index.d.ts +3 -0
- package/dist/naming/index.js +4 -0
- package/dist/naming/index.js.map +1 -0
- package/dist/naming/resolver.d.ts +26 -0
- package/dist/naming/resolver.js +59 -0
- package/dist/naming/resolver.js.map +1 -0
- package/dist/naming/types.d.ts +11 -0
- package/dist/naming/types.js +9 -0
- package/dist/naming/types.js.map +1 -0
- package/dist/reader/dmmf-reader.d.ts +12 -0
- package/dist/reader/dmmf-reader.js +135 -0
- package/dist/reader/dmmf-reader.js.map +1 -0
- package/dist/reader/index.d.ts +3 -0
- package/dist/reader/index.js +2 -0
- package/dist/reader/index.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
type ScalarType = "String" | "Boolean" | "Int" | "BigInt" | "Float" | "Decimal" | "DateTime" | "Json" | "Bytes";
|
|
2
|
+
type ReferentialAction = "Cascade" | "Restrict" | "NoAction" | "SetNull" | "SetDefault";
|
|
3
|
+
interface NativeType {
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly args: readonly string[];
|
|
6
|
+
}
|
|
7
|
+
type FieldType = {
|
|
8
|
+
readonly kind: "scalar";
|
|
9
|
+
readonly scalar: ScalarType;
|
|
10
|
+
} | {
|
|
11
|
+
readonly kind: "enum";
|
|
12
|
+
readonly enumName: string;
|
|
13
|
+
} | {
|
|
14
|
+
readonly kind: "relation";
|
|
15
|
+
readonly modelName: string;
|
|
16
|
+
readonly relationName: string | null;
|
|
17
|
+
readonly relationFromFields: readonly string[];
|
|
18
|
+
readonly relationToFields: readonly string[];
|
|
19
|
+
readonly onDelete: ReferentialAction | null;
|
|
20
|
+
readonly onUpdate: ReferentialAction | null;
|
|
21
|
+
} | {
|
|
22
|
+
readonly kind: "unsupported";
|
|
23
|
+
readonly raw: string;
|
|
24
|
+
};
|
|
25
|
+
type DefaultValue = {
|
|
26
|
+
readonly kind: "literal";
|
|
27
|
+
readonly value: string | number | boolean | null;
|
|
28
|
+
} | {
|
|
29
|
+
readonly kind: "function";
|
|
30
|
+
readonly name: string;
|
|
31
|
+
readonly args: readonly unknown[];
|
|
32
|
+
} | {
|
|
33
|
+
readonly kind: "list";
|
|
34
|
+
readonly values: readonly unknown[];
|
|
35
|
+
};
|
|
36
|
+
type NormaliseOp = "trim" | "lowercase" | "uppercase" | "nullEmptyToNull";
|
|
37
|
+
type CoerceTo = "date" | "int" | "float" | "decimal" | "string";
|
|
38
|
+
type JsonAnnotation = {
|
|
39
|
+
readonly kind: "bare";
|
|
40
|
+
readonly typeName: string;
|
|
41
|
+
} | {
|
|
42
|
+
readonly kind: "with-path";
|
|
43
|
+
readonly typeName: string;
|
|
44
|
+
readonly importPath: string;
|
|
45
|
+
} | {
|
|
46
|
+
readonly kind: "inline-anonymous";
|
|
47
|
+
readonly typeExpression: string;
|
|
48
|
+
} | {
|
|
49
|
+
readonly kind: "inline-named";
|
|
50
|
+
readonly typeName: string;
|
|
51
|
+
readonly typeExpression: string;
|
|
52
|
+
};
|
|
53
|
+
interface TypeOverride {
|
|
54
|
+
readonly typeName: string;
|
|
55
|
+
readonly importPath: string | null;
|
|
56
|
+
}
|
|
57
|
+
interface DeprecatedInfo {
|
|
58
|
+
readonly reason: string | null;
|
|
59
|
+
}
|
|
60
|
+
interface AnnotationSet {
|
|
61
|
+
hide: boolean;
|
|
62
|
+
deprecated: DeprecatedInfo | null;
|
|
63
|
+
json: JsonAnnotation | null;
|
|
64
|
+
type: TypeOverride | null;
|
|
65
|
+
name: string | null;
|
|
66
|
+
normalise: readonly NormaliseOp[] | null;
|
|
67
|
+
coerce: CoerceTo | null;
|
|
68
|
+
/** Documentation text stripped of annotation lines; preserved for JSDoc emission. */
|
|
69
|
+
documentation: string | null;
|
|
70
|
+
/** Raw annotation source kept for debugging / unknown-annotation warnings. */
|
|
71
|
+
rawAnnotations: readonly string[];
|
|
72
|
+
}
|
|
73
|
+
interface FieldDef {
|
|
74
|
+
readonly name: string;
|
|
75
|
+
readonly dbName: string | null;
|
|
76
|
+
readonly type: FieldType;
|
|
77
|
+
readonly isList: boolean;
|
|
78
|
+
readonly isRequired: boolean;
|
|
79
|
+
readonly isUnique: boolean;
|
|
80
|
+
readonly isId: boolean;
|
|
81
|
+
readonly isUpdatedAt: boolean;
|
|
82
|
+
readonly hasDefaultValue: boolean;
|
|
83
|
+
readonly default: DefaultValue | null;
|
|
84
|
+
readonly documentation: string | null;
|
|
85
|
+
readonly annotations: AnnotationSet;
|
|
86
|
+
readonly nativeType: NativeType | null;
|
|
87
|
+
}
|
|
88
|
+
interface PrimaryKeyDef {
|
|
89
|
+
readonly name: string | null;
|
|
90
|
+
readonly fields: readonly string[];
|
|
91
|
+
}
|
|
92
|
+
interface UniqueIndexDef {
|
|
93
|
+
readonly name: string | null;
|
|
94
|
+
readonly fields: readonly string[];
|
|
95
|
+
}
|
|
96
|
+
interface IndexDef {
|
|
97
|
+
readonly name: string | null;
|
|
98
|
+
readonly fields: readonly string[];
|
|
99
|
+
}
|
|
100
|
+
interface ModelDef {
|
|
101
|
+
readonly name: string;
|
|
102
|
+
readonly dbName: string | null;
|
|
103
|
+
readonly documentation: string | null;
|
|
104
|
+
readonly fields: readonly FieldDef[];
|
|
105
|
+
readonly primaryKey: PrimaryKeyDef | null;
|
|
106
|
+
readonly uniqueIndexes: readonly UniqueIndexDef[];
|
|
107
|
+
readonly indexes: readonly IndexDef[];
|
|
108
|
+
readonly annotations: AnnotationSet;
|
|
109
|
+
}
|
|
110
|
+
interface EnumValueDef {
|
|
111
|
+
readonly name: string;
|
|
112
|
+
readonly dbName: string | null;
|
|
113
|
+
readonly documentation: string | null;
|
|
114
|
+
readonly annotations: AnnotationSet;
|
|
115
|
+
}
|
|
116
|
+
interface EnumDef {
|
|
117
|
+
readonly name: string;
|
|
118
|
+
readonly dbName: string | null;
|
|
119
|
+
readonly documentation: string | null;
|
|
120
|
+
readonly values: readonly EnumValueDef[];
|
|
121
|
+
readonly annotations: AnnotationSet;
|
|
122
|
+
}
|
|
123
|
+
interface PolyPrismIR {
|
|
124
|
+
readonly models: readonly ModelDef[];
|
|
125
|
+
readonly enums: readonly EnumDef[];
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Returns an AnnotationSet with no annotations parsed.
|
|
129
|
+
* Used as the baseline before the annotation parser (Task 3) runs.
|
|
130
|
+
*/
|
|
131
|
+
declare function emptyAnnotationSet(documentation: string | null): AnnotationSet;
|
|
132
|
+
|
|
133
|
+
export { type AnnotationSet, type CoerceTo, type DefaultValue, type DeprecatedInfo, type EnumDef, type EnumValueDef, type FieldDef, type FieldType, type IndexDef, type JsonAnnotation, type ModelDef, type NativeType, type NormaliseOp, type PolyPrismIR, type PrimaryKeyDef, type ReferentialAction, type ScalarType, type TypeOverride, type UniqueIndexDef, emptyAnnotationSet };
|
package/dist/ir/types.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
function emptyAnnotationSet(documentation) {
|
|
2
|
+
return {
|
|
3
|
+
hide: false,
|
|
4
|
+
deprecated: null,
|
|
5
|
+
json: null,
|
|
6
|
+
type: null,
|
|
7
|
+
name: null,
|
|
8
|
+
normalise: null,
|
|
9
|
+
coerce: null,
|
|
10
|
+
documentation,
|
|
11
|
+
rawAnnotations: []
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
emptyAnnotationSet
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/ir/types.ts"],"sourcesContent":["// Language-agnostic intermediate representation for PolyPrism.\n// Designed so a future PHP (or Go, Rust, ...) emitter can consume the same IR\n// without needing to understand DMMF.\n\nexport type ScalarType =\n | \"String\"\n | \"Boolean\"\n | \"Int\"\n | \"BigInt\"\n | \"Float\"\n | \"Decimal\"\n | \"DateTime\"\n | \"Json\"\n | \"Bytes\";\n\nexport type ReferentialAction = \"Cascade\" | \"Restrict\" | \"NoAction\" | \"SetNull\" | \"SetDefault\";\n\nexport interface NativeType {\n readonly name: string;\n readonly args: readonly string[];\n}\n\nexport type FieldType =\n | { readonly kind: \"scalar\"; readonly scalar: ScalarType }\n | { readonly kind: \"enum\"; readonly enumName: string }\n | {\n readonly kind: \"relation\";\n readonly modelName: string;\n readonly relationName: string | null;\n readonly relationFromFields: readonly string[];\n readonly relationToFields: readonly string[];\n readonly onDelete: ReferentialAction | null;\n readonly onUpdate: ReferentialAction | null;\n }\n | { readonly kind: \"unsupported\"; readonly raw: string };\n\nexport type DefaultValue =\n | { readonly kind: \"literal\"; readonly value: string | number | boolean | null }\n | { readonly kind: \"function\"; readonly name: string; readonly args: readonly unknown[] }\n | { readonly kind: \"list\"; readonly values: readonly unknown[] };\n\nexport type NormaliseOp = \"trim\" | \"lowercase\" | \"uppercase\" | \"nullEmptyToNull\";\n\nexport type CoerceTo = \"date\" | \"int\" | \"float\" | \"decimal\" | \"string\";\n\nexport type JsonAnnotation =\n | { readonly kind: \"bare\"; readonly typeName: string }\n | { readonly kind: \"with-path\"; readonly typeName: string; readonly importPath: string }\n | { readonly kind: \"inline-anonymous\"; readonly typeExpression: string }\n | {\n readonly kind: \"inline-named\";\n readonly typeName: string;\n readonly typeExpression: string;\n };\n\nexport interface TypeOverride {\n readonly typeName: string;\n readonly importPath: string | null;\n}\n\nexport interface DeprecatedInfo {\n readonly reason: string | null;\n}\n\nexport interface AnnotationSet {\n hide: boolean;\n deprecated: DeprecatedInfo | null;\n json: JsonAnnotation | null;\n type: TypeOverride | null;\n name: string | null;\n normalise: readonly NormaliseOp[] | null;\n coerce: CoerceTo | null;\n /** Documentation text stripped of annotation lines; preserved for JSDoc emission. */\n documentation: string | null;\n /** Raw annotation source kept for debugging / unknown-annotation warnings. */\n rawAnnotations: readonly string[];\n}\n\nexport interface FieldDef {\n readonly name: string;\n readonly dbName: string | null;\n readonly type: FieldType;\n readonly isList: boolean;\n readonly isRequired: boolean;\n readonly isUnique: boolean;\n readonly isId: boolean;\n readonly isUpdatedAt: boolean;\n readonly hasDefaultValue: boolean;\n readonly default: DefaultValue | null;\n readonly documentation: string | null;\n readonly annotations: AnnotationSet;\n readonly nativeType: NativeType | null;\n}\n\nexport interface PrimaryKeyDef {\n readonly name: string | null;\n readonly fields: readonly string[];\n}\n\nexport interface UniqueIndexDef {\n readonly name: string | null;\n readonly fields: readonly string[];\n}\n\nexport interface IndexDef {\n readonly name: string | null;\n readonly fields: readonly string[];\n}\n\nexport interface ModelDef {\n readonly name: string;\n readonly dbName: string | null;\n readonly documentation: string | null;\n readonly fields: readonly FieldDef[];\n readonly primaryKey: PrimaryKeyDef | null;\n readonly uniqueIndexes: readonly UniqueIndexDef[];\n readonly indexes: readonly IndexDef[];\n readonly annotations: AnnotationSet;\n}\n\nexport interface EnumValueDef {\n readonly name: string;\n readonly dbName: string | null;\n readonly documentation: string | null;\n readonly annotations: AnnotationSet;\n}\n\nexport interface EnumDef {\n readonly name: string;\n readonly dbName: string | null;\n readonly documentation: string | null;\n readonly values: readonly EnumValueDef[];\n readonly annotations: AnnotationSet;\n}\n\nexport interface PolyPrismIR {\n readonly models: readonly ModelDef[];\n readonly enums: readonly EnumDef[];\n}\n\n/**\n * Returns an AnnotationSet with no annotations parsed.\n * Used as the baseline before the annotation parser (Task 3) runs.\n */\nexport function emptyAnnotationSet(documentation: string | null): AnnotationSet {\n return {\n hide: false,\n deprecated: null,\n json: null,\n type: null,\n name: null,\n normalise: null,\n coerce: null,\n documentation,\n rawAnnotations: [],\n };\n}\n"],"mappings":"AAgJO,SAAS,mBAAmB,eAA6C;AAC9E,SAAO;AAAA,IACL,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,IACX,QAAQ;AAAA,IACR;AAAA,IACA,gBAAgB,CAAC;AAAA,EACnB;AACF;","names":[]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
declare function splitWords(input: string): readonly string[];
|
|
2
|
+
declare function toPascalCase(input: string): string;
|
|
3
|
+
declare function toCamelCase(input: string): string;
|
|
4
|
+
declare function toSnakeCase(input: string): string;
|
|
5
|
+
declare function toKebabCase(input: string): string;
|
|
6
|
+
|
|
7
|
+
export { splitWords, toCamelCase, toKebabCase, toPascalCase, toSnakeCase };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const ACRONYM_BOUNDARY = /([A-Z]+)([A-Z][a-z])/g;
|
|
2
|
+
const CAMEL_BOUNDARY = /([a-z0-9])([A-Z])/g;
|
|
3
|
+
const SEPARATOR = /[_\-\s]+/;
|
|
4
|
+
function splitWords(input) {
|
|
5
|
+
if (input.length === 0) return [];
|
|
6
|
+
return input.replace(ACRONYM_BOUNDARY, "$1 $2").replace(CAMEL_BOUNDARY, "$1 $2").split(SEPARATOR).filter((s) => s.length > 0);
|
|
7
|
+
}
|
|
8
|
+
function capitalize(word) {
|
|
9
|
+
if (word.length === 0) return word;
|
|
10
|
+
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
|
11
|
+
}
|
|
12
|
+
function toPascalCase(input) {
|
|
13
|
+
return splitWords(input).map(capitalize).join("");
|
|
14
|
+
}
|
|
15
|
+
function toCamelCase(input) {
|
|
16
|
+
const words = splitWords(input);
|
|
17
|
+
if (words.length === 0) return "";
|
|
18
|
+
const [first, ...rest] = words;
|
|
19
|
+
return first.toLowerCase() + rest.map(capitalize).join("");
|
|
20
|
+
}
|
|
21
|
+
function toSnakeCase(input) {
|
|
22
|
+
return splitWords(input).map((w) => w.toLowerCase()).join("_");
|
|
23
|
+
}
|
|
24
|
+
function toKebabCase(input) {
|
|
25
|
+
return splitWords(input).map((w) => w.toLowerCase()).join("-");
|
|
26
|
+
}
|
|
27
|
+
export {
|
|
28
|
+
splitWords,
|
|
29
|
+
toCamelCase,
|
|
30
|
+
toKebabCase,
|
|
31
|
+
toPascalCase,
|
|
32
|
+
toSnakeCase
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=casing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/naming/casing.ts"],"sourcesContent":["// Pure casing transformations. No external state, no IR awareness.\n//\n// Word boundary detection:\n// - camelCase: `createdAt` → [\"created\", \"At\"]\n// - PascalCase + acronym: `HTMLParser` → [\"HTML\", \"Parser\"]\n// - snake_case / kebab-case: `created_at`, `created-at` → [\"created\", \"at\"]\n// - SCREAMING_SNAKE: `LEGACY_VALUE` → [\"LEGACY\", \"VALUE\"]\n\nconst ACRONYM_BOUNDARY = /([A-Z]+)([A-Z][a-z])/g;\nconst CAMEL_BOUNDARY = /([a-z0-9])([A-Z])/g;\nconst SEPARATOR = /[_\\-\\s]+/;\n\nexport function splitWords(input: string): readonly string[] {\n if (input.length === 0) return [];\n return input\n .replace(ACRONYM_BOUNDARY, \"$1 $2\")\n .replace(CAMEL_BOUNDARY, \"$1 $2\")\n .split(SEPARATOR)\n .filter((s) => s.length > 0);\n}\n\nfunction capitalize(word: string): string {\n if (word.length === 0) return word;\n return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();\n}\n\nexport function toPascalCase(input: string): string {\n return splitWords(input).map(capitalize).join(\"\");\n}\n\nexport function toCamelCase(input: string): string {\n const words = splitWords(input);\n if (words.length === 0) return \"\";\n const [first, ...rest] = words;\n return first!.toLowerCase() + rest.map(capitalize).join(\"\");\n}\n\nexport function toSnakeCase(input: string): string {\n return splitWords(input)\n .map((w) => w.toLowerCase())\n .join(\"_\");\n}\n\nexport function toKebabCase(input: string): string {\n return splitWords(input)\n .map((w) => w.toLowerCase())\n .join(\"-\");\n}\n"],"mappings":"AAQA,MAAM,mBAAmB;AACzB,MAAM,iBAAiB;AACvB,MAAM,YAAY;AAEX,SAAS,WAAW,OAAkC;AAC3D,MAAI,MAAM,WAAW,EAAG,QAAO,CAAC;AAChC,SAAO,MACJ,QAAQ,kBAAkB,OAAO,EACjC,QAAQ,gBAAgB,OAAO,EAC/B,MAAM,SAAS,EACf,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AAC/B;AAEA,SAAS,WAAW,MAAsB;AACxC,MAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,SAAO,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,EAAE,YAAY;AAClE;AAEO,SAAS,aAAa,OAAuB;AAClD,SAAO,WAAW,KAAK,EAAE,IAAI,UAAU,EAAE,KAAK,EAAE;AAClD;AAEO,SAAS,YAAY,OAAuB;AACjD,QAAM,QAAQ,WAAW,KAAK;AAC9B,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,QAAM,CAAC,OAAO,GAAG,IAAI,IAAI;AACzB,SAAO,MAAO,YAAY,IAAI,KAAK,IAAI,UAAU,EAAE,KAAK,EAAE;AAC5D;AAEO,SAAS,YAAY,OAAuB;AACjD,SAAO,WAAW,KAAK,EACpB,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,EAC1B,KAAK,GAAG;AACb;AAEO,SAAS,YAAY,OAAuB;AACjD,SAAO,WAAW,KAAK,EACpB,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,EAC1B,KAAK,GAAG;AACb;","names":[]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { splitWords, toCamelCase, toKebabCase, toPascalCase, toSnakeCase } from './casing.js';
|
|
2
|
+
export { ResolveFieldIdent, ResolveTypeIdent, applyFieldConvention, applyFileConvention, applyTypeConvention, autoNameInlineJson, resolveFieldIdent, resolveTypeFilename, resolveTypeIdent } from './resolver.js';
|
|
3
|
+
export { DEFAULT_NAMING, FieldNamingConvention, FileNamingConvention, NamingConfig, TypeNamingConvention } from './types.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/naming/index.ts"],"sourcesContent":["export * from \"./casing.js\";\nexport * from \"./resolver.js\";\nexport * from \"./types.js\";\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { FieldNamingConvention, TypeNamingConvention, FileNamingConvention } from './types.js';
|
|
2
|
+
|
|
3
|
+
declare function applyTypeConvention(input: string, convention: TypeNamingConvention): string;
|
|
4
|
+
declare function applyFieldConvention(input: string, convention: FieldNamingConvention): string;
|
|
5
|
+
declare function applyFileConvention(input: string, convention: FileNamingConvention): string;
|
|
6
|
+
interface ResolveTypeIdent {
|
|
7
|
+
schemaName: string;
|
|
8
|
+
override: string | null;
|
|
9
|
+
convention: TypeNamingConvention;
|
|
10
|
+
}
|
|
11
|
+
declare function resolveTypeIdent(args: ResolveTypeIdent): string;
|
|
12
|
+
interface ResolveFieldIdent {
|
|
13
|
+
schemaName: string;
|
|
14
|
+
override: string | null;
|
|
15
|
+
convention: FieldNamingConvention;
|
|
16
|
+
}
|
|
17
|
+
declare function resolveFieldIdent(args: ResolveFieldIdent): string;
|
|
18
|
+
declare function resolveTypeFilename(typeIdent: string, convention: FileNamingConvention): string;
|
|
19
|
+
/**
|
|
20
|
+
* Auto-name an inline-anonymous JSON type. Always PascalCase derived from
|
|
21
|
+
* the model and field schema names — the project's typeNaming applies
|
|
22
|
+
* separately when the resulting name is referenced as a type identifier.
|
|
23
|
+
*/
|
|
24
|
+
declare function autoNameInlineJson(modelSchemaName: string, fieldSchemaName: string): string;
|
|
25
|
+
|
|
26
|
+
export { type ResolveFieldIdent, type ResolveTypeIdent, applyFieldConvention, applyFileConvention, applyTypeConvention, autoNameInlineJson, resolveFieldIdent, resolveTypeFilename, resolveTypeIdent };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { toCamelCase, toKebabCase, toPascalCase, toSnakeCase } from "./casing.js";
|
|
2
|
+
function applyTypeConvention(input, convention) {
|
|
3
|
+
switch (convention) {
|
|
4
|
+
case "PascalCase":
|
|
5
|
+
return toPascalCase(input);
|
|
6
|
+
case "camelCase":
|
|
7
|
+
return toCamelCase(input);
|
|
8
|
+
case "snake_case":
|
|
9
|
+
return toSnakeCase(input);
|
|
10
|
+
case "preserve":
|
|
11
|
+
return input;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function applyFieldConvention(input, convention) {
|
|
15
|
+
switch (convention) {
|
|
16
|
+
case "camelCase":
|
|
17
|
+
return toCamelCase(input);
|
|
18
|
+
case "snake_case":
|
|
19
|
+
return toSnakeCase(input);
|
|
20
|
+
case "preserve":
|
|
21
|
+
return input;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function applyFileConvention(input, convention) {
|
|
25
|
+
switch (convention) {
|
|
26
|
+
case "PascalCase":
|
|
27
|
+
return toPascalCase(input);
|
|
28
|
+
case "camelCase":
|
|
29
|
+
return toCamelCase(input);
|
|
30
|
+
case "kebab-case":
|
|
31
|
+
return toKebabCase(input);
|
|
32
|
+
case "snake_case":
|
|
33
|
+
return toSnakeCase(input);
|
|
34
|
+
case "preserve":
|
|
35
|
+
return input;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function resolveTypeIdent(args) {
|
|
39
|
+
return args.override ?? applyTypeConvention(args.schemaName, args.convention);
|
|
40
|
+
}
|
|
41
|
+
function resolveFieldIdent(args) {
|
|
42
|
+
return args.override ?? applyFieldConvention(args.schemaName, args.convention);
|
|
43
|
+
}
|
|
44
|
+
function resolveTypeFilename(typeIdent, convention) {
|
|
45
|
+
return applyFileConvention(typeIdent, convention);
|
|
46
|
+
}
|
|
47
|
+
function autoNameInlineJson(modelSchemaName, fieldSchemaName) {
|
|
48
|
+
return toPascalCase(modelSchemaName) + toPascalCase(fieldSchemaName);
|
|
49
|
+
}
|
|
50
|
+
export {
|
|
51
|
+
applyFieldConvention,
|
|
52
|
+
applyFileConvention,
|
|
53
|
+
applyTypeConvention,
|
|
54
|
+
autoNameInlineJson,
|
|
55
|
+
resolveFieldIdent,
|
|
56
|
+
resolveTypeFilename,
|
|
57
|
+
resolveTypeIdent
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/naming/resolver.ts"],"sourcesContent":["// Naming resolution: applies the project's naming config to schema identifiers,\n// honouring `@name(...)` per-identifier overrides.\n//\n// Rules:\n// - `@name(X)` overrides the identifier verbatim. The override is the\n// identifier; filenames are still derived from it via fileNaming.\n// - Without an override, the schema identifier is transformed via the\n// relevant axis (typeNaming for models/enums, fieldNaming for fields).\n// - Filenames are always derived from the *resolved* type identifier via\n// fileNaming, regardless of override source.\n\nimport { toCamelCase, toKebabCase, toPascalCase, toSnakeCase } from \"./casing.js\";\nimport type { FieldNamingConvention, FileNamingConvention, TypeNamingConvention } from \"./types.js\";\n\nexport function applyTypeConvention(input: string, convention: TypeNamingConvention): string {\n switch (convention) {\n case \"PascalCase\":\n return toPascalCase(input);\n case \"camelCase\":\n return toCamelCase(input);\n case \"snake_case\":\n return toSnakeCase(input);\n case \"preserve\":\n return input;\n }\n}\n\nexport function applyFieldConvention(input: string, convention: FieldNamingConvention): string {\n switch (convention) {\n case \"camelCase\":\n return toCamelCase(input);\n case \"snake_case\":\n return toSnakeCase(input);\n case \"preserve\":\n return input;\n }\n}\n\nexport function applyFileConvention(input: string, convention: FileNamingConvention): string {\n switch (convention) {\n case \"PascalCase\":\n return toPascalCase(input);\n case \"camelCase\":\n return toCamelCase(input);\n case \"kebab-case\":\n return toKebabCase(input);\n case \"snake_case\":\n return toSnakeCase(input);\n case \"preserve\":\n return input;\n }\n}\n\nexport interface ResolveTypeIdent {\n schemaName: string;\n override: string | null;\n convention: TypeNamingConvention;\n}\n\nexport function resolveTypeIdent(args: ResolveTypeIdent): string {\n return args.override ?? applyTypeConvention(args.schemaName, args.convention);\n}\n\nexport interface ResolveFieldIdent {\n schemaName: string;\n override: string | null;\n convention: FieldNamingConvention;\n}\n\nexport function resolveFieldIdent(args: ResolveFieldIdent): string {\n return args.override ?? applyFieldConvention(args.schemaName, args.convention);\n}\n\nexport function resolveTypeFilename(typeIdent: string, convention: FileNamingConvention): string {\n return applyFileConvention(typeIdent, convention);\n}\n\n/**\n * Auto-name an inline-anonymous JSON type. Always PascalCase derived from\n * the model and field schema names — the project's typeNaming applies\n * separately when the resulting name is referenced as a type identifier.\n */\nexport function autoNameInlineJson(modelSchemaName: string, fieldSchemaName: string): string {\n return toPascalCase(modelSchemaName) + toPascalCase(fieldSchemaName);\n}\n"],"mappings":"AAWA,SAAS,aAAa,aAAa,cAAc,mBAAmB;AAG7D,SAAS,oBAAoB,OAAe,YAA0C;AAC3F,UAAQ,YAAY;AAAA,IAClB,KAAK;AACH,aAAO,aAAa,KAAK;AAAA,IAC3B,KAAK;AACH,aAAO,YAAY,KAAK;AAAA,IAC1B,KAAK;AACH,aAAO,YAAY,KAAK;AAAA,IAC1B,KAAK;AACH,aAAO;AAAA,EACX;AACF;AAEO,SAAS,qBAAqB,OAAe,YAA2C;AAC7F,UAAQ,YAAY;AAAA,IAClB,KAAK;AACH,aAAO,YAAY,KAAK;AAAA,IAC1B,KAAK;AACH,aAAO,YAAY,KAAK;AAAA,IAC1B,KAAK;AACH,aAAO;AAAA,EACX;AACF;AAEO,SAAS,oBAAoB,OAAe,YAA0C;AAC3F,UAAQ,YAAY;AAAA,IAClB,KAAK;AACH,aAAO,aAAa,KAAK;AAAA,IAC3B,KAAK;AACH,aAAO,YAAY,KAAK;AAAA,IAC1B,KAAK;AACH,aAAO,YAAY,KAAK;AAAA,IAC1B,KAAK;AACH,aAAO,YAAY,KAAK;AAAA,IAC1B,KAAK;AACH,aAAO;AAAA,EACX;AACF;AAQO,SAAS,iBAAiB,MAAgC;AAC/D,SAAO,KAAK,YAAY,oBAAoB,KAAK,YAAY,KAAK,UAAU;AAC9E;AAQO,SAAS,kBAAkB,MAAiC;AACjE,SAAO,KAAK,YAAY,qBAAqB,KAAK,YAAY,KAAK,UAAU;AAC/E;AAEO,SAAS,oBAAoB,WAAmB,YAA0C;AAC/F,SAAO,oBAAoB,WAAW,UAAU;AAClD;AAOO,SAAS,mBAAmB,iBAAyB,iBAAiC;AAC3F,SAAO,aAAa,eAAe,IAAI,aAAa,eAAe;AACrE;","names":[]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type FileNamingConvention = "PascalCase" | "camelCase" | "kebab-case" | "snake_case" | "preserve";
|
|
2
|
+
type TypeNamingConvention = "PascalCase" | "camelCase" | "snake_case" | "preserve";
|
|
3
|
+
type FieldNamingConvention = "camelCase" | "snake_case" | "preserve";
|
|
4
|
+
interface NamingConfig {
|
|
5
|
+
readonly fileNaming: FileNamingConvention;
|
|
6
|
+
readonly typeNaming: TypeNamingConvention;
|
|
7
|
+
readonly fieldNaming: FieldNamingConvention;
|
|
8
|
+
}
|
|
9
|
+
declare const DEFAULT_NAMING: NamingConfig;
|
|
10
|
+
|
|
11
|
+
export { DEFAULT_NAMING, type FieldNamingConvention, type FileNamingConvention, type NamingConfig, type TypeNamingConvention };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/naming/types.ts"],"sourcesContent":["export type FileNamingConvention =\n | \"PascalCase\"\n | \"camelCase\"\n | \"kebab-case\"\n | \"snake_case\"\n | \"preserve\";\n\nexport type TypeNamingConvention = \"PascalCase\" | \"camelCase\" | \"snake_case\" | \"preserve\";\n\nexport type FieldNamingConvention = \"camelCase\" | \"snake_case\" | \"preserve\";\n\nexport interface NamingConfig {\n readonly fileNaming: FileNamingConvention;\n readonly typeNaming: TypeNamingConvention;\n readonly fieldNaming: FieldNamingConvention;\n}\n\nexport const DEFAULT_NAMING: NamingConfig = {\n fileNaming: \"PascalCase\",\n typeNaming: \"PascalCase\",\n fieldNaming: \"preserve\",\n};\n"],"mappings":"AAiBO,MAAM,iBAA+B;AAAA,EAC1C,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,aAAa;AACf;","names":[]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { DMMF } from '@prisma/generator-helper';
|
|
2
|
+
import { PolyPrismIR } from '../ir/types.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Read a Prisma DMMF Document into PolyPrism's intermediate representation.
|
|
6
|
+
*
|
|
7
|
+
* The returned IR has unparsed annotations (all empty) — run the annotation
|
|
8
|
+
* parser (Task 3) over the IR to populate `annotations` from `documentation`.
|
|
9
|
+
*/
|
|
10
|
+
declare function readDmmf(document: DMMF.Document): PolyPrismIR;
|
|
11
|
+
|
|
12
|
+
export { readDmmf };
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { emptyAnnotationSet } from "../ir/types.js";
|
|
2
|
+
const SCALAR_TYPES = /* @__PURE__ */ new Set([
|
|
3
|
+
"String",
|
|
4
|
+
"Boolean",
|
|
5
|
+
"Int",
|
|
6
|
+
"BigInt",
|
|
7
|
+
"Float",
|
|
8
|
+
"Decimal",
|
|
9
|
+
"DateTime",
|
|
10
|
+
"Json",
|
|
11
|
+
"Bytes"
|
|
12
|
+
]);
|
|
13
|
+
function isScalarType(s) {
|
|
14
|
+
return SCALAR_TYPES.has(s);
|
|
15
|
+
}
|
|
16
|
+
const REFERENTIAL_ACTIONS = /* @__PURE__ */ new Set([
|
|
17
|
+
"Cascade",
|
|
18
|
+
"Restrict",
|
|
19
|
+
"NoAction",
|
|
20
|
+
"SetNull",
|
|
21
|
+
"SetDefault"
|
|
22
|
+
]);
|
|
23
|
+
function asReferentialAction(s) {
|
|
24
|
+
if (s == null) return null;
|
|
25
|
+
return REFERENTIAL_ACTIONS.has(s) ? s : null;
|
|
26
|
+
}
|
|
27
|
+
function mapFieldType(field) {
|
|
28
|
+
switch (field.kind) {
|
|
29
|
+
case "scalar":
|
|
30
|
+
if (isScalarType(field.type)) {
|
|
31
|
+
return { kind: "scalar", scalar: field.type };
|
|
32
|
+
}
|
|
33
|
+
return { kind: "unsupported", raw: field.type };
|
|
34
|
+
case "enum":
|
|
35
|
+
return { kind: "enum", enumName: field.type };
|
|
36
|
+
case "object":
|
|
37
|
+
return {
|
|
38
|
+
kind: "relation",
|
|
39
|
+
modelName: field.type,
|
|
40
|
+
relationName: field.relationName ?? null,
|
|
41
|
+
relationFromFields: field.relationFromFields ?? [],
|
|
42
|
+
relationToFields: field.relationToFields ?? [],
|
|
43
|
+
onDelete: asReferentialAction(field.relationOnDelete),
|
|
44
|
+
onUpdate: asReferentialAction(field.relationOnUpdate)
|
|
45
|
+
};
|
|
46
|
+
case "unsupported":
|
|
47
|
+
return { kind: "unsupported", raw: field.type };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function mapDefault(field) {
|
|
51
|
+
if (!field.hasDefaultValue || field.default === void 0) return null;
|
|
52
|
+
const def = field.default;
|
|
53
|
+
if (def === null || typeof def === "string" || typeof def === "number" || typeof def === "boolean") {
|
|
54
|
+
return { kind: "literal", value: def };
|
|
55
|
+
}
|
|
56
|
+
if (Array.isArray(def)) {
|
|
57
|
+
return { kind: "list", values: def };
|
|
58
|
+
}
|
|
59
|
+
if (typeof def === "object" && "name" in def && "args" in def) {
|
|
60
|
+
const fnDef = def;
|
|
61
|
+
return { kind: "function", name: fnDef.name, args: fnDef.args };
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
function mapNativeType(nt) {
|
|
66
|
+
if (!nt) return null;
|
|
67
|
+
return { name: nt[0], args: nt[1] };
|
|
68
|
+
}
|
|
69
|
+
function readField(dmmfField) {
|
|
70
|
+
return {
|
|
71
|
+
name: dmmfField.name,
|
|
72
|
+
dbName: dmmfField.dbName ?? null,
|
|
73
|
+
type: mapFieldType(dmmfField),
|
|
74
|
+
isList: dmmfField.isList,
|
|
75
|
+
isRequired: dmmfField.isRequired,
|
|
76
|
+
isUnique: dmmfField.isUnique,
|
|
77
|
+
isId: dmmfField.isId,
|
|
78
|
+
isUpdatedAt: dmmfField.isUpdatedAt ?? false,
|
|
79
|
+
hasDefaultValue: dmmfField.hasDefaultValue,
|
|
80
|
+
default: mapDefault(dmmfField),
|
|
81
|
+
documentation: dmmfField.documentation ?? null,
|
|
82
|
+
annotations: emptyAnnotationSet(dmmfField.documentation ?? null),
|
|
83
|
+
nativeType: mapNativeType(dmmfField.nativeType)
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function readModel(dmmfModel) {
|
|
87
|
+
const fields = dmmfModel.fields.map(readField);
|
|
88
|
+
const primaryKey = dmmfModel.primaryKey ? {
|
|
89
|
+
name: dmmfModel.primaryKey.name ?? null,
|
|
90
|
+
fields: dmmfModel.primaryKey.fields
|
|
91
|
+
} : null;
|
|
92
|
+
const uniqueIndexes = dmmfModel.uniqueIndexes.map((u) => ({
|
|
93
|
+
name: u.name ?? null,
|
|
94
|
+
fields: u.fields
|
|
95
|
+
}));
|
|
96
|
+
const indexes = [];
|
|
97
|
+
return {
|
|
98
|
+
name: dmmfModel.name,
|
|
99
|
+
dbName: dmmfModel.dbName ?? null,
|
|
100
|
+
documentation: dmmfModel.documentation ?? null,
|
|
101
|
+
fields,
|
|
102
|
+
primaryKey,
|
|
103
|
+
uniqueIndexes,
|
|
104
|
+
indexes,
|
|
105
|
+
annotations: emptyAnnotationSet(dmmfModel.documentation ?? null)
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function readEnumValue(v) {
|
|
109
|
+
const documentation = v.documentation ?? null;
|
|
110
|
+
return {
|
|
111
|
+
name: v.name,
|
|
112
|
+
dbName: v.dbName ?? null,
|
|
113
|
+
documentation,
|
|
114
|
+
annotations: emptyAnnotationSet(documentation)
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function readEnum(dmmfEnum) {
|
|
118
|
+
return {
|
|
119
|
+
name: dmmfEnum.name,
|
|
120
|
+
dbName: dmmfEnum.dbName ?? null,
|
|
121
|
+
documentation: dmmfEnum.documentation ?? null,
|
|
122
|
+
values: dmmfEnum.values.map(readEnumValue),
|
|
123
|
+
annotations: emptyAnnotationSet(dmmfEnum.documentation ?? null)
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function readDmmf(document) {
|
|
127
|
+
return {
|
|
128
|
+
models: document.datamodel.models.map(readModel),
|
|
129
|
+
enums: document.datamodel.enums.map(readEnum)
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
export {
|
|
133
|
+
readDmmf
|
|
134
|
+
};
|
|
135
|
+
//# sourceMappingURL=dmmf-reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/reader/dmmf-reader.ts"],"sourcesContent":["// DMMF → PolyPrism IR.\n//\n// ⚠️ This is the single isolation point for Prisma's `@prisma/generator-helper`.\n// DMMF is officially unstable; when Prisma ships its stable generator API\n// (announced for a future release), THIS file is the only one that should change.\n// The IR consumed by emitters stays the same.\n\nimport type { DMMF } from \"@prisma/generator-helper\";\n\nimport type {\n DefaultValue,\n EnumDef,\n EnumValueDef,\n FieldDef,\n FieldType,\n IndexDef,\n ModelDef,\n NativeType,\n PolyPrismIR,\n PrimaryKeyDef,\n ReferentialAction,\n ScalarType,\n UniqueIndexDef,\n} from \"../ir/types.js\";\nimport { emptyAnnotationSet } from \"../ir/types.js\";\n\nconst SCALAR_TYPES: ReadonlySet<ScalarType> = new Set([\n \"String\",\n \"Boolean\",\n \"Int\",\n \"BigInt\",\n \"Float\",\n \"Decimal\",\n \"DateTime\",\n \"Json\",\n \"Bytes\",\n]);\n\nfunction isScalarType(s: string): s is ScalarType {\n return SCALAR_TYPES.has(s as ScalarType);\n}\n\nconst REFERENTIAL_ACTIONS: ReadonlySet<ReferentialAction> = new Set([\n \"Cascade\",\n \"Restrict\",\n \"NoAction\",\n \"SetNull\",\n \"SetDefault\",\n]);\n\nfunction asReferentialAction(s: string | undefined | null): ReferentialAction | null {\n if (s == null) return null;\n return REFERENTIAL_ACTIONS.has(s as ReferentialAction) ? (s as ReferentialAction) : null;\n}\n\nfunction mapFieldType(field: DMMF.Field): FieldType {\n switch (field.kind) {\n case \"scalar\":\n if (isScalarType(field.type)) {\n return { kind: \"scalar\", scalar: field.type };\n }\n return { kind: \"unsupported\", raw: field.type };\n case \"enum\":\n return { kind: \"enum\", enumName: field.type };\n case \"object\":\n return {\n kind: \"relation\",\n modelName: field.type,\n relationName: field.relationName ?? null,\n relationFromFields: field.relationFromFields ?? [],\n relationToFields: field.relationToFields ?? [],\n onDelete: asReferentialAction(field.relationOnDelete),\n onUpdate: asReferentialAction(field.relationOnUpdate),\n };\n case \"unsupported\":\n return { kind: \"unsupported\", raw: field.type };\n }\n}\n\nfunction mapDefault(field: DMMF.Field): DefaultValue | null {\n if (!field.hasDefaultValue || field.default === undefined) return null;\n const def = field.default;\n if (\n def === null ||\n typeof def === \"string\" ||\n typeof def === \"number\" ||\n typeof def === \"boolean\"\n ) {\n return { kind: \"literal\", value: def };\n }\n if (Array.isArray(def)) {\n return { kind: \"list\", values: def };\n }\n if (typeof def === \"object\" && \"name\" in def && \"args\" in def) {\n const fnDef = def as { name: string; args: readonly unknown[] };\n return { kind: \"function\", name: fnDef.name, args: fnDef.args };\n }\n return null;\n}\n\nfunction mapNativeType(\n nt: readonly [string, readonly string[]] | null | undefined,\n): NativeType | null {\n if (!nt) return null;\n return { name: nt[0], args: nt[1] };\n}\n\nfunction readField(dmmfField: DMMF.Field): FieldDef {\n return {\n name: dmmfField.name,\n dbName: dmmfField.dbName ?? null,\n type: mapFieldType(dmmfField),\n isList: dmmfField.isList,\n isRequired: dmmfField.isRequired,\n isUnique: dmmfField.isUnique,\n isId: dmmfField.isId,\n isUpdatedAt: dmmfField.isUpdatedAt ?? false,\n hasDefaultValue: dmmfField.hasDefaultValue,\n default: mapDefault(dmmfField),\n documentation: dmmfField.documentation ?? null,\n annotations: emptyAnnotationSet(dmmfField.documentation ?? null),\n nativeType: mapNativeType(dmmfField.nativeType),\n };\n}\n\nfunction readModel(dmmfModel: DMMF.Model): ModelDef {\n const fields = dmmfModel.fields.map(readField);\n\n const primaryKey: PrimaryKeyDef | null = dmmfModel.primaryKey\n ? {\n name: dmmfModel.primaryKey.name ?? null,\n fields: dmmfModel.primaryKey.fields,\n }\n : null;\n\n const uniqueIndexes: UniqueIndexDef[] = dmmfModel.uniqueIndexes.map((u) => ({\n name: u.name ?? null,\n fields: u.fields,\n }));\n\n // DMMF's `@@index` reflection has historically been spotty across Prisma versions.\n // Left empty for v0.1; revisit when we need to surface index metadata.\n const indexes: IndexDef[] = [];\n\n return {\n name: dmmfModel.name,\n dbName: dmmfModel.dbName ?? null,\n documentation: dmmfModel.documentation ?? null,\n fields,\n primaryKey,\n uniqueIndexes,\n indexes,\n annotations: emptyAnnotationSet(dmmfModel.documentation ?? null),\n };\n}\n\nfunction readEnumValue(v: DMMF.EnumValue): EnumValueDef {\n // EnumValue.documentation isn't on every DMMF version; pluck defensively\n // so `@deprecated` on enum values works wherever Prisma surfaces it.\n const documentation = (v as { documentation?: string | null }).documentation ?? null;\n return {\n name: v.name,\n dbName: v.dbName ?? null,\n documentation,\n annotations: emptyAnnotationSet(documentation),\n };\n}\n\nfunction readEnum(dmmfEnum: DMMF.DatamodelEnum): EnumDef {\n return {\n name: dmmfEnum.name,\n dbName: dmmfEnum.dbName ?? null,\n documentation: dmmfEnum.documentation ?? null,\n values: dmmfEnum.values.map(readEnumValue),\n annotations: emptyAnnotationSet(dmmfEnum.documentation ?? null),\n };\n}\n\n/**\n * Read a Prisma DMMF Document into PolyPrism's intermediate representation.\n *\n * The returned IR has unparsed annotations (all empty) — run the annotation\n * parser (Task 3) over the IR to populate `annotations` from `documentation`.\n */\nexport function readDmmf(document: DMMF.Document): PolyPrismIR {\n return {\n models: document.datamodel.models.map(readModel),\n enums: document.datamodel.enums.map(readEnum),\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/reader/index.ts"],"sourcesContent":["export * from \"./dmmf-reader.js\";\n"],"mappings":"AAAA,cAAc;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@polyprism/core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Core IR, DMMF reader, annotation parser, and naming layer for PolyPrism Prisma generators.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Travis Fitzgerald",
|
|
8
|
+
"homepage": "https://github.com/TravFitz/polyprism/tree/main/packages/core",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/TravFitz/polyprism.git",
|
|
12
|
+
"directory": "packages/core"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/TravFitz/polyprism/issues"
|
|
16
|
+
},
|
|
17
|
+
"main": "./dist/index.js",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"polyprism-source": {
|
|
22
|
+
"types": "./src/index.ts",
|
|
23
|
+
"import": "./src/index.ts"
|
|
24
|
+
},
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"import": "./dist/index.js"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist",
|
|
31
|
+
"README.md"
|
|
32
|
+
],
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
},
|
|
36
|
+
"keywords": [
|
|
37
|
+
"prisma",
|
|
38
|
+
"prisma-generator",
|
|
39
|
+
"codegen",
|
|
40
|
+
"polyprism"
|
|
41
|
+
],
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@prisma/generator-helper": "^7.0.0"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsup",
|
|
47
|
+
"dev": "tsup --watch",
|
|
48
|
+
"typecheck": "tsc --noEmit",
|
|
49
|
+
"test": "vitest run",
|
|
50
|
+
"test:watch": "vitest"
|
|
51
|
+
}
|
|
52
|
+
}
|