@rayspec/spec 1.5.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 +105 -0
- package/dist/brace-params.d.ts +32 -0
- package/dist/brace-params.d.ts.map +1 -0
- package/dist/brace-params.js +89 -0
- package/dist/brace-params.js.map +1 -0
- package/dist/detect.d.ts +44 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/detect.js +72 -0
- package/dist/detect.js.map +1 -0
- package/dist/errors.d.ts +204 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +165 -0
- package/dist/errors.js.map +1 -0
- package/dist/export.d.ts +54 -0
- package/dist/export.d.ts.map +1 -0
- package/dist/export.js +121 -0
- package/dist/export.js.map +1 -0
- package/dist/grammar.d.ts +569 -0
- package/dist/grammar.d.ts.map +1 -0
- package/dist/grammar.js +503 -0
- package/dist/grammar.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/lint.d.ts +79 -0
- package/dist/lint.d.ts.map +1 -0
- package/dist/lint.js +823 -0
- package/dist/lint.js.map +1 -0
- package/dist/parse.d.ts +8 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +118 -0
- package/dist/parse.js.map +1 -0
- package/dist/product-events.d.ts +73 -0
- package/dist/product-events.d.ts.map +1 -0
- package/dist/product-events.js +42 -0
- package/dist/product-events.js.map +1 -0
- package/dist/product-grammar.d.ts +948 -0
- package/dist/product-grammar.d.ts.map +1 -0
- package/dist/product-grammar.js +581 -0
- package/dist/product-grammar.js.map +1 -0
- package/dist/product-lint.d.ts +74 -0
- package/dist/product-lint.d.ts.map +1 -0
- package/dist/product-lint.js +821 -0
- package/dist/product-lint.js.map +1 -0
- package/dist/product-parse.d.ts +8 -0
- package/dist/product-parse.d.ts.map +1 -0
- package/dist/product-parse.js +119 -0
- package/dist/product-parse.js.map +1 -0
- package/dist/product-scope.d.ts +53 -0
- package/dist/product-scope.d.ts.map +1 -0
- package/dist/product-scope.js +55 -0
- package/dist/product-scope.js.map +1 -0
- package/dist/product-views-lint.d.ts +14 -0
- package/dist/product-views-lint.d.ts.map +1 -0
- package/dist/product-views-lint.js +669 -0
- package/dist/product-views-lint.js.map +1 -0
- package/dist/product-views.d.ts +426 -0
- package/dist/product-views.d.ts.map +1 -0
- package/dist/product-views.js +317 -0
- package/dist/product-views.js.map +1 -0
- package/package.json +34 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Functional Source License, Version 1.1, ALv2 Future License
|
|
2
|
+
|
|
3
|
+
## Abbreviation
|
|
4
|
+
|
|
5
|
+
FSL-1.1-ALv2
|
|
6
|
+
|
|
7
|
+
## Notice
|
|
8
|
+
|
|
9
|
+
Copyright 2026 Socialinsiders UG (haftungsbeschränkt)
|
|
10
|
+
|
|
11
|
+
## Terms and Conditions
|
|
12
|
+
|
|
13
|
+
### Licensor ("We")
|
|
14
|
+
|
|
15
|
+
The party offering the Software under these Terms and Conditions.
|
|
16
|
+
|
|
17
|
+
### The Software
|
|
18
|
+
|
|
19
|
+
The "Software" is each version of the software that we make available under
|
|
20
|
+
these Terms and Conditions, as indicated by our inclusion of these Terms and
|
|
21
|
+
Conditions with the Software.
|
|
22
|
+
|
|
23
|
+
### License Grant
|
|
24
|
+
|
|
25
|
+
Subject to your compliance with this License Grant and the Patents,
|
|
26
|
+
Redistribution and Trademark clauses below, we hereby grant you the right to
|
|
27
|
+
use, copy, modify, create derivative works, publicly perform, publicly display
|
|
28
|
+
and redistribute the Software for any Permitted Purpose identified below.
|
|
29
|
+
|
|
30
|
+
### Permitted Purpose
|
|
31
|
+
|
|
32
|
+
A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
|
|
33
|
+
means making the Software available to others in a commercial product or
|
|
34
|
+
service that:
|
|
35
|
+
|
|
36
|
+
1. substitutes for the Software;
|
|
37
|
+
|
|
38
|
+
2. substitutes for any other product or service we offer using the Software
|
|
39
|
+
that exists as of the date we make the Software available; or
|
|
40
|
+
|
|
41
|
+
3. offers the same or substantially similar functionality as the Software.
|
|
42
|
+
|
|
43
|
+
Permitted Purposes specifically include using the Software:
|
|
44
|
+
|
|
45
|
+
1. for your internal use and access;
|
|
46
|
+
|
|
47
|
+
2. for non-commercial education;
|
|
48
|
+
|
|
49
|
+
3. for non-commercial research; and
|
|
50
|
+
|
|
51
|
+
4. in connection with professional services that you provide to a licensee
|
|
52
|
+
using the Software in accordance with these Terms and Conditions.
|
|
53
|
+
|
|
54
|
+
### Patents
|
|
55
|
+
|
|
56
|
+
To the extent your use for a Permitted Purpose would necessarily infringe our
|
|
57
|
+
patents, the license grant above includes a license under our patents. If you
|
|
58
|
+
make a claim against any party that the Software infringes or contributes to
|
|
59
|
+
the infringement of any patent, then your patent license to the Software ends
|
|
60
|
+
immediately.
|
|
61
|
+
|
|
62
|
+
### Redistribution
|
|
63
|
+
|
|
64
|
+
The Terms and Conditions apply to all copies, modifications and derivatives of
|
|
65
|
+
the Software.
|
|
66
|
+
|
|
67
|
+
If you redistribute any copies, modifications or derivatives of the Software,
|
|
68
|
+
you must include a copy of or a link to these Terms and Conditions and not
|
|
69
|
+
remove any copyright notices provided in or with the Software.
|
|
70
|
+
|
|
71
|
+
### Disclaimer
|
|
72
|
+
|
|
73
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
|
|
74
|
+
IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
|
|
75
|
+
PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
|
|
76
|
+
|
|
77
|
+
IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
|
|
78
|
+
SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
|
|
79
|
+
EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
|
|
80
|
+
|
|
81
|
+
### Trademarks
|
|
82
|
+
|
|
83
|
+
Except for displaying the License Details and identifying us as the origin of
|
|
84
|
+
the Software, you have no right under these Terms and Conditions to use our
|
|
85
|
+
trademarks, trade names, service marks or product names.
|
|
86
|
+
|
|
87
|
+
## Grant of Future License
|
|
88
|
+
|
|
89
|
+
We hereby irrevocably grant you an additional license to use the Software under
|
|
90
|
+
the Apache License, Version 2.0 that is effective on the second anniversary of
|
|
91
|
+
the date we make the Software available. On or after that date, you may use the
|
|
92
|
+
Software under the Apache License, Version 2.0, in which case the following
|
|
93
|
+
will apply:
|
|
94
|
+
|
|
95
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
96
|
+
this file except in compliance with the License.
|
|
97
|
+
|
|
98
|
+
You may obtain a copy of the License at
|
|
99
|
+
|
|
100
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
101
|
+
|
|
102
|
+
Unless required by applicable law or agreed to in writing, software distributed
|
|
103
|
+
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
104
|
+
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
105
|
+
specific language governing permissions and limitations under the License.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `{param}` extraction/rewriting for declared route paths — a single forward character scan, with NO
|
|
3
|
+
* regular expression, so the work is strictly linear in the input length for EVERY input (no
|
|
4
|
+
* backtracking, no quantifier, and no length cap on the param name).
|
|
5
|
+
*
|
|
6
|
+
* The two helpers are the shared, byte-exact equivalent of iterating the pattern `\{([^}/]+)\}`
|
|
7
|
+
* globally over a path — the form the route/view emitters and the Hono-path rewrite historically used.
|
|
8
|
+
* They preserve that pattern's EXACT semantics for every input, including its edges:
|
|
9
|
+
* - `{}` → NOT a param (the run needs at least one character);
|
|
10
|
+
* - `{a/b}` → NOT a param (a `/` ends the run before a `}` can close it);
|
|
11
|
+
* - `{a}{b}` → two params (`a`, `b`);
|
|
12
|
+
* - `{a{b}` → one param whose name is `a{b` (an inner `{` is an ordinary name character);
|
|
13
|
+
* - `{unclosed` → no param (no closing `}`);
|
|
14
|
+
* - names of ANY length (1, 128, 129, thousands) and ANY code points (ASCII, emoji, astral).
|
|
15
|
+
*
|
|
16
|
+
* A `{param}` here is `{`, then a maximal run of ≥1 characters that are neither `}` nor `/`, then a
|
|
17
|
+
* `}`. Because the run stops at the first `}` or `/`, a match exists at a `{` iff that first stopping
|
|
18
|
+
* character is a `}` (a `/` or end-of-input means no match at this `{`); on a non-match the scan
|
|
19
|
+
* advances by a single character, exactly as a global regex retries at the next position.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Extract the `{param}` names from a declared route path in order (e.g. `/meetings/{id}/x` → `['id']`).
|
|
23
|
+
* Byte-exact equivalent of collecting capture group 1 of a global `\{([^}/]+)\}` scan.
|
|
24
|
+
*/
|
|
25
|
+
export declare function braceParamNames(path: string): string[];
|
|
26
|
+
/**
|
|
27
|
+
* Rewrite each `{param}` in a declared route path via `replace(name)`, copying every other character
|
|
28
|
+
* verbatim (e.g. `toHonoPath` uses `(name) => ':' + name`; the operationId slug uses
|
|
29
|
+
* `(name) => '_by_' + name + '_'`). Byte-exact equivalent of `path.replace(/\{([^}/]+)\}/g, cb)`.
|
|
30
|
+
*/
|
|
31
|
+
export declare function rewriteBraceParams(path: string, replace: (name: string) => string): string;
|
|
32
|
+
//# sourceMappingURL=brace-params.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brace-params.d.ts","sourceRoot":"","sources":["../src/brace-params.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAmBH;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAiBtD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAqB1F"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `{param}` extraction/rewriting for declared route paths — a single forward character scan, with NO
|
|
3
|
+
* regular expression, so the work is strictly linear in the input length for EVERY input (no
|
|
4
|
+
* backtracking, no quantifier, and no length cap on the param name).
|
|
5
|
+
*
|
|
6
|
+
* The two helpers are the shared, byte-exact equivalent of iterating the pattern `\{([^}/]+)\}`
|
|
7
|
+
* globally over a path — the form the route/view emitters and the Hono-path rewrite historically used.
|
|
8
|
+
* They preserve that pattern's EXACT semantics for every input, including its edges:
|
|
9
|
+
* - `{}` → NOT a param (the run needs at least one character);
|
|
10
|
+
* - `{a/b}` → NOT a param (a `/` ends the run before a `}` can close it);
|
|
11
|
+
* - `{a}{b}` → two params (`a`, `b`);
|
|
12
|
+
* - `{a{b}` → one param whose name is `a{b` (an inner `{` is an ordinary name character);
|
|
13
|
+
* - `{unclosed` → no param (no closing `}`);
|
|
14
|
+
* - names of ANY length (1, 128, 129, thousands) and ANY code points (ASCII, emoji, astral).
|
|
15
|
+
*
|
|
16
|
+
* A `{param}` here is `{`, then a maximal run of ≥1 characters that are neither `}` nor `/`, then a
|
|
17
|
+
* `}`. Because the run stops at the first `}` or `/`, a match exists at a `{` iff that first stopping
|
|
18
|
+
* character is a `}` (a `/` or end-of-input means no match at this `{`); on a non-match the scan
|
|
19
|
+
* advances by a single character, exactly as a global regex retries at the next position.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Locate the `{param}` span starting at `open` (where `path[open] === '{'`). Returns the closing-brace
|
|
23
|
+
* index and the param name when a valid `{name}` (name length ≥ 1, first stopping char is `}`) begins
|
|
24
|
+
* there, or `undefined` when this `{` does not open a param. Shared by both public helpers so the
|
|
25
|
+
* extract and rewrite paths can never drift.
|
|
26
|
+
*/
|
|
27
|
+
function braceSpanAt(path, open) {
|
|
28
|
+
// Walk to the first `}` or `/` after the `{` (or the end of the string).
|
|
29
|
+
let j = open + 1;
|
|
30
|
+
while (j < path.length && path[j] !== '}' && path[j] !== '/')
|
|
31
|
+
j++;
|
|
32
|
+
// A param exists iff that stopping char is a `}` AND at least one name char preceded it.
|
|
33
|
+
if (j < path.length && path[j] === '}' && j > open + 1) {
|
|
34
|
+
return { close: j, name: path.slice(open + 1, j) };
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Extract the `{param}` names from a declared route path in order (e.g. `/meetings/{id}/x` → `['id']`).
|
|
40
|
+
* Byte-exact equivalent of collecting capture group 1 of a global `\{([^}/]+)\}` scan.
|
|
41
|
+
*/
|
|
42
|
+
export function braceParamNames(path) {
|
|
43
|
+
const out = [];
|
|
44
|
+
let i = 0;
|
|
45
|
+
while (i < path.length) {
|
|
46
|
+
if (path[i] !== '{') {
|
|
47
|
+
i++;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
const span = braceSpanAt(path, i);
|
|
51
|
+
if (span) {
|
|
52
|
+
out.push(span.name);
|
|
53
|
+
i = span.close + 1; // continue after the closing `}`
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
i++; // not a param — advance one char and retry (a global regex does the same)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Rewrite each `{param}` in a declared route path via `replace(name)`, copying every other character
|
|
63
|
+
* verbatim (e.g. `toHonoPath` uses `(name) => ':' + name`; the operationId slug uses
|
|
64
|
+
* `(name) => '_by_' + name + '_'`). Byte-exact equivalent of `path.replace(/\{([^}/]+)\}/g, cb)`.
|
|
65
|
+
*/
|
|
66
|
+
export function rewriteBraceParams(path, replace) {
|
|
67
|
+
let out = '';
|
|
68
|
+
let last = 0; // start of the not-yet-copied verbatim region
|
|
69
|
+
let i = 0;
|
|
70
|
+
while (i < path.length) {
|
|
71
|
+
if (path[i] !== '{') {
|
|
72
|
+
i++;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const span = braceSpanAt(path, i);
|
|
76
|
+
if (span) {
|
|
77
|
+
out += path.slice(last, i); // verbatim text before this `{param}`
|
|
78
|
+
out += replace(span.name);
|
|
79
|
+
i = span.close + 1;
|
|
80
|
+
last = i;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
i++;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
out += path.slice(last); // trailing verbatim text
|
|
87
|
+
return out;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=brace-params.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brace-params.js","sourceRoot":"","sources":["../src/brace-params.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH;;;;;GAKG;AACH,SAAS,WAAW,CAAC,IAAY,EAAE,IAAY;IAC7C,yEAAyE;IACzE,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;IACjB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,CAAC,EAAE,CAAC;IAClE,yFAAyF;IACzF,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC;QACvD,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IACrD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACpB,CAAC,EAAE,CAAC;YACJ,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAClC,IAAI,IAAI,EAAE,CAAC;YACT,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpB,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,iCAAiC;QACvD,CAAC;aAAM,CAAC;YACN,CAAC,EAAE,CAAC,CAAC,0EAA0E;QACjF,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,OAAiC;IAChF,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,8CAA8C;IAC5D,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACpB,CAAC,EAAE,CAAC;YACJ,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAClC,IAAI,IAAI,EAAE,CAAC;YACT,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,sCAAsC;YAClE,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;YACnB,IAAI,GAAG,CAAC,CAAC;QACX,CAAC;aAAM,CAAC;YACN,CAAC,EAAE,CAAC;QACN,CAAC;IACH,CAAC;IACD,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,yBAAyB;IAClD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/dist/detect.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { SpecError } from './errors.js';
|
|
2
|
+
import { type RaySpec } from './grammar.js';
|
|
3
|
+
import type { ProductSpec } from './product-grammar.js';
|
|
4
|
+
/** Which document PROFILE a raw YAML string is. `unknown` = not parseable to an object root. */
|
|
5
|
+
export type SpecKind = 'rayspec' | 'product' | 'unknown';
|
|
6
|
+
/**
|
|
7
|
+
* Detect the document profile. A `version:'1.0'` doc is the PRODUCT profile iff it carries a top-level
|
|
8
|
+
* `product:` section, else the BACKEND profile. Any other object root (a version-less doc, or one with
|
|
9
|
+
* an unsupported version) → the backend parser, which fails closed there with a clean
|
|
10
|
+
* `unsupported_version`. Fail-closed: a non-object / unparseable root → `unknown`.
|
|
11
|
+
*/
|
|
12
|
+
export declare function detectSpecKind(rawYamlText: string): SpecKind;
|
|
13
|
+
/** A validate-only envelope for callers (doctor/plan/deploy) that only need the fail-closed verdict. */
|
|
14
|
+
export interface ValidateResult {
|
|
15
|
+
readonly ok: boolean;
|
|
16
|
+
readonly kind: SpecKind;
|
|
17
|
+
readonly errors: SpecError[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Validate a raw spec of EITHER family, collapsing to `{ ok, kind, errors }`. Routes to the correct
|
|
21
|
+
* parser by `detectSpecKind`. An `unknown` root is routed to `parseSpec` so its existing
|
|
22
|
+
* `unsupported_version`/`yaml_parse_error` message is preserved (no behavior change for RaySpec).
|
|
23
|
+
*/
|
|
24
|
+
export declare function validateAnySpec(rawYamlText: string): ValidateResult;
|
|
25
|
+
/**
|
|
26
|
+
* A discriminated parse result carrying the typed value of whichever family the doc is. Callers that
|
|
27
|
+
* need the parsed value (not just the verdict) use this. `unknown`/`rayspec` roots parse as RaySpec.
|
|
28
|
+
*/
|
|
29
|
+
export type AnySpecParse = {
|
|
30
|
+
readonly ok: true;
|
|
31
|
+
readonly kind: 'rayspec';
|
|
32
|
+
readonly spec: RaySpec;
|
|
33
|
+
} | {
|
|
34
|
+
readonly ok: true;
|
|
35
|
+
readonly kind: 'product';
|
|
36
|
+
readonly spec: ProductSpec;
|
|
37
|
+
} | {
|
|
38
|
+
readonly ok: false;
|
|
39
|
+
readonly kind: SpecKind;
|
|
40
|
+
readonly errors: SpecError[];
|
|
41
|
+
};
|
|
42
|
+
/** Parse a raw spec of either family, returning the typed value on success. */
|
|
43
|
+
export declare function parseAnySpec(rawYamlText: string): AnySpecParse;
|
|
44
|
+
//# sourceMappingURL=detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAU,SAAS,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,KAAK,OAAO,EAAgB,MAAM,cAAc,CAAC;AAE1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGxD,gGAAgG;AAChG,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAEzD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,QAAQ,CAY5D;AAED,wGAAwG;AACxG,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC;CAC9B;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,CAUnE;AAED;;;GAGG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GACvE;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GAC3E;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,CAAA;CAAE,CAAC;AAElF,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,CAY9D"}
|
package/dist/detect.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Document-kind detection + a unified validator.
|
|
3
|
+
*
|
|
4
|
+
* RaySpec is ONE declarative language — `version: '1.0'` — with two PROFILES, told apart by the
|
|
5
|
+
* presence of the `product:` archetype discriminant:
|
|
6
|
+
* • RaySpec (backend profile) — a `version:'1.0'` doc with NO `product:` section (grammar.ts /
|
|
7
|
+
* parse.ts) — the low-level surface AND the internal engine target.
|
|
8
|
+
* • Product-YAML (product profile) — a `version:'1.0'` doc that carries the required `product:`
|
|
9
|
+
* section (product-grammar.ts / product-parse.ts) — the
|
|
10
|
+
* high-level product-meaning surface that lowers to the backend.
|
|
11
|
+
*
|
|
12
|
+
* `detectSpecKind` keys on `version:'1.0'` + `product:` presence: a doc that carries a top-level
|
|
13
|
+
* `product:` section is the product profile, else the backend profile. A YAML parse/shape failure is
|
|
14
|
+
* reported as `unknown` so the caller can surface a clean error.
|
|
15
|
+
*/
|
|
16
|
+
import { parse as parseYaml } from 'yaml';
|
|
17
|
+
import { SPEC_VERSION } from './grammar.js';
|
|
18
|
+
import { parseSpec } from './parse.js';
|
|
19
|
+
import { parseProductSpec } from './product-parse.js';
|
|
20
|
+
/**
|
|
21
|
+
* Detect the document profile. A `version:'1.0'` doc is the PRODUCT profile iff it carries a top-level
|
|
22
|
+
* `product:` section, else the BACKEND profile. Any other object root (a version-less doc, or one with
|
|
23
|
+
* an unsupported version) → the backend parser, which fails closed there with a clean
|
|
24
|
+
* `unsupported_version`. Fail-closed: a non-object / unparseable root → `unknown`.
|
|
25
|
+
*/
|
|
26
|
+
export function detectSpecKind(rawYamlText) {
|
|
27
|
+
let loaded;
|
|
28
|
+
try {
|
|
29
|
+
loaded = parseYaml(rawYamlText);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return 'unknown';
|
|
33
|
+
}
|
|
34
|
+
if (loaded === null || typeof loaded !== 'object' || Array.isArray(loaded))
|
|
35
|
+
return 'unknown';
|
|
36
|
+
const doc = loaded;
|
|
37
|
+
// version:'1.0' + the `product:` discriminant selects the product profile; everything else is backend.
|
|
38
|
+
if (doc.version === SPEC_VERSION && 'product' in doc)
|
|
39
|
+
return 'product';
|
|
40
|
+
return 'rayspec';
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Validate a raw spec of EITHER family, collapsing to `{ ok, kind, errors }`. Routes to the correct
|
|
44
|
+
* parser by `detectSpecKind`. An `unknown` root is routed to `parseSpec` so its existing
|
|
45
|
+
* `unsupported_version`/`yaml_parse_error` message is preserved (no behavior change for RaySpec).
|
|
46
|
+
*/
|
|
47
|
+
export function validateAnySpec(rawYamlText) {
|
|
48
|
+
const kind = detectSpecKind(rawYamlText);
|
|
49
|
+
if (kind === 'product') {
|
|
50
|
+
const res = parseProductSpec(rawYamlText);
|
|
51
|
+
return res.ok ? { ok: true, kind, errors: [] } : { ok: false, kind, errors: res.errors };
|
|
52
|
+
}
|
|
53
|
+
const res = parseSpec(rawYamlText);
|
|
54
|
+
return res.ok
|
|
55
|
+
? { ok: true, kind: 'rayspec', errors: [] }
|
|
56
|
+
: { ok: false, kind: 'rayspec', errors: res.errors };
|
|
57
|
+
}
|
|
58
|
+
/** Parse a raw spec of either family, returning the typed value on success. */
|
|
59
|
+
export function parseAnySpec(rawYamlText) {
|
|
60
|
+
const kind = detectSpecKind(rawYamlText);
|
|
61
|
+
if (kind === 'product') {
|
|
62
|
+
const res = parseProductSpec(rawYamlText);
|
|
63
|
+
return res.ok
|
|
64
|
+
? { ok: true, kind: 'product', spec: res.value }
|
|
65
|
+
: { ok: false, kind: 'product', errors: res.errors };
|
|
66
|
+
}
|
|
67
|
+
const res = parseSpec(rawYamlText);
|
|
68
|
+
return res.ok
|
|
69
|
+
? { ok: true, kind: 'rayspec', spec: res.value }
|
|
70
|
+
: { ok: false, kind: 'rayspec', errors: res.errors };
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,EAAgB,YAAY,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAKtD;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,WAAmB;IAChD,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAC;IAC7F,MAAM,GAAG,GAAG,MAAiC,CAAC;IAC9C,uGAAuG;IACvG,IAAI,GAAG,CAAC,OAAO,KAAK,YAAY,IAAI,SAAS,IAAI,GAAG;QAAE,OAAO,SAAS,CAAC;IACvE,OAAO,SAAS,CAAC;AACnB,CAAC;AASD;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,WAAmB;IACjD,MAAM,IAAI,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IACzC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;QAC1C,OAAO,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;IAC3F,CAAC;IACD,MAAM,GAAG,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;IACnC,OAAO,GAAG,CAAC,EAAE;QACX,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE;QAC3C,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;AACzD,CAAC;AAWD,+EAA+E;AAC/E,MAAM,UAAU,YAAY,CAAC,WAAmB;IAC9C,MAAM,IAAI,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IACzC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,GAAG,GAAmC,gBAAgB,CAAC,WAAW,CAAC,CAAC;QAC1E,OAAO,GAAG,CAAC,EAAE;YACX,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,CAAC,KAAK,EAAE;YAChD,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;IACzD,CAAC;IACD,MAAM,GAAG,GAA+B,SAAS,CAAC,WAAW,CAAC,CAAC;IAC/D,OAAO,GAAG,CAAC,EAAE;QACX,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,CAAC,KAAK,EAAE;QAChD,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;AACzD,CAAC"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SpecError — the closed-code error envelope for the RaySpec config grammar.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the auth-core `ErrorCode`/`ErrorEnvelope` pattern (packages/auth-core/src/errors.ts):
|
|
5
|
+
* a CLOSED Zod enum of codes + a flat `{ code, message, path? }` envelope. Closed-by-construction
|
|
6
|
+
* so a fresh session reading a parse failure sees a finite, documented vocabulary — never a free
|
|
7
|
+
* string. `parseSpec`/`lintSpec` aggregate the FULL list of violations (not the first), so an
|
|
8
|
+
* author sees every problem in one pass.
|
|
9
|
+
*
|
|
10
|
+
* `path` is a JSON path into the spec (dot/bracket notation, e.g. `agents[0].backend`) so a
|
|
11
|
+
* violation points at the exact offending node. It is absent for whole-document failures
|
|
12
|
+
* (`yaml_parse_error`, `unsupported_version`) where no in-document path applies.
|
|
13
|
+
*/
|
|
14
|
+
import { z } from 'zod';
|
|
15
|
+
/**
|
|
16
|
+
* The CLOSED set of spec-error codes. Every parse/lint failure carries exactly one of these.
|
|
17
|
+
*
|
|
18
|
+
* - `yaml_parse_error` — the raw text is not valid YAML (the `yaml` lib threw).
|
|
19
|
+
* - `unsupported_version` — `version` is missing or not the supported literal ('1.0').
|
|
20
|
+
* - `schema_violation` — a Zod shape failure that is not a pure unknown-key rejection
|
|
21
|
+
* (wrong type, missing required field, bad enum value, …).
|
|
22
|
+
* - `unknown_field` — a `.strict()` unknown-key rejection (fail-closed: any extra key).
|
|
23
|
+
* - `dangling_ref` — a cross-reference points at an id/name that is not declared.
|
|
24
|
+
* - `duplicate_name` — two entries in one section share an id/name.
|
|
25
|
+
* - `capability_violation` — an agent demands a capability its chosen backend lacks
|
|
26
|
+
* (via core `validateSpec`; e.g. native structured output on pi).
|
|
27
|
+
* - `invalid_embedded_schema`— an embedded JSON-Schema (tool `parameters`/`outputSchema`,
|
|
28
|
+
* agent `outputSchema.schema`) failed to compile through Ajv2020.
|
|
29
|
+
* - `reserved_column_name` — a store declares a business column whose name collides with a
|
|
30
|
+
* tenancy/GDPR column the table generator injects (`id`,
|
|
31
|
+
* `tenant_id`, `created_at`, `deleted_at`, `retention_days`,
|
|
32
|
+
* `region`) — fail-closed against a shadow/tenancy collision.
|
|
33
|
+
* - `reserved_query_keyword` — a store declares a business column whose name is one of the
|
|
34
|
+
* list-query CONTROL keywords (`order`, `after`, `limit`). Those keys
|
|
35
|
+
* steer the declarative `list` route's sorting + keyset pagination, so a
|
|
36
|
+
* column of that name would be silently un-equality-filterable AND would
|
|
37
|
+
* emit a DUPLICATE OpenAPI query parameter (control param + per-column
|
|
38
|
+
* filter param, same name+location) → an invalid OpenAPI 3.1 document.
|
|
39
|
+
* Rename the business column.
|
|
40
|
+
* - `frontend_route_collision` — a declared static frontend mount's `route` collides with another
|
|
41
|
+
* mount, with a declared `api[].path`, or with a reserved system prefix
|
|
42
|
+
* (`/v1`, `/health`, `/oidc`) — the static mount would either shadow or be
|
|
43
|
+
* shadowed by that route. Root `/` is exempt (it coexists with `/v1/*` via
|
|
44
|
+
* registration order). Rename the frontend route.
|
|
45
|
+
* - `frontend_dir_missing` — a declared frontend `dir` does not resolve to a readable directory of
|
|
46
|
+
* built assets (surfaced by `doctor`, which checks the filesystem).
|
|
47
|
+
* - `fk_cycle` — the declared stores form a CIRCULAR foreign-key reference (store A
|
|
48
|
+
* references B and B references A, directly or transitively). Such a set is
|
|
49
|
+
* UNORDERABLE: each store's FK ADD needs its parent table to already exist,
|
|
50
|
+
* so no CREATE order satisfies every FK. Rejected fail-closed at config time
|
|
51
|
+
* rather than surfacing as a cryptic `42P01 relation does not exist` at
|
|
52
|
+
* apply. Self-references are EXEMPT (a self-FK applies after its own CREATE).
|
|
53
|
+
*
|
|
54
|
+
* PRODUCT-YAML codes — used ONLY by the Product-YAML validation path (`parseProductSpec`,
|
|
55
|
+
* `product-lint.ts`). They share this closed envelope so a fresh session sees ONE error vocabulary
|
|
56
|
+
* across both document families; the RaySpec path never emits them.
|
|
57
|
+
* - `no_code_in_yaml` — a code/handler/SQL/shell key or an inline-code string value appears
|
|
58
|
+
* in a Product-YAML doc: implementation belongs in Tier A/B, not
|
|
59
|
+
* in product meaning. The message names what the offending key should be.
|
|
60
|
+
* - `provider_native_leak` — a provider-native wire blob (raw request/response payload) or a
|
|
61
|
+
* provider/model policy field / provider name leaked into the executable
|
|
62
|
+
* `workflows`/`agents` graph (which must stay provider-neutral so it
|
|
63
|
+
* compiles through the workflow bridge). Provider policy is only allowed
|
|
64
|
+
* in `capabilities[].provider_policy` / `deployment_overrides`.
|
|
65
|
+
* - `invalid_capability_status` — RESERVED (closed-code discipline). The earlier doc-level
|
|
66
|
+
* rejection of `status:'available'` was retired (the Tier B
|
|
67
|
+
* runtime is wired now); capability WIREDNESS is enforced at the deploy
|
|
68
|
+
* composition (fail-closed `unsupported_spec`), not by the parser.
|
|
69
|
+
* - `invalid_contract` — a `contracts[]` schema uses a key/type outside the closed, declarative
|
|
70
|
+
* JSON-Schema-like vocabulary (no functions/transforms/computed
|
|
71
|
+
* expressions/provider-native shapes).
|
|
72
|
+
* - `prompt_execution_claim` — a Product-YAML `workflows`/`agents` graph STRING claims prompt/LLM
|
|
73
|
+
* EXECUTION (`llm call`, `agent call`, `prompt execution`, `execute
|
|
74
|
+
* prompt`). Mirrors the workflow-bridge's `prompt_execution_claim` so a
|
|
75
|
+
* doc that validates here also compiles through the bridge (anti-drift;
|
|
76
|
+
* parity-tested). Prompt/agent execution is a Tier-B runtime concern.
|
|
77
|
+
* - `production_execution_claim` — a graph STRING claims production EXECUTION (`production_ready`,
|
|
78
|
+
* `production execution`, `prod runtime`). Mirrors the bridge's
|
|
79
|
+
* `production_execution_claim` (parity-tested): a product doc declares
|
|
80
|
+
* meaning, not that it EXECUTES in production.
|
|
81
|
+
* - `invalid_dependency_order` — a workflow step's `depends_on` references a step that is NOT declared
|
|
82
|
+
* before it (a forward/self reference). Declaration-order is required, which
|
|
83
|
+
* structurally forbids dependency CYCLES (a cycle needs a forward edge).
|
|
84
|
+
* - `invalid_view` — a view declaration violates the view semantics (product-views-lint):
|
|
85
|
+
* a source/contract conflation (a source ref that names a
|
|
86
|
+
* contract instead of a store/artifact/capability contract), a read/shape
|
|
87
|
+
* context violation (page fields outside `list` mode, group outside `collect`,
|
|
88
|
+
* …), incomplete param coverage, a shape that does not conform to its declared
|
|
89
|
+
* response contract, a reserved (`__proto__`-class) name, or a pagination law
|
|
90
|
+
* violation. Every mis-declared view construct is rejected — never skipped.
|
|
91
|
+
* - `invalid_store` — a declared product store / store-step declaration violates the store
|
|
92
|
+
* semantics: a store name colliding with a
|
|
93
|
+
* derived collection store, a column name on the graph key denylist (it could
|
|
94
|
+
* never be referenced from a workflow step), a key naming an undeclared or
|
|
95
|
+
* nullable column, a store step targeting an undeclared store, a filter/values
|
|
96
|
+
* column outside the store's declared columns, a write omitting the conflict-
|
|
97
|
+
* key column, or store vocabulary on a non-store step type. Fail-closed.
|
|
98
|
+
*/
|
|
99
|
+
export declare const SpecErrorCode: z.ZodEnum<{
|
|
100
|
+
yaml_parse_error: "yaml_parse_error";
|
|
101
|
+
unsupported_version: "unsupported_version";
|
|
102
|
+
schema_violation: "schema_violation";
|
|
103
|
+
unknown_field: "unknown_field";
|
|
104
|
+
dangling_ref: "dangling_ref";
|
|
105
|
+
duplicate_name: "duplicate_name";
|
|
106
|
+
capability_violation: "capability_violation";
|
|
107
|
+
invalid_embedded_schema: "invalid_embedded_schema";
|
|
108
|
+
reserved_column_name: "reserved_column_name";
|
|
109
|
+
reserved_query_keyword: "reserved_query_keyword";
|
|
110
|
+
frontend_route_collision: "frontend_route_collision";
|
|
111
|
+
frontend_dir_missing: "frontend_dir_missing";
|
|
112
|
+
fk_cycle: "fk_cycle";
|
|
113
|
+
no_code_in_yaml: "no_code_in_yaml";
|
|
114
|
+
provider_native_leak: "provider_native_leak";
|
|
115
|
+
invalid_capability_status: "invalid_capability_status";
|
|
116
|
+
invalid_contract: "invalid_contract";
|
|
117
|
+
prompt_execution_claim: "prompt_execution_claim";
|
|
118
|
+
production_execution_claim: "production_execution_claim";
|
|
119
|
+
invalid_dependency_order: "invalid_dependency_order";
|
|
120
|
+
invalid_view: "invalid_view";
|
|
121
|
+
invalid_store: "invalid_store";
|
|
122
|
+
}>;
|
|
123
|
+
export type SpecErrorCode = z.infer<typeof SpecErrorCode>;
|
|
124
|
+
/** A single fail-closed spec violation (closed code + message + optional JSON path). */
|
|
125
|
+
export declare const SpecError: z.ZodObject<{
|
|
126
|
+
code: z.ZodEnum<{
|
|
127
|
+
yaml_parse_error: "yaml_parse_error";
|
|
128
|
+
unsupported_version: "unsupported_version";
|
|
129
|
+
schema_violation: "schema_violation";
|
|
130
|
+
unknown_field: "unknown_field";
|
|
131
|
+
dangling_ref: "dangling_ref";
|
|
132
|
+
duplicate_name: "duplicate_name";
|
|
133
|
+
capability_violation: "capability_violation";
|
|
134
|
+
invalid_embedded_schema: "invalid_embedded_schema";
|
|
135
|
+
reserved_column_name: "reserved_column_name";
|
|
136
|
+
reserved_query_keyword: "reserved_query_keyword";
|
|
137
|
+
frontend_route_collision: "frontend_route_collision";
|
|
138
|
+
frontend_dir_missing: "frontend_dir_missing";
|
|
139
|
+
fk_cycle: "fk_cycle";
|
|
140
|
+
no_code_in_yaml: "no_code_in_yaml";
|
|
141
|
+
provider_native_leak: "provider_native_leak";
|
|
142
|
+
invalid_capability_status: "invalid_capability_status";
|
|
143
|
+
invalid_contract: "invalid_contract";
|
|
144
|
+
prompt_execution_claim: "prompt_execution_claim";
|
|
145
|
+
production_execution_claim: "production_execution_claim";
|
|
146
|
+
invalid_dependency_order: "invalid_dependency_order";
|
|
147
|
+
invalid_view: "invalid_view";
|
|
148
|
+
invalid_store: "invalid_store";
|
|
149
|
+
}>;
|
|
150
|
+
message: z.ZodString;
|
|
151
|
+
path: z.ZodOptional<z.ZodString>;
|
|
152
|
+
}, z.core.$strip>;
|
|
153
|
+
export type SpecError = z.infer<typeof SpecError>;
|
|
154
|
+
/** Construct a SpecError (path omitted when undefined so the envelope stays minimal). */
|
|
155
|
+
export declare function specError(code: SpecErrorCode, message: string, path?: string): SpecError;
|
|
156
|
+
/**
|
|
157
|
+
* The CLOSED set of NON-FATAL spec-warning codes. A warning flags a documented, deliberately-permitted
|
|
158
|
+
* interaction the author should be AWARE of — it does NOT fail `doctor`/`plan` (unlike a `SpecError`).
|
|
159
|
+
* Kept a distinct closed vocabulary from `SpecErrorCode` so a fresh session never confuses "advisory"
|
|
160
|
+
* with "fail-closed".
|
|
161
|
+
*
|
|
162
|
+
* - `softdelete_fk_restrict` — a `softDelete` store is the TARGET of a `restrict` business-key
|
|
163
|
+
* (`referencesColumn`) foreign key. Soft-deleting such a parent is an
|
|
164
|
+
* `UPDATE(deleted_at)` that does NOT fire the database ON DELETE restrict,
|
|
165
|
+
* so children keep pointing at the tombstoned row — the restrict guarantee
|
|
166
|
+
* only binds on a HARD delete. This is a permitted, documented interaction.
|
|
167
|
+
* - `fk_forward_reference` — a store declares a foreign key onto another store declared LATER in the
|
|
168
|
+
* `stores` array. The product-SQL generator topo-sorts stores so the parent
|
|
169
|
+
* table is created before the child's FK is added, so a forward reference
|
|
170
|
+
* still applies cleanly; this advisory notes only that the declared order
|
|
171
|
+
* relies on that reordering (declaring the parent first makes it explicit).
|
|
172
|
+
* Acyclic by construction — a true cycle is the fail-closed `fk_cycle`
|
|
173
|
+
* error, never a warning.
|
|
174
|
+
*/
|
|
175
|
+
export declare const SpecWarningCode: z.ZodEnum<{
|
|
176
|
+
softdelete_fk_restrict: "softdelete_fk_restrict";
|
|
177
|
+
fk_forward_reference: "fk_forward_reference";
|
|
178
|
+
}>;
|
|
179
|
+
export type SpecWarningCode = z.infer<typeof SpecWarningCode>;
|
|
180
|
+
/** A single NON-FATAL spec warning (closed code + message + optional JSON path). Never fails a parse. */
|
|
181
|
+
export declare const SpecWarning: z.ZodObject<{
|
|
182
|
+
code: z.ZodEnum<{
|
|
183
|
+
softdelete_fk_restrict: "softdelete_fk_restrict";
|
|
184
|
+
fk_forward_reference: "fk_forward_reference";
|
|
185
|
+
}>;
|
|
186
|
+
message: z.ZodString;
|
|
187
|
+
path: z.ZodOptional<z.ZodString>;
|
|
188
|
+
}, z.core.$strip>;
|
|
189
|
+
export type SpecWarning = z.infer<typeof SpecWarning>;
|
|
190
|
+
/** Construct a SpecWarning (path omitted when undefined so the envelope stays minimal). */
|
|
191
|
+
export declare function specWarning(code: SpecWarningCode, message: string, path?: string): SpecWarning;
|
|
192
|
+
/**
|
|
193
|
+
* The result of `parseSpec` — a discriminated `Result` so a caller MUST check `ok` before
|
|
194
|
+
* touching `value` (the fail-closed contract: a spec with any violation yields `ok:false` and
|
|
195
|
+
* the full violation list, never a partially-trusted value).
|
|
196
|
+
*/
|
|
197
|
+
export type Result<T, E> = {
|
|
198
|
+
ok: true;
|
|
199
|
+
value: T;
|
|
200
|
+
} | {
|
|
201
|
+
ok: false;
|
|
202
|
+
errors: E[];
|
|
203
|
+
};
|
|
204
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmFG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;EAuBxB,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D,wFAAwF;AACxF,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAKpB,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AAElD,yFAAyF;AACzF,wBAAgB,SAAS,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAExF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,eAAe;;;EAA6D,CAAC;AAC1F,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,yGAAyG;AACzG,eAAO,MAAM,WAAW;;;;;;;iBAKtB,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD,2FAA2F;AAC3F,wBAAgB,WAAW,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CAE9F;AAED;;;;GAIG;AACH,MAAM,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,CAAC,EAAE,CAAA;CAAE,CAAC"}
|