@luckystack/devkit 0.9.1 → 0.10.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/CHANGELOG.md +16 -0
- package/CLAUDE.md +2 -0
- package/dist/index.js +8 -4
- package/dist/index.js.map +1 -1
- package/docs/type-map-generation.md +4 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.9.2] - 2026-09-01
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- A sync route without the optional `_client` handler is no longer reported as
|
|
15
|
+
degraded type extraction. `apiTypeDiagnostics.generated.json` matched on the
|
|
16
|
+
fallback TEXT alone, and an absent side produces the same `{ }` as a side that
|
|
17
|
+
is present but declares no shape — so every deliberately server-only sync
|
|
18
|
+
landed in `fallbackCount` as a `default-fallback`. In a real project that was
|
|
19
|
+
44 of 46 reported fallbacks, and the only way to silence them was to add the
|
|
20
|
+
no-op `_client` handlers `ARCHITECTURE_SYNC.md` tells you not to write (they
|
|
21
|
+
cost one execution per recipient). The generator now carries which sides were
|
|
22
|
+
actually found and suppresses only the missing side's own field. A thrown
|
|
23
|
+
extraction is still checked first and always reported, and a side that IS
|
|
24
|
+
present keeps falling back exactly as before.
|
|
25
|
+
|
|
10
26
|
## [0.8.7] - 2026-08-18
|
|
11
27
|
|
|
12
28
|
### Fixed
|
package/CLAUDE.md
CHANGED
|
@@ -101,6 +101,8 @@ Object literal types → `.strict()` (unknown keys rejected, fail-closed). This
|
|
|
101
101
|
|
|
102
102
|
Every `generateTypeMapFile()` run emits `apiTypeDiagnostics.generated.json` alongside `apiDocs.generated.json`. It lists every route whose type extraction degraded to a fallback (source file miss, thrown API/sync input/output/**stream** extraction, or `z.any()` in the Zod schema). Shape: `{ generatedAt, totalRoutes, fallbackCount, fallbacks: DiagnosticsEntry[] }`. CI can fail on non-zero `fallbackCount` to enforce type-fidelity. The file path is `<generatedApiDocs dir>/apiTypeDiagnostics.generated.json`.
|
|
103
103
|
|
|
104
|
+
One case is deliberately NOT a fallback: a sync side that does not exist on disk. `_client` is optional by contract (`/docs/ARCHITECTURE_SYNC.md` — a pass-through sync must not have one, because a no-op handler costs an execution per recipient), and an absent side yields the same `{ }` text as a present side that declares no shape. The generator therefore carries per-entry presence flags so the emitter can tell the two apart, and suppresses only the field belonging to the missing side. A THROWN extraction is still checked first and always reported, so this can never hide a real failure — do not widen the exception past the missing side's own field.
|
|
105
|
+
|
|
104
106
|
**D4 — transport-safe route contracts**
|
|
105
107
|
|
|
106
108
|
Output extraction projects `JSON.stringify` semantics recursively: `Date` becomes `string`; `toJSON()` becomes its return type; omitted object values (`undefined`, symbol, every callable value) disappear or make a union-valued property optional; those values become `null` in arrays/tuples. Binary values are rejected because HTTP JSON and Socket.io binary delivery cannot share one truthful output type. Input extraction does not project declarations, but rejects `Date`: JSON can only deliver an ISO string, so route authors must declare `string`, validate it, and convert explicitly before using Date methods.
|
package/dist/index.js
CHANGED
|
@@ -1030,14 +1030,16 @@ var validateGeneratedTypeIdentifiers = (content) => {
|
|
|
1030
1030
|
};
|
|
1031
1031
|
var collectFallbacks = (typesByPage, syncTypesByPage) => {
|
|
1032
1032
|
const entries = [];
|
|
1033
|
-
const flagField = (route, kind, field, value, checkZod = false) => {
|
|
1033
|
+
const flagField = (route, kind, field, value, checkZod = false, intentionalDefault = false) => {
|
|
1034
1034
|
const extractionError = findExtractionFailure(route, kind, field);
|
|
1035
1035
|
if (extractionError !== void 0) {
|
|
1036
1036
|
entries.push({ route, kind, field, fallback: value, reason: "extraction-error", detail: extractionError });
|
|
1037
1037
|
return;
|
|
1038
1038
|
}
|
|
1039
1039
|
if (value === "{ }" || value === "{ status: string }") {
|
|
1040
|
-
|
|
1040
|
+
if (!intentionalDefault) {
|
|
1041
|
+
entries.push({ route, kind, field, fallback: value, reason: "default-fallback" });
|
|
1042
|
+
}
|
|
1041
1043
|
return;
|
|
1042
1044
|
}
|
|
1043
1045
|
const zodSrc = checkZod ? typeTextToZodSource(value) : null;
|
|
@@ -1059,8 +1061,8 @@ var collectFallbacks = (typesByPage, syncTypesByPage) => {
|
|
|
1059
1061
|
const { name, version } = splitVersionedKey(syncKey);
|
|
1060
1062
|
const route = `${pagePath}/${name}@${version}`;
|
|
1061
1063
|
flagField(route, "sync", "clientInput", entry.clientInput);
|
|
1062
|
-
flagField(route, "sync", "serverOutput", entry.serverOutput);
|
|
1063
|
-
flagField(route, "sync", "clientOutput", entry.clientOutput);
|
|
1064
|
+
flagField(route, "sync", "serverOutput", entry.serverOutput, false, !entry.hasServer);
|
|
1065
|
+
flagField(route, "sync", "clientOutput", entry.clientOutput, false, !entry.hasClient);
|
|
1064
1066
|
flagField(route, "sync", "serverStream", entry.serverStream);
|
|
1065
1067
|
flagField(route, "sync", "clientStream", entry.clientStream);
|
|
1066
1068
|
}
|
|
@@ -2967,6 +2969,8 @@ var collectSyncTypes = (syncServerFiles, syncClientFiles, collectors) => {
|
|
|
2967
2969
|
serverStream: serverStreamType,
|
|
2968
2970
|
clientStream: clientStreamType,
|
|
2969
2971
|
version: syncVersion,
|
|
2972
|
+
hasServer: serverFile !== void 0,
|
|
2973
|
+
hasClient: clientFile !== void 0,
|
|
2970
2974
|
...syncMeta ? { meta: syncMeta } : {}
|
|
2971
2975
|
});
|
|
2972
2976
|
}
|