@prisma-next/sql-contract-psl 0.11.0 → 0.12.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/package.json CHANGED
@@ -1,40 +1,51 @@
1
1
  {
2
2
  "name": "@prisma-next/sql-contract-psl",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "description": "PSL-to-SQL ContractIR interpreter for Prisma Next",
8
8
  "dependencies": {
9
- "@prisma-next/config": "0.11.0",
10
- "@prisma-next/contract": "0.11.0",
11
- "@prisma-next/framework-components": "0.11.0",
12
- "@prisma-next/psl-parser": "0.11.0",
13
- "@prisma-next/sql-contract": "0.11.0",
14
- "@prisma-next/sql-contract-ts": "0.11.0",
15
- "@prisma-next/utils": "0.11.0",
9
+ "@prisma-next/config": "0.12.0",
10
+ "@prisma-next/contract": "0.12.0",
11
+ "@prisma-next/framework-components": "0.12.0",
12
+ "@prisma-next/psl-parser": "0.12.0",
13
+ "@prisma-next/sql-contract": "0.12.0",
14
+ "@prisma-next/sql-contract-ts": "0.12.0",
15
+ "@prisma-next/utils": "0.12.0",
16
16
  "pathe": "^2.0.3"
17
17
  },
18
18
  "devDependencies": {
19
- "@prisma-next/contract-authoring": "0.11.0",
20
- "@prisma-next/test-utils": "0.11.0",
21
- "@prisma-next/tsconfig": "0.11.0",
22
- "@prisma-next/tsdown": "0.11.0",
19
+ "@prisma-next/contract-authoring": "0.12.0",
20
+ "@prisma-next/test-utils": "0.12.0",
21
+ "@prisma-next/tsconfig": "0.12.0",
22
+ "@prisma-next/tsdown": "0.12.0",
23
23
  "arktype": "^2.2.0",
24
24
  "tsdown": "0.22.0",
25
25
  "typescript": "5.9.3",
26
26
  "vitest": "4.1.6"
27
27
  },
28
+ "peerDependencies": {
29
+ "typescript": ">=5.9"
30
+ },
31
+ "peerDependenciesMeta": {
32
+ "typescript": {
33
+ "optional": true
34
+ }
35
+ },
28
36
  "files": [
29
37
  "dist",
30
38
  "src"
31
39
  ],
40
+ "types": "./dist/index.d.mts",
32
41
  "exports": {
33
42
  ".": "./dist/index.mjs",
34
43
  "./provider": "./dist/provider.mjs",
35
44
  "./package.json": "./package.json"
36
45
  },
37
- "types": "./dist/index.d.mts",
46
+ "engines": {
47
+ "node": ">=24"
48
+ },
38
49
  "repository": {
39
50
  "type": "git",
40
51
  "url": "https://github.com/prisma/prisma-next.git",
@@ -9,6 +9,7 @@ import type {
9
9
  ContractModel,
10
10
  ContractValueObject,
11
11
  } from '@prisma-next/contract/types';
12
+ import { crossRef } from '@prisma-next/contract/types';
12
13
  import type {
13
14
  AuthoringContributions,
14
15
  AuthoringEntityContext,
@@ -22,6 +23,7 @@ import type {
22
23
  MutationDefaultGeneratorDescriptor,
23
24
  } from '@prisma-next/framework-components/control';
24
25
  import type { Namespace } from '@prisma-next/framework-components/ir';
26
+ import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
25
27
  import type {
26
28
  ParsePslDocumentResult,
27
29
  PslAttribute,
@@ -227,6 +229,10 @@ const UNSPECIFIED_PSL_NAMESPACE_NAME = '__unspecified__';
227
229
  * slot empty (which means the late-bound default at the `StorageTable`
228
230
  * layer; emitted JSON omits the field).
229
231
  */
232
+ function defaultSqlNamespaceIdForTarget(targetId: string): string {
233
+ return targetId === 'postgres' ? 'public' : UNBOUND_NAMESPACE_ID;
234
+ }
235
+
230
236
  function resolveNamespaceIdForSqlTarget(input: {
231
237
  readonly bucketName: string;
232
238
  readonly targetId: string;
@@ -235,7 +241,7 @@ function resolveNamespaceIdForSqlTarget(input: {
235
241
  return undefined;
236
242
  }
237
243
  if (input.bucketName === UNSPECIFIED_PSL_NAMESPACE_NAME) {
238
- return undefined;
244
+ return 'public';
239
245
  }
240
246
  if (input.bucketName === 'unbound') {
241
247
  return '__unbound__';
@@ -1303,6 +1309,8 @@ function resolvePolymorphism(
1303
1309
  baseDeclarations: Map<string, BaseDeclaration>,
1304
1310
  modelNames: Set<string>,
1305
1311
  modelMappings: ReadonlyMap<string, ModelNameMapping>,
1312
+ modelNamespaceIds: ReadonlyMap<string, string>,
1313
+ targetId: string,
1306
1314
  sourceId: string,
1307
1315
  diagnostics: ContractSourceDiagnostic[],
1308
1316
  ): Record<string, ContractModel> {
@@ -1406,7 +1414,10 @@ function resolvePolymorphism(
1406
1414
  ...patched,
1407
1415
  [variantName]: {
1408
1416
  ...variantModel,
1409
- base: baseDecl.baseName,
1417
+ base: crossRef(
1418
+ baseDecl.baseName,
1419
+ modelNamespaceIds.get(baseDecl.baseName) ?? defaultSqlNamespaceIdForTarget(targetId),
1420
+ ),
1410
1421
  ...(resolvedTable ? { storage: { ...variantModel.storage, table: resolvedTable } } : {}),
1411
1422
  },
1412
1423
  };
@@ -1668,10 +1679,18 @@ export function interpretPslDocumentToSqlContract(
1668
1679
  })),
1669
1680
  });
1670
1681
 
1671
- let patchedModels = patchModelDomainFields(
1672
- contract.models as Record<string, ContractModel>,
1673
- modelResolvedFields,
1674
- );
1682
+ const modelsForPatch: Record<string, ContractModel> = {};
1683
+ for (const namespaceSlice of Object.values(contract.domain.namespaces)) {
1684
+ for (const [modelName, model] of Object.entries(namespaceSlice.models)) {
1685
+ if (Object.hasOwn(modelsForPatch, modelName)) {
1686
+ throw new Error(
1687
+ `duplicate model name "${modelName}" across domain namespaces during PSL interpretation`,
1688
+ );
1689
+ }
1690
+ modelsForPatch[modelName] = model as ContractModel;
1691
+ }
1692
+ }
1693
+ let patchedModels = patchModelDomainFields(modelsForPatch, modelResolvedFields);
1675
1694
 
1676
1695
  const polyDiagnostics: ContractSourceDiagnostic[] = [];
1677
1696
  patchedModels = resolvePolymorphism(
@@ -1680,6 +1699,8 @@ export function interpretPslDocumentToSqlContract(
1680
1699
  baseDeclarations,
1681
1700
  modelNames,
1682
1701
  modelMappings,
1702
+ modelNamespaceIds,
1703
+ input.target.targetId,
1683
1704
  sourceId,
1684
1705
  polyDiagnostics,
1685
1706
  );
@@ -1693,14 +1714,36 @@ export function interpretPslDocumentToSqlContract(
1693
1714
 
1694
1715
  const variantModelNames = new Set(baseDeclarations.keys());
1695
1716
  const filteredRoots = Object.fromEntries(
1696
- Object.entries(contract.roots).filter(([, modelName]) => !variantModelNames.has(modelName)),
1717
+ Object.entries(contract.roots).filter(
1718
+ ([, crossReference]) => !variantModelNames.has(crossReference.model),
1719
+ ),
1697
1720
  );
1698
1721
 
1699
1722
  const patchedContract: Contract = {
1700
1723
  ...contract,
1701
1724
  roots: filteredRoots,
1702
- models: patchedModels,
1703
- ...(Object.keys(valueObjects).length > 0 ? { valueObjects } : {}),
1725
+ domain: {
1726
+ namespaces: Object.fromEntries(
1727
+ Object.entries(contract.domain.namespaces).map(([namespaceId, namespaceSlice]) => [
1728
+ namespaceId,
1729
+ {
1730
+ models: Object.fromEntries(
1731
+ Object.entries(namespaceSlice.models).map(([modelName, model]) => [
1732
+ modelName,
1733
+ patchedModels[modelName] ?? model,
1734
+ ]),
1735
+ ),
1736
+ ...(namespaceSlice.valueObjects !== undefined
1737
+ ? { valueObjects: namespaceSlice.valueObjects }
1738
+ : {}),
1739
+ ...(namespaceId === defaultSqlNamespaceIdForTarget(input.target.targetId) &&
1740
+ Object.keys(valueObjects).length > 0
1741
+ ? { valueObjects }
1742
+ : {}),
1743
+ },
1744
+ ]),
1745
+ ),
1746
+ },
1704
1747
  };
1705
1748
 
1706
1749
  return ok(patchedContract);