@prisma-next/sql-contract-psl 0.5.0-dev.80 → 0.5.0-dev.82
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/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{interpreter-C9MPo8FK.mjs → interpreter-ijCjxhaU.mjs} +150 -5
- package/dist/interpreter-ijCjxhaU.mjs.map +1 -0
- package/dist/provider.mjs +1 -1
- package/package.json +11 -10
- package/src/interpreter.ts +44 -0
- package/src/psl-attribute-parsing.ts +126 -0
- package/dist/interpreter-C9MPo8FK.mjs.map +0 -1
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/psl-column-resolution.ts","../src/interpreter.ts"],"mappings":";;;;;;;;;KAuCY,gBAAA;EAAA,SACD,OAAA;EAAA,SACA,UAAA;EAAA,SACA,OAAA;EAAA,SACA,UAAA,GAAa,MAAA;AAAA;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/psl-column-resolution.ts","../src/interpreter.ts"],"mappings":";;;;;;;;;KAuCY,gBAAA;EAAA,SACD,OAAA;EAAA,SACA,UAAA;EAAA,SACA,OAAA;EAAA,SACA,UAAA,GAAa,MAAA;AAAA;;;UCsCP,sCAAA;EAAA,SACN,QAAA,EAAU,sBAAA;EAAA,SACV,MAAA,EAAQ,aAAA;EAAA,SACR,qBAAA,EAAuB,WAAA,SAAoB,gBAAA;EAAA,SAC3C,sBAAA;EAAA,SACA,yBAAA,YAAqC,gBAAA;EAAA,SACrC,uBAAA,GAA0B,yBAAA;EAAA,SAC1B,sBAAA,GAAyB,sBAAA;AAAA;AAAA,iBA+nCpB,iCAAA,CACd,KAAA,EAAO,sCAAA,GACN,MAAA,CAAO,QAAA,EAAU,yBAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as interpretPslDocumentToSqlContract } from "./interpreter-
|
|
1
|
+
import { t as interpretPslDocumentToSqlContract } from "./interpreter-ijCjxhaU.mjs";
|
|
2
2
|
export { interpretPslDocumentToSqlContract };
|
|
@@ -76,6 +76,109 @@ function parseConstraintMapArgument(input) {
|
|
|
76
76
|
function getPositionalArguments(attribute) {
|
|
77
77
|
return attribute.args.filter((arg) => arg.kind === "positional").map((arg) => arg.kind === "positional" ? arg.value : "");
|
|
78
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Parses a PSL object-literal attribute argument value of the form
|
|
81
|
+
* `{ key1: "value1", key2: "value2" }` into a `Record<string, string>`.
|
|
82
|
+
*
|
|
83
|
+
* V1 admits string literals only as leaf values. Boolean and number
|
|
84
|
+
* literals are rejected. Trailing commas are allowed.
|
|
85
|
+
*
|
|
86
|
+
* Returns the parsed record, or pushes a diagnostic and returns undefined
|
|
87
|
+
* on malformed input or non-string leaves.
|
|
88
|
+
*/
|
|
89
|
+
function parseObjectLiteralStringMap(input) {
|
|
90
|
+
const trimmed = input.raw.trim();
|
|
91
|
+
if (!trimmed.startsWith("{") || !trimmed.endsWith("}")) return pushInvalidAttributeArgument({
|
|
92
|
+
diagnostics: input.diagnostics,
|
|
93
|
+
sourceId: input.sourceId,
|
|
94
|
+
span: input.span,
|
|
95
|
+
message: `${input.entityLabel} expected an object literal value of the form { key: "value", ... }`
|
|
96
|
+
});
|
|
97
|
+
const body = trimmed.slice(1, -1).trim();
|
|
98
|
+
if (body.length === 0) return {};
|
|
99
|
+
const result = {};
|
|
100
|
+
for (const part of splitObjectLiteralEntries(body)) {
|
|
101
|
+
const colonAt = findTopLevelColon(part);
|
|
102
|
+
if (colonAt === -1) return pushInvalidAttributeArgument({
|
|
103
|
+
diagnostics: input.diagnostics,
|
|
104
|
+
sourceId: input.sourceId,
|
|
105
|
+
span: input.span,
|
|
106
|
+
message: `${input.entityLabel} object-literal entry "${part}" is missing a "key: value" colon`
|
|
107
|
+
});
|
|
108
|
+
const key = part.slice(0, colonAt).trim();
|
|
109
|
+
const rawValue = part.slice(colonAt + 1).trim();
|
|
110
|
+
if (key.length === 0 || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) return pushInvalidAttributeArgument({
|
|
111
|
+
diagnostics: input.diagnostics,
|
|
112
|
+
sourceId: input.sourceId,
|
|
113
|
+
span: input.span,
|
|
114
|
+
message: `${input.entityLabel} object-literal key "${key}" must be a bare identifier`
|
|
115
|
+
});
|
|
116
|
+
const parsedString = parseQuotedStringLiteral(rawValue);
|
|
117
|
+
if (parsedString === void 0) return pushInvalidAttributeArgument({
|
|
118
|
+
diagnostics: input.diagnostics,
|
|
119
|
+
sourceId: input.sourceId,
|
|
120
|
+
span: input.span,
|
|
121
|
+
message: `${input.entityLabel} object-literal value for "${key}" must be a quoted string literal (V1 PSL @@index options support string leaves only; use the TS authoring surface for non-string options)`
|
|
122
|
+
});
|
|
123
|
+
if (Object.hasOwn(result, key)) return pushInvalidAttributeArgument({
|
|
124
|
+
diagnostics: input.diagnostics,
|
|
125
|
+
sourceId: input.sourceId,
|
|
126
|
+
span: input.span,
|
|
127
|
+
message: `${input.entityLabel} object-literal key "${key}" appears more than once`
|
|
128
|
+
});
|
|
129
|
+
result[key] = parsedString;
|
|
130
|
+
}
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
function splitObjectLiteralEntries(body) {
|
|
134
|
+
const parts = [];
|
|
135
|
+
let depthBrace = 0;
|
|
136
|
+
let depthBracket = 0;
|
|
137
|
+
let depthParen = 0;
|
|
138
|
+
let quote = null;
|
|
139
|
+
let start = 0;
|
|
140
|
+
for (let index = 0; index < body.length; index += 1) {
|
|
141
|
+
const ch = body[index] ?? "";
|
|
142
|
+
if (quote) {
|
|
143
|
+
if (ch === quote && body[index - 1] !== "\\") quote = null;
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (ch === "\"" || ch === "'") {
|
|
147
|
+
quote = ch;
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
if (ch === "{") depthBrace += 1;
|
|
151
|
+
else if (ch === "}") depthBrace = Math.max(0, depthBrace - 1);
|
|
152
|
+
else if (ch === "[") depthBracket += 1;
|
|
153
|
+
else if (ch === "]") depthBracket = Math.max(0, depthBracket - 1);
|
|
154
|
+
else if (ch === "(") depthParen += 1;
|
|
155
|
+
else if (ch === ")") depthParen = Math.max(0, depthParen - 1);
|
|
156
|
+
else if (ch === "," && depthBrace === 0 && depthBracket === 0 && depthParen === 0) {
|
|
157
|
+
const segment = body.slice(start, index).trim();
|
|
158
|
+
if (segment.length > 0) parts.push(segment);
|
|
159
|
+
start = index + 1;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const tail = body.slice(start).trim();
|
|
163
|
+
if (tail.length > 0) parts.push(tail);
|
|
164
|
+
return parts;
|
|
165
|
+
}
|
|
166
|
+
function findTopLevelColon(entry) {
|
|
167
|
+
let quote = null;
|
|
168
|
+
for (let index = 0; index < entry.length; index += 1) {
|
|
169
|
+
const ch = entry[index] ?? "";
|
|
170
|
+
if (quote) {
|
|
171
|
+
if (ch === quote && entry[index - 1] !== "\\") quote = null;
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
if (ch === "\"" || ch === "'") {
|
|
175
|
+
quote = ch;
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
if (ch === ":") return index;
|
|
179
|
+
}
|
|
180
|
+
return -1;
|
|
181
|
+
}
|
|
79
182
|
function pushInvalidAttributeArgument(input) {
|
|
80
183
|
input.diagnostics.push({
|
|
81
184
|
code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
|
|
@@ -2072,10 +2175,52 @@ function buildModelNodeFromPsl(input) {
|
|
|
2072
2175
|
columns: columnNames,
|
|
2073
2176
|
...ifDefined("name", constraintName)
|
|
2074
2177
|
});
|
|
2075
|
-
else
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2178
|
+
else {
|
|
2179
|
+
const indexEntityLabel = `Model "${model.name}" @@index`;
|
|
2180
|
+
const rawTypeArg = getNamedArgument(modelAttribute, "type");
|
|
2181
|
+
let indexType;
|
|
2182
|
+
if (rawTypeArg !== void 0) {
|
|
2183
|
+
const parsed = parseQuotedStringLiteral(rawTypeArg);
|
|
2184
|
+
if (parsed === void 0) {
|
|
2185
|
+
diagnostics.push({
|
|
2186
|
+
code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
|
|
2187
|
+
message: `${indexEntityLabel} type argument must be a quoted string literal`,
|
|
2188
|
+
sourceId,
|
|
2189
|
+
span: modelAttribute.span
|
|
2190
|
+
});
|
|
2191
|
+
continue;
|
|
2192
|
+
}
|
|
2193
|
+
indexType = parsed;
|
|
2194
|
+
}
|
|
2195
|
+
const rawOptionsArg = getNamedArgument(modelAttribute, "options");
|
|
2196
|
+
let indexOptions;
|
|
2197
|
+
if (rawOptionsArg !== void 0) {
|
|
2198
|
+
if (indexType === void 0) {
|
|
2199
|
+
diagnostics.push({
|
|
2200
|
+
code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
|
|
2201
|
+
message: `${indexEntityLabel} options argument requires a type argument`,
|
|
2202
|
+
sourceId,
|
|
2203
|
+
span: modelAttribute.span
|
|
2204
|
+
});
|
|
2205
|
+
continue;
|
|
2206
|
+
}
|
|
2207
|
+
const parsed = parseObjectLiteralStringMap({
|
|
2208
|
+
raw: rawOptionsArg,
|
|
2209
|
+
diagnostics,
|
|
2210
|
+
sourceId,
|
|
2211
|
+
span: modelAttribute.span,
|
|
2212
|
+
entityLabel: indexEntityLabel
|
|
2213
|
+
});
|
|
2214
|
+
if (parsed === void 0) continue;
|
|
2215
|
+
indexOptions = parsed;
|
|
2216
|
+
}
|
|
2217
|
+
indexNodes.push({
|
|
2218
|
+
columns: columnNames,
|
|
2219
|
+
...ifDefined("name", constraintName),
|
|
2220
|
+
...ifDefined("type", indexType),
|
|
2221
|
+
...ifDefined("options", indexOptions)
|
|
2222
|
+
});
|
|
2223
|
+
}
|
|
2079
2224
|
continue;
|
|
2080
2225
|
}
|
|
2081
2226
|
const uncomposedNamespace = checkUncomposedNamespace(modelAttribute.name, input.composedExtensions, {
|
|
@@ -2622,4 +2767,4 @@ function interpretPslDocumentToSqlContract(input) {
|
|
|
2622
2767
|
//#endregion
|
|
2623
2768
|
export { interpretPslDocumentToSqlContract as t };
|
|
2624
2769
|
|
|
2625
|
-
//# sourceMappingURL=interpreter-
|
|
2770
|
+
//# sourceMappingURL=interpreter-ijCjxhaU.mjs.map
|