@prisma-next/sql-contract-psl 0.5.0-dev.52 → 0.5.0-dev.54

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/psl-column-resolution.ts","../src/interpreter.ts"],"sourcesContent":[],"mappings":";;;;;;;;;KAuCY,gBAAA;;;;EAAA,SAAA,UAAgB,CAAA,EAIJ,MAJI,CAAA,MAIJ,EAAM,OAAA,CAAA;;;;UCkCb,sCAAA;EDtCL,SAAA,QAAA,ECuCS,sBDnCS;mBCoCX;kCACe,oBAAoB;;EAHrC,SAAA,yBAAA,CAAA,EAAA,SAK+B,gBALO,CAAA,KAAA,EAAA,MAAA,CAAA,EAAA;EAClC,SAAA,uBAAA,CAAA,EAKgB,yBALhB;EACF,SAAA,sBAAA,CAAA,EAKiB,sBALjB;;AACe,iBAggClB,iCAAA,CAhgCkB,KAAA,EAigCzB,sCAjgCyB,CAAA,EAkgC/B,MAlgC+B,CAkgCxB,QAlgCwB,EAkgCd,yBAlgCc,CAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/psl-column-resolution.ts","../src/interpreter.ts"],"sourcesContent":[],"mappings":";;;;;;;;;KAuCY,gBAAA;;;;EAAA,SAAA,UAAgB,CAAA,EAIJ,MAJI,CAAA,MAIJ,EAAM,OAAA,CAAA;;;;UCoCb,sCAAA;EDxCL,SAAA,QAAA,ECyCS,sBDrCS;mBCsCX;kCACe,oBAAoB;;EAHrC,SAAA,yBAAA,CAAA,EAAA,SAK+B,gBALO,CAAA,KAAA,EAAA,MAAA,CAAA,EAAA;EAClC,SAAA,uBAAA,CAAA,EAKgB,yBALhB;EACF,SAAA,sBAAA,CAAA,EAKiB,sBALjB;;AACe,iBAylClB,iCAAA,CAzlCkB,KAAA,EA0lCzB,sCA1lCyB,CAAA,EA2lC/B,MA3lC+B,CA2lCxB,QA3lCwB,EA2lCd,yBA3lCc,CAAA"}
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { t as interpretPslDocumentToSqlContract } from "./interpreter-DJrrH8Ee.mjs";
1
+ import { t as interpretPslDocumentToSqlContract } from "./interpreter-BChe-9vN.mjs";
2
2
 
3
3
  export { interpretPslDocumentToSqlContract };
@@ -149,7 +149,7 @@ function parseAttributeFieldList(input) {
149
149
  if (!raw) {
150
150
  input.diagnostics.push({
151
151
  code: input.code,
152
- message: `${input.messagePrefix} requires fields list argument`,
152
+ message: `${input.entityLabel} requires fields list argument`,
153
153
  sourceId: input.sourceId,
154
154
  span: input.attribute.span
155
155
  });
@@ -159,7 +159,7 @@ function parseAttributeFieldList(input) {
159
159
  if (!fields || fields.length === 0) {
160
160
  input.diagnostics.push({
161
161
  code: input.code,
162
- message: `${input.messagePrefix} requires bracketed field list argument`,
162
+ message: `${input.entityLabel} requires bracketed field list argument`,
163
163
  sourceId: input.sourceId,
164
164
  span: input.attribute.span
165
165
  });
@@ -167,6 +167,13 @@ function parseAttributeFieldList(input) {
167
167
  }
168
168
  return fields;
169
169
  }
170
+ function findDuplicateFieldName(fieldNames) {
171
+ const seen = /* @__PURE__ */ new Set();
172
+ for (const name of fieldNames) {
173
+ if (seen.has(name)) return name;
174
+ seen.add(name);
175
+ }
176
+ }
170
177
  function mapFieldNamesToColumns(input) {
171
178
  const columns = [];
172
179
  for (const fieldName of input.fieldNames) {
@@ -174,7 +181,7 @@ function mapFieldNamesToColumns(input) {
174
181
  if (!columnName) {
175
182
  input.diagnostics.push({
176
183
  code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
177
- message: `${input.contextLabel} references unknown field "${input.modelName}.${fieldName}"`,
184
+ message: `${input.entityLabel} references unknown field "${input.modelName}.${fieldName}"`,
178
185
  sourceId: input.sourceId,
179
186
  span: input.span
180
187
  });
@@ -1343,6 +1350,16 @@ function collectResolvedFields(input) {
1343
1350
  sourceId,
1344
1351
  diagnostics
1345
1352
  });
1353
+ let isIdField = Boolean(idAttribute);
1354
+ if (idAttribute && field.optional) {
1355
+ diagnostics.push({
1356
+ code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
1357
+ message: `Field "${model.name}.${field.name}" @id cannot be optional; primary key columns must be NOT NULL`,
1358
+ sourceId,
1359
+ span: idAttribute.span
1360
+ });
1361
+ isIdField = false;
1362
+ }
1346
1363
  if (presetContributions && idAttribute && !presetContributions.id) {
1347
1364
  diagnostics.push({
1348
1365
  code: "PSL_PRESET_AND_ID_CONFLICT",
@@ -1360,7 +1377,7 @@ function collectResolvedFields(input) {
1360
1377
  descriptor,
1361
1378
  ...ifDefined("defaultValue", fieldDefaultValue),
1362
1379
  ...ifDefined("executionDefaults", fieldExecutionDefaults),
1363
- isId: Boolean(idAttribute) || Boolean(presetContributions?.id),
1380
+ isId: isIdField || Boolean(presetContributions?.id),
1364
1381
  isUnique: Boolean(uniqueAttribute) || Boolean(presetContributions?.unique),
1365
1382
  ...ifDefined("idName", idName),
1366
1383
  ...ifDefined("uniqueName", uniqueName),
@@ -1887,16 +1904,20 @@ function buildModelNodeFromPsl(input) {
1887
1904
  sourceId,
1888
1905
  scalarTypeDescriptors: input.scalarTypeDescriptors
1889
1906
  });
1890
- const primaryKeyFields = resolvedFields.filter((field) => field.isId);
1891
- const primaryKeyColumns = primaryKeyFields.map((field) => field.columnName);
1892
- const primaryKeyName = primaryKeyFields.length === 1 ? primaryKeyFields[0]?.idName : void 0;
1893
- const isVariantModel = model.attributes.some((attr) => attr.name === "base");
1894
- if (primaryKeyColumns.length === 0 && !isVariantModel) diagnostics.push({
1895
- code: "PSL_MISSING_PRIMARY_KEY",
1896
- message: `Model "${model.name}" must declare at least one @id field for SQL provider`,
1907
+ const inlineIdFields = resolvedFields.filter((field) => field.isId);
1908
+ if (inlineIdFields.length > 1) diagnostics.push({
1909
+ code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
1910
+ message: `Model "${model.name}" cannot declare inline @id on multiple fields; use model-level @@id([...]) for composite identity`,
1897
1911
  sourceId,
1898
1912
  span: model.span
1899
1913
  });
1914
+ const singleInlineIdField = inlineIdFields.length === 1 ? inlineIdFields[0] : void 0;
1915
+ let primaryKey = singleInlineIdField ? {
1916
+ columns: [singleInlineIdField.columnName],
1917
+ ...ifDefined("name", singleInlineIdField.idName)
1918
+ } : void 0;
1919
+ const hasInlinePrimaryKey = primaryKey !== void 0;
1920
+ let blockPrimaryKeyDeclared = false;
1900
1921
  const resultBackrelationCandidates = [];
1901
1922
  for (const field of model.fields) {
1902
1923
  if (!field.list || !input.modelNames.has(field.typeName)) continue;
@@ -1963,15 +1984,98 @@ function buildModelNodeFromPsl(input) {
1963
1984
  for (const modelAttribute of model.attributes) {
1964
1985
  if (modelAttribute.name === "map") continue;
1965
1986
  if (modelAttribute.name === "discriminator" || modelAttribute.name === "base") continue;
1987
+ const attributeLabel = `Model "${model.name}" @@${modelAttribute.name}`;
1988
+ if (modelAttribute.name === "id") {
1989
+ if (blockPrimaryKeyDeclared) {
1990
+ diagnostics.push({
1991
+ code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
1992
+ message: `Model "${model.name}" declares @@id more than once`,
1993
+ sourceId,
1994
+ span: modelAttribute.span
1995
+ });
1996
+ continue;
1997
+ }
1998
+ if (hasInlinePrimaryKey) {
1999
+ diagnostics.push({
2000
+ code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
2001
+ message: `Model "${model.name}" cannot declare both field-level @id and model-level @@id`,
2002
+ sourceId,
2003
+ span: modelAttribute.span
2004
+ });
2005
+ blockPrimaryKeyDeclared = true;
2006
+ continue;
2007
+ }
2008
+ const fieldNames = parseAttributeFieldList({
2009
+ attribute: modelAttribute,
2010
+ sourceId,
2011
+ diagnostics,
2012
+ code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
2013
+ entityLabel: attributeLabel
2014
+ });
2015
+ if (!fieldNames) continue;
2016
+ const duplicateFieldName = findDuplicateFieldName(fieldNames);
2017
+ if (duplicateFieldName !== void 0) {
2018
+ diagnostics.push({
2019
+ code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
2020
+ message: `${attributeLabel} list contains duplicate field "${duplicateFieldName}"`,
2021
+ sourceId,
2022
+ span: modelAttribute.span
2023
+ });
2024
+ continue;
2025
+ }
2026
+ const nullableFieldName = fieldNames.find((name) => model.fields.find((f) => f.name === name)?.optional === true);
2027
+ if (nullableFieldName !== void 0) {
2028
+ diagnostics.push({
2029
+ code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
2030
+ message: `${attributeLabel} cannot include optional field "${nullableFieldName}"; primary key columns must be NOT NULL`,
2031
+ sourceId,
2032
+ span: modelAttribute.span
2033
+ });
2034
+ continue;
2035
+ }
2036
+ const columnNames = mapFieldNamesToColumns({
2037
+ modelName: model.name,
2038
+ fieldNames,
2039
+ mapping,
2040
+ sourceId,
2041
+ diagnostics,
2042
+ span: modelAttribute.span,
2043
+ entityLabel: attributeLabel
2044
+ });
2045
+ if (!columnNames) continue;
2046
+ primaryKey = {
2047
+ columns: columnNames,
2048
+ ...ifDefined("name", parseConstraintMapArgument({
2049
+ attribute: modelAttribute,
2050
+ sourceId,
2051
+ diagnostics,
2052
+ entityLabel: attributeLabel,
2053
+ span: modelAttribute.span,
2054
+ code: "PSL_INVALID_ATTRIBUTE_ARGUMENT"
2055
+ }))
2056
+ };
2057
+ blockPrimaryKeyDeclared = true;
2058
+ continue;
2059
+ }
1966
2060
  if (modelAttribute.name === "unique" || modelAttribute.name === "index") {
1967
2061
  const fieldNames = parseAttributeFieldList({
1968
2062
  attribute: modelAttribute,
1969
2063
  sourceId,
1970
2064
  diagnostics,
1971
2065
  code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
1972
- messagePrefix: `Model "${model.name}" @@${modelAttribute.name}`
2066
+ entityLabel: attributeLabel
1973
2067
  });
1974
2068
  if (!fieldNames) continue;
2069
+ const duplicateFieldName = findDuplicateFieldName(fieldNames);
2070
+ if (duplicateFieldName !== void 0) {
2071
+ diagnostics.push({
2072
+ code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
2073
+ message: `${attributeLabel} list contains duplicate field "${duplicateFieldName}"`,
2074
+ sourceId,
2075
+ span: modelAttribute.span
2076
+ });
2077
+ continue;
2078
+ }
1975
2079
  const columnNames = mapFieldNamesToColumns({
1976
2080
  modelName: model.name,
1977
2081
  fieldNames,
@@ -1979,14 +2083,14 @@ function buildModelNodeFromPsl(input) {
1979
2083
  sourceId,
1980
2084
  diagnostics,
1981
2085
  span: modelAttribute.span,
1982
- contextLabel: `Model "${model.name}" @@${modelAttribute.name}`
2086
+ entityLabel: attributeLabel
1983
2087
  });
1984
2088
  if (!columnNames) continue;
1985
2089
  const constraintName = parseConstraintMapArgument({
1986
2090
  attribute: modelAttribute,
1987
2091
  sourceId,
1988
2092
  diagnostics,
1989
- entityLabel: `Model "${model.name}" @@${modelAttribute.name}`,
2093
+ entityLabel: attributeLabel,
1990
2094
  span: modelAttribute.span,
1991
2095
  code: "PSL_INVALID_ATTRIBUTE_ARGUMENT"
1992
2096
  });
@@ -2068,7 +2172,7 @@ function buildModelNodeFromPsl(input) {
2068
2172
  sourceId,
2069
2173
  diagnostics,
2070
2174
  span: relationAttribute.relation.span,
2071
- contextLabel: `Relation field "${model.name}.${relationAttribute.field.name}"`
2175
+ entityLabel: `Relation field "${model.name}.${relationAttribute.field.name}"`
2072
2176
  });
2073
2177
  if (!localColumns) continue;
2074
2178
  const referencedColumns = mapFieldNamesToColumns({
@@ -2078,7 +2182,7 @@ function buildModelNodeFromPsl(input) {
2078
2182
  sourceId,
2079
2183
  diagnostics,
2080
2184
  span: relationAttribute.relation.span,
2081
- contextLabel: `Relation field "${model.name}.${relationAttribute.field.name}"`
2185
+ entityLabel: `Relation field "${model.name}.${relationAttribute.field.name}"`
2082
2186
  });
2083
2187
  if (!referencedColumns) continue;
2084
2188
  if (localColumns.length !== referencedColumns.length) {
@@ -2142,10 +2246,7 @@ function buildModelNodeFromPsl(input) {
2142
2246
  ...ifDefined("default", resolvedField.defaultValue),
2143
2247
  ...ifDefined("executionDefaults", resolvedField.executionDefaults)
2144
2248
  })),
2145
- ...primaryKeyColumns.length > 0 ? { id: {
2146
- columns: primaryKeyColumns,
2147
- ...ifDefined("name", primaryKeyName)
2148
- } } : {},
2249
+ ...ifDefined("id", primaryKey),
2149
2250
  ...uniqueConstraints.length > 0 ? { uniques: uniqueConstraints } : {},
2150
2251
  ...indexNodes.length > 0 ? { indexes: indexNodes } : {},
2151
2252
  ...foreignKeyNodes.length > 0 ? { foreignKeys: foreignKeyNodes } : {}
@@ -2547,4 +2648,4 @@ function interpretPslDocumentToSqlContract(input) {
2547
2648
 
2548
2649
  //#endregion
2549
2650
  export { interpretPslDocumentToSqlContract as t };
2550
- //# sourceMappingURL=interpreter-DJrrH8Ee.mjs.map
2651
+ //# sourceMappingURL=interpreter-BChe-9vN.mjs.map