@prisma-next/sql-contract-psl 0.5.0-dev.60 → 0.5.0-dev.61

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":"provider.mjs","names":["schema: string"],"sources":["../src/provider.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { ContractConfig } from '@prisma-next/config/config-types';\nimport type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport type { ExtensionPackRef, TargetPackRef } from '@prisma-next/framework-components/components';\nimport { parsePslDocument } from '@prisma-next/psl-parser';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport { interpretPslDocumentToSqlContract } from './interpreter';\nimport type { ColumnDescriptor } from './psl-column-resolution';\n\nexport interface PrismaContractOptions {\n readonly output?: string;\n readonly target: TargetPackRef<'sql', string>;\n readonly composedExtensionPackRefs?: readonly ExtensionPackRef<'sql', string>[];\n}\n\nfunction buildColumnDescriptorMap(\n scalarTypeDescriptors: ReadonlyMap<string, string>,\n codecLookup: CodecLookup,\n): ReadonlyMap<string, ColumnDescriptor> {\n const result = new Map<string, ColumnDescriptor>();\n for (const [typeName, codecId] of scalarTypeDescriptors) {\n const codec = codecLookup.get(codecId);\n if (!codec) continue;\n const nativeType = codec.targetTypes[0];\n if (nativeType === undefined) continue;\n result.set(typeName, { codecId, nativeType });\n }\n return result;\n}\n\nexport function prismaContract(schemaPath: string, options: PrismaContractOptions): ContractConfig {\n return {\n source: {\n inputs: [schemaPath],\n load: async (context) => {\n const [absoluteSchemaPath] = context.resolvedInputs;\n if (absoluteSchemaPath === undefined) {\n throw new Error(\n 'prismaContract: context.resolvedInputs is empty. The CLI config loader should populate it positional-matched with source.inputs.',\n );\n }\n let schema: string;\n try {\n schema = await readFile(absoluteSchemaPath, 'utf-8');\n } catch (error) {\n const message = String(error);\n return notOk({\n summary: `Failed to read Prisma schema at \"${schemaPath}\"`,\n diagnostics: [\n {\n code: 'PSL_SCHEMA_READ_FAILED',\n message,\n sourceId: schemaPath,\n },\n ],\n meta: { schemaPath, absoluteSchemaPath, cause: message },\n });\n }\n\n const document = parsePslDocument({\n schema,\n sourceId: schemaPath,\n });\n\n const scalarTypeDescriptors = buildColumnDescriptorMap(\n context.scalarTypeDescriptors,\n context.codecLookup,\n );\n\n const interpreted = interpretPslDocumentToSqlContract({\n document,\n target: options.target,\n authoringContributions: context.authoringContributions,\n scalarTypeDescriptors,\n ...ifDefined(\n 'composedExtensionPacks',\n context.composedExtensionPacks.length > 0\n ? [...context.composedExtensionPacks]\n : undefined,\n ),\n ...ifDefined(\n 'composedExtensionPackRefs',\n options.composedExtensionPackRefs?.length\n ? options.composedExtensionPackRefs\n : undefined,\n ),\n controlMutationDefaults: context.controlMutationDefaults,\n });\n if (!interpreted.ok) {\n return interpreted;\n }\n\n return ok(interpreted.value);\n },\n },\n ...ifDefined('output', options.output),\n };\n}\n"],"mappings":";;;;;;;AAgBA,SAAS,yBACP,uBACA,aACuC;CACvC,MAAM,yBAAS,IAAI,KAA+B;AAClD,MAAK,MAAM,CAAC,UAAU,YAAY,uBAAuB;EACvD,MAAM,QAAQ,YAAY,IAAI,QAAQ;AACtC,MAAI,CAAC,MAAO;EACZ,MAAM,aAAa,MAAM,YAAY;AACrC,MAAI,eAAe,OAAW;AAC9B,SAAO,IAAI,UAAU;GAAE;GAAS;GAAY,CAAC;;AAE/C,QAAO;;AAGT,SAAgB,eAAe,YAAoB,SAAgD;AACjG,QAAO;EACL,QAAQ;GACN,QAAQ,CAAC,WAAW;GACpB,MAAM,OAAO,YAAY;IACvB,MAAM,CAAC,sBAAsB,QAAQ;AACrC,QAAI,uBAAuB,OACzB,OAAM,IAAI,MACR,mIACD;IAEH,IAAIA;AACJ,QAAI;AACF,cAAS,MAAM,SAAS,oBAAoB,QAAQ;aAC7C,OAAO;KACd,MAAM,UAAU,OAAO,MAAM;AAC7B,YAAO,MAAM;MACX,SAAS,oCAAoC,WAAW;MACxD,aAAa,CACX;OACE,MAAM;OACN;OACA,UAAU;OACX,CACF;MACD,MAAM;OAAE;OAAY;OAAoB,OAAO;OAAS;MACzD,CAAC;;IAGJ,MAAM,WAAW,iBAAiB;KAChC;KACA,UAAU;KACX,CAAC;IAEF,MAAM,wBAAwB,yBAC5B,QAAQ,uBACR,QAAQ,YACT;IAED,MAAM,cAAc,kCAAkC;KACpD;KACA,QAAQ,QAAQ;KAChB,wBAAwB,QAAQ;KAChC;KACA,GAAG,UACD,0BACA,QAAQ,uBAAuB,SAAS,IACpC,CAAC,GAAG,QAAQ,uBAAuB,GACnC,OACL;KACD,GAAG,UACD,6BACA,QAAQ,2BAA2B,SAC/B,QAAQ,4BACR,OACL;KACD,yBAAyB,QAAQ;KAClC,CAAC;AACF,QAAI,CAAC,YAAY,GACf,QAAO;AAGT,WAAO,GAAG,YAAY,MAAM;;GAE/B;EACD,GAAG,UAAU,UAAU,QAAQ,OAAO;EACvC"}
1
+ {"version":3,"file":"provider.mjs","names":["schema: string"],"sources":["../src/provider.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { ContractConfig } from '@prisma-next/config/config-types';\nimport type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport type { ExtensionPackRef, TargetPackRef } from '@prisma-next/framework-components/components';\nimport { parsePslDocument } from '@prisma-next/psl-parser';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport { interpretPslDocumentToSqlContract } from './interpreter';\nimport type { ColumnDescriptor } from './psl-column-resolution';\n\nexport interface PrismaContractOptions {\n readonly output?: string;\n readonly target: TargetPackRef<'sql', string>;\n readonly composedExtensionPackRefs?: readonly ExtensionPackRef<'sql', string>[];\n}\n\nfunction buildColumnDescriptorMap(\n scalarTypeDescriptors: ReadonlyMap<string, string>,\n codecLookup: CodecLookup,\n): ReadonlyMap<string, ColumnDescriptor> {\n const result = new Map<string, ColumnDescriptor>();\n for (const [typeName, codecId] of scalarTypeDescriptors) {\n const nativeType = codecLookup.targetTypesFor(codecId)?.[0];\n if (nativeType === undefined) continue;\n result.set(typeName, { codecId, nativeType });\n }\n return result;\n}\n\nexport function prismaContract(schemaPath: string, options: PrismaContractOptions): ContractConfig {\n return {\n source: {\n inputs: [schemaPath],\n load: async (context) => {\n const [absoluteSchemaPath] = context.resolvedInputs;\n if (absoluteSchemaPath === undefined) {\n throw new Error(\n 'prismaContract: context.resolvedInputs is empty. The CLI config loader should populate it positional-matched with source.inputs.',\n );\n }\n let schema: string;\n try {\n schema = await readFile(absoluteSchemaPath, 'utf-8');\n } catch (error) {\n const message = String(error);\n return notOk({\n summary: `Failed to read Prisma schema at \"${schemaPath}\"`,\n diagnostics: [\n {\n code: 'PSL_SCHEMA_READ_FAILED',\n message,\n sourceId: schemaPath,\n },\n ],\n meta: { schemaPath, absoluteSchemaPath, cause: message },\n });\n }\n\n const document = parsePslDocument({\n schema,\n sourceId: schemaPath,\n });\n\n const scalarTypeDescriptors = buildColumnDescriptorMap(\n context.scalarTypeDescriptors,\n context.codecLookup,\n );\n\n const interpreted = interpretPslDocumentToSqlContract({\n document,\n target: options.target,\n authoringContributions: context.authoringContributions,\n scalarTypeDescriptors,\n ...ifDefined(\n 'composedExtensionPacks',\n context.composedExtensionPacks.length > 0\n ? [...context.composedExtensionPacks]\n : undefined,\n ),\n ...ifDefined(\n 'composedExtensionPackRefs',\n options.composedExtensionPackRefs?.length\n ? options.composedExtensionPackRefs\n : undefined,\n ),\n controlMutationDefaults: context.controlMutationDefaults,\n });\n if (!interpreted.ok) {\n return interpreted;\n }\n\n return ok(interpreted.value);\n },\n },\n ...ifDefined('output', options.output),\n };\n}\n"],"mappings":";;;;;;;AAgBA,SAAS,yBACP,uBACA,aACuC;CACvC,MAAM,yBAAS,IAAI,KAA+B;AAClD,MAAK,MAAM,CAAC,UAAU,YAAY,uBAAuB;EACvD,MAAM,aAAa,YAAY,eAAe,QAAQ,GAAG;AACzD,MAAI,eAAe,OAAW;AAC9B,SAAO,IAAI,UAAU;GAAE;GAAS;GAAY,CAAC;;AAE/C,QAAO;;AAGT,SAAgB,eAAe,YAAoB,SAAgD;AACjG,QAAO;EACL,QAAQ;GACN,QAAQ,CAAC,WAAW;GACpB,MAAM,OAAO,YAAY;IACvB,MAAM,CAAC,sBAAsB,QAAQ;AACrC,QAAI,uBAAuB,OACzB,OAAM,IAAI,MACR,mIACD;IAEH,IAAIA;AACJ,QAAI;AACF,cAAS,MAAM,SAAS,oBAAoB,QAAQ;aAC7C,OAAO;KACd,MAAM,UAAU,OAAO,MAAM;AAC7B,YAAO,MAAM;MACX,SAAS,oCAAoC,WAAW;MACxD,aAAa,CACX;OACE,MAAM;OACN;OACA,UAAU;OACX,CACF;MACD,MAAM;OAAE;OAAY;OAAoB,OAAO;OAAS;MACzD,CAAC;;IAGJ,MAAM,WAAW,iBAAiB;KAChC;KACA,UAAU;KACX,CAAC;IAEF,MAAM,wBAAwB,yBAC5B,QAAQ,uBACR,QAAQ,YACT;IAED,MAAM,cAAc,kCAAkC;KACpD;KACA,QAAQ,QAAQ;KAChB,wBAAwB,QAAQ;KAChC;KACA,GAAG,UACD,0BACA,QAAQ,uBAAuB,SAAS,IACpC,CAAC,GAAG,QAAQ,uBAAuB,GACnC,OACL;KACD,GAAG,UACD,6BACA,QAAQ,2BAA2B,SAC/B,QAAQ,4BACR,OACL;KACD,yBAAyB,QAAQ;KAClC,CAAC;AACF,QAAI,CAAC,YAAY,GACf,QAAO;AAGT,WAAO,GAAG,YAAY,MAAM;;GAE/B;EACD,GAAG,UAAU,UAAU,QAAQ,OAAO;EACvC"}
package/package.json CHANGED
@@ -1,27 +1,27 @@
1
1
  {
2
2
  "name": "@prisma-next/sql-contract-psl",
3
- "version": "0.5.0-dev.60",
3
+ "version": "0.5.0-dev.61",
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
9
  "pathe": "^2.0.3",
10
- "@prisma-next/config": "0.5.0-dev.60",
11
- "@prisma-next/framework-components": "0.5.0-dev.60",
12
- "@prisma-next/psl-parser": "0.5.0-dev.60",
13
- "@prisma-next/contract": "0.5.0-dev.60",
14
- "@prisma-next/sql-contract": "0.5.0-dev.60",
15
- "@prisma-next/sql-contract-ts": "0.5.0-dev.60",
16
- "@prisma-next/utils": "0.5.0-dev.60"
10
+ "@prisma-next/config": "0.5.0-dev.61",
11
+ "@prisma-next/contract": "0.5.0-dev.61",
12
+ "@prisma-next/sql-contract": "0.5.0-dev.61",
13
+ "@prisma-next/framework-components": "0.5.0-dev.61",
14
+ "@prisma-next/sql-contract-ts": "0.5.0-dev.61",
15
+ "@prisma-next/utils": "0.5.0-dev.61",
16
+ "@prisma-next/psl-parser": "0.5.0-dev.61"
17
17
  },
18
18
  "devDependencies": {
19
19
  "tsdown": "0.18.4",
20
20
  "typescript": "5.9.3",
21
21
  "vitest": "4.0.17",
22
- "@prisma-next/contract-authoring": "0.5.0-dev.60",
23
- "@prisma-next/tsconfig": "0.0.0",
22
+ "@prisma-next/contract-authoring": "0.5.0-dev.61",
24
23
  "@prisma-next/test-utils": "0.0.1",
24
+ "@prisma-next/tsconfig": "0.0.0",
25
25
  "@prisma-next/tsdown": "0.0.0"
26
26
  },
27
27
  "files": [
package/src/provider.ts CHANGED
@@ -20,9 +20,7 @@ function buildColumnDescriptorMap(
20
20
  ): ReadonlyMap<string, ColumnDescriptor> {
21
21
  const result = new Map<string, ColumnDescriptor>();
22
22
  for (const [typeName, codecId] of scalarTypeDescriptors) {
23
- const codec = codecLookup.get(codecId);
24
- if (!codec) continue;
25
- const nativeType = codec.targetTypes[0];
23
+ const nativeType = codecLookup.targetTypesFor(codecId)?.[0];
26
24
  if (nativeType === undefined) continue;
27
25
  result.set(typeName, { codecId, nativeType });
28
26
  }
@@ -41,7 +41,7 @@ export type ColumnDescriptor = {
41
41
  readonly codecId: string;
42
42
  readonly nativeType: string;
43
43
  readonly typeRef?: string;
44
- readonly typeParams?: Record<string, unknown>;
44
+ readonly typeParams?: Record<string, unknown> | undefined;
45
45
  };
46
46
 
47
47
  export function toNamedTypeFieldDescriptor(
@@ -72,16 +72,9 @@ export function getAuthoringTypeConstructor(
72
72
  }
73
73
 
74
74
  /**
75
- * Walks `authoringContributions.field` segment-by-segment and returns the
76
- * field-preset descriptor at the resolved path, or `undefined` if no descriptor
77
- * is registered.
75
+ * Walks `authoringContributions.field` segment-by-segment and returns the field-preset descriptor at the resolved path, or `undefined` if no descriptor is registered.
78
76
  *
79
- * Symmetric with `getAuthoringTypeConstructor`. Field presets are strictly
80
- * richer than type constructors — they can contribute `default` /
81
- * `executionDefaults` / `id` / `unique` / `nullable` in addition to the
82
- * `codecId` / `nativeType` / `typeParams` triple. PSL resolution tries field
83
- * presets first, then falls back to type constructors on miss (see
84
- * `resolveFieldTypeDescriptor`).
77
+ * Symmetric with `getAuthoringTypeConstructor`. Field presets are strictly richer than type constructors — they can contribute `default` / `executionDefaults` / `id` / `unique` / `nullable` in addition to the `codecId` / `nativeType` / `typeParams` triple. PSL resolution tries field presets first, then falls back to type constructors on miss (see `resolveFieldTypeDescriptor`).
85
78
  */
86
79
  export function getAuthoringFieldPreset(
87
80
  contributions: AuthoringContributions | undefined,
@@ -100,9 +93,7 @@ export function getAuthoringFieldPreset(
100
93
  }
101
94
 
102
95
  /**
103
- * Returns the namespace prefix of `attributeName` if it references an
104
- * unrecognized extension namespace, otherwise `undefined`. A namespace is
105
- * considered recognized when it is:
96
+ * Returns the namespace prefix of `attributeName` if it references an unrecognized extension namespace, otherwise `undefined`. A namespace is considered recognized when it is:
106
97
  *
107
98
  * - `db` (native-type spec, always allowed),
108
99
  * - the active family id (e.g. `sql`),
@@ -110,10 +101,7 @@ export function getAuthoringFieldPreset(
110
101
  * - a registered field-preset namespace (e.g. `temporal`),
111
102
  * - present in `composedExtensions`.
112
103
  *
113
- * Family/target/field-preset namespaces are exempted so that e.g. `@sql.foo`
114
- * surfaces as PSL_UNSUPPORTED_*_ATTRIBUTE (the attribute isn't defined)
115
- * rather than PSL_EXTENSION_NAMESPACE_NOT_COMPOSED (the namespace is already
116
- * composed).
104
+ * Family/target/field-preset namespaces are exempted so that e.g. `@sql.foo` surfaces as PSL_UNSUPPORTED_*_ATTRIBUTE (the attribute isn't defined) rather than PSL_EXTENSION_NAMESPACE_NOT_COMPOSED (the namespace is already composed).
117
105
  */
118
106
  export function checkUncomposedNamespace(
119
107
  attributeName: string,
@@ -142,12 +130,9 @@ export function checkUncomposedNamespace(
142
130
  }
143
131
 
144
132
  /**
145
- * Pushes the canonical `PSL_EXTENSION_NAMESPACE_NOT_COMPOSED` diagnostic for a
146
- * subject (attribute, model attribute, or type constructor) that references an
147
- * extension namespace which is not composed in the current contract.
133
+ * Pushes the canonical `PSL_EXTENSION_NAMESPACE_NOT_COMPOSED` diagnostic for a subject (attribute, model attribute, or type constructor) that references an extension namespace which is not composed in the current contract.
148
134
  *
149
- * The `data` payload carries the missing namespace so machine consumers
150
- * (agents, IDE extensions, CLI auto-fix) don't have to parse the prose.
135
+ * The `data` payload carries the missing namespace so machine consumers (agents, IDE extensions, CLI auto-fix) don't have to parse the prose.
151
136
  */
152
137
  export function reportUncomposedNamespace(input: {
153
138
  readonly subjectLabel: string;
@@ -166,10 +151,7 @@ export function reportUncomposedNamespace(input: {
166
151
  }
167
152
 
168
153
  /**
169
- * Pushes the canonical `PSL_UNKNOWN_FIELD_PRESET` diagnostic when a typoed
170
- * preset name is referenced inside a registered field-preset namespace. The
171
- * `data` payload exposes the namespace and full helper path so machine
172
- * consumers (agents, IDE extensions) don't have to parse the prose.
154
+ * Pushes the canonical `PSL_UNKNOWN_FIELD_PRESET` diagnostic when a typoed preset name is referenced inside a registered field-preset namespace. The `data` payload exposes the namespace and full helper path so machine consumers (agents, IDE extensions) don't have to parse the prose.
173
155
  */
174
156
  export function reportUnknownFieldPreset(input: {
175
157
  readonly entityLabel: string;
@@ -292,16 +274,9 @@ export function resolvePslTypeConstructorDescriptor(input: {
292
274
  }
293
275
 
294
276
  /**
295
- * Instantiates a field-preset call against its descriptor, coercing PSL AST
296
- * arguments into the descriptor's typed argument shape and returning the
297
- * preset's full set of contract contributions.
277
+ * Instantiates a field-preset call against its descriptor, coercing PSL AST arguments into the descriptor's typed argument shape and returning the preset's full set of contract contributions.
298
278
  *
299
- * Symmetric with `instantiatePslTypeConstructor` but richer: a field preset
300
- * can contribute `default`, `executionDefaults`, `id`, `unique`, and
301
- * `nullable` in addition to the storage-type triple. PSL → typed-args
302
- * coercion happens here (via `mapPslHelperArgs`) so that
303
- * `instantiateAuthoringFieldPreset` itself stays typed-input-only and TS
304
- * keeps its zero-runtime-validation cost.
279
+ * Symmetric with `instantiatePslTypeConstructor` but richer: a field preset can contribute `default`, `executionDefaults`, `id`, `unique`, and `nullable` in addition to the storage-type triple. PSL → typed-args coercion happens here (via `mapPslHelperArgs`) so that `instantiateAuthoringFieldPreset` itself stays typed-input-only and TS keeps its zero-runtime-validation cost.
305
280
  */
306
281
  export function instantiatePslFieldPreset(input: {
307
282
  readonly call: PslTypeConstructorCall;
@@ -365,10 +340,7 @@ export function instantiatePslFieldPreset(input: {
365
340
  }
366
341
 
367
342
  /**
368
- * Contract contributions a field preset adds beyond the bare storage-type
369
- * triple. Set when a field is resolved through the field-preset dispatch
370
- * path; absent when resolved through the type-constructor path or as a
371
- * scalar/enum/named-type lookup.
343
+ * Contract contributions a field preset adds beyond the bare storage-type triple. Set when a field is resolved through the field-preset dispatch path; absent when resolved through the type-constructor path or as a scalar/enum/named-type lookup.
372
344
  */
373
345
  export type FieldPresetContributions = {
374
346
  readonly nullable: boolean;
@@ -400,9 +372,7 @@ export function resolveFieldTypeDescriptor(input: {
400
372
  readonly entityLabel: string;
401
373
  }): ResolveFieldTypeResult {
402
374
  if (input.field.typeConstructor) {
403
- // Field presets carry richer semantics than type constructors, so a field
404
- // preset match is the complete answer. Shared composition rejects exact
405
- // cross-registry collisions before PSL resolution can observe them.
375
+ // Field presets carry richer semantics than type constructors, so a field preset match is the complete answer. Shared composition rejects exact cross-registry collisions before PSL resolution can observe them.
406
376
  const presetDescriptor = getAuthoringFieldPreset(
407
377
  input.authoringContributions,
408
378
  input.field.typeConstructor.path,
@@ -778,11 +748,7 @@ export function lowerDefaultForField(input: {
778
748
  return {};
779
749
  }
780
750
 
781
- // Preset-only generators (e.g. `timestampNow`) co-register their codec
782
- // through the preset descriptor, so they don't carry an
783
- // `applicableCodecIds` list. Such a generator surfacing on the
784
- // `@default(...)` lowering path is itself the bug — emit a diagnostic
785
- // pointing the user at the correct authoring surface.
751
+ // Preset-only generators (e.g. `timestampNow`) co-register their codec through the preset descriptor, so they don't carry an `applicableCodecIds` list. Such a generator surfacing on the `@default(...)` lowering path is itself the bug — emit a diagnostic pointing the user at the correct authoring surface.
786
752
  if (generatorDescriptor.applicableCodecIds === undefined) {
787
753
  input.diagnostics.push({
788
754
  code: 'PSL_INVALID_DEFAULT_APPLICABILITY',