@hodeinavarro/odoo-rpc-ts 0.2.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 +21 -0
- package/README.md +401 -0
- package/dist/client.d.ts +184 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +277 -0
- package/dist/client.js.map +1 -0
- package/dist/combinators/retryOnSessionExpired.d.ts +13 -0
- package/dist/combinators/retryOnSessionExpired.d.ts.map +1 -0
- package/dist/combinators/retryOnSessionExpired.js +15 -0
- package/dist/combinators/retryOnSessionExpired.js.map +1 -0
- package/dist/commands.d.ts +91 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +69 -0
- package/dist/commands.js.map +1 -0
- package/dist/config.d.ts +32 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +60 -0
- package/dist/config.js.map +1 -0
- package/dist/domain.d.ts +30 -0
- package/dist/domain.d.ts.map +1 -0
- package/dist/domain.js +70 -0
- package/dist/domain.js.map +1 -0
- package/dist/errors/auth.d.ts +27 -0
- package/dist/errors/auth.d.ts.map +1 -0
- package/dist/errors/auth.js +8 -0
- package/dist/errors/auth.js.map +1 -0
- package/dist/errors/index.d.ts +30 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +13 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/errors/mapFault.d.ts +31 -0
- package/dist/errors/mapFault.d.ts.map +1 -0
- package/dist/errors/mapFault.js +48 -0
- package/dist/errors/mapFault.js.map +1 -0
- package/dist/errors/protocol.d.ts +22 -0
- package/dist/errors/protocol.d.ts.map +1 -0
- package/dist/errors/protocol.js +9 -0
- package/dist/errors/protocol.js.map +1 -0
- package/dist/errors/schema.d.ts +22 -0
- package/dist/errors/schema.d.ts.map +1 -0
- package/dist/errors/schema.js +14 -0
- package/dist/errors/schema.js.map +1 -0
- package/dist/errors/server.d.ts +109 -0
- package/dist/errors/server.d.ts.map +1 -0
- package/dist/errors/server.js +49 -0
- package/dist/errors/server.js.map +1 -0
- package/dist/errors/session.d.ts +16 -0
- package/dist/errors/session.d.ts.map +1 -0
- package/dist/errors/session.js +11 -0
- package/dist/errors/session.js.map +1 -0
- package/dist/errors/transport.d.ts +42 -0
- package/dist/errors/transport.d.ts.map +1 -0
- package/dist/errors/transport.js +49 -0
- package/dist/errors/transport.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/platform.d.ts +12 -0
- package/dist/internal/platform.d.ts.map +1 -0
- package/dist/internal/platform.js +11 -0
- package/dist/internal/platform.js.map +1 -0
- package/dist/internal/singleFlight.d.ts +29 -0
- package/dist/internal/singleFlight.d.ts.map +1 -0
- package/dist/internal/singleFlight.js +41 -0
- package/dist/internal/singleFlight.js.map +1 -0
- package/dist/profiles.d.ts +179 -0
- package/dist/profiles.d.ts.map +1 -0
- package/dist/profiles.js +191 -0
- package/dist/profiles.js.map +1 -0
- package/dist/protocol/jsonrpc.d.ts +127 -0
- package/dist/protocol/jsonrpc.d.ts.map +1 -0
- package/dist/protocol/jsonrpc.js +117 -0
- package/dist/protocol/jsonrpc.js.map +1 -0
- package/dist/records/index.d.ts +14 -0
- package/dist/records/index.d.ts.map +1 -0
- package/dist/records/index.js +14 -0
- package/dist/records/index.js.map +1 -0
- package/dist/records/recordModel.d.ts +131 -0
- package/dist/records/recordModel.d.ts.map +1 -0
- package/dist/records/recordModel.js +101 -0
- package/dist/records/recordModel.js.map +1 -0
- package/dist/records/related.d.ts +42 -0
- package/dist/records/related.d.ts.map +1 -0
- package/dist/records/related.js +51 -0
- package/dist/records/related.js.map +1 -0
- package/dist/records/relations.d.ts +66 -0
- package/dist/records/relations.d.ts.map +1 -0
- package/dist/records/relations.js +119 -0
- package/dist/records/relations.js.map +1 -0
- package/dist/records/spec.d.ts +44 -0
- package/dist/records/spec.d.ts.map +1 -0
- package/dist/records/spec.js +63 -0
- package/dist/records/spec.js.map +1 -0
- package/dist/records/typed.d.ts +71 -0
- package/dist/records/typed.d.ts.map +1 -0
- package/dist/records/typed.js +65 -0
- package/dist/records/typed.js.map +1 -0
- package/dist/rpc.d.ts +90 -0
- package/dist/rpc.d.ts.map +1 -0
- package/dist/rpc.js +113 -0
- package/dist/rpc.js.map +1 -0
- package/dist/services/db.d.ts +128 -0
- package/dist/services/db.d.ts.map +1 -0
- package/dist/services/db.js +132 -0
- package/dist/services/db.js.map +1 -0
- package/dist/services/report.d.ts +48 -0
- package/dist/services/report.d.ts.map +1 -0
- package/dist/services/report.js +103 -0
- package/dist/services/report.js.map +1 -0
- package/dist/session/cookie.d.ts +114 -0
- package/dist/session/cookie.d.ts.map +1 -0
- package/dist/session/cookie.js +231 -0
- package/dist/session/cookie.js.map +1 -0
- package/dist/testing/fakeTransport.d.ts +40 -0
- package/dist/testing/fakeTransport.d.ts.map +1 -0
- package/dist/testing/fakeTransport.js +36 -0
- package/dist/testing/fakeTransport.js.map +1 -0
- package/dist/testing/index.d.ts +9 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +9 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/transport.d.ts +62 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +9 -0
- package/dist/transport.js.map +1 -0
- package/dist/transports/json2.d.ts +41 -0
- package/dist/transports/json2.d.ts.map +1 -0
- package/dist/transports/json2.js +196 -0
- package/dist/transports/json2.js.map +1 -0
- package/dist/transports/jsonrpc.d.ts +41 -0
- package/dist/transports/jsonrpc.d.ts.map +1 -0
- package/dist/transports/jsonrpc.js +119 -0
- package/dist/transports/jsonrpc.js.map +1 -0
- package/dist/transports/web.d.ts +15 -0
- package/dist/transports/web.d.ts.map +1 -0
- package/dist/transports/web.js +62 -0
- package/dist/transports/web.js.map +1 -0
- package/dist/version-live.d.ts +41 -0
- package/dist/version-live.d.ts.map +1 -0
- package/dist/version-live.js +26 -0
- package/dist/version-live.js.map +1 -0
- package/dist/version.d.ts +78 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +46 -0
- package/dist/version.js.map +1 -0
- package/docs/protocol-verification.md +43 -0
- package/package.json +71 -0
- package/src/client.ts +731 -0
- package/src/combinators/retryOnSessionExpired.ts +25 -0
- package/src/commands.ts +112 -0
- package/src/config.ts +110 -0
- package/src/domain.ts +91 -0
- package/src/errors/auth.ts +28 -0
- package/src/errors/index.ts +50 -0
- package/src/errors/mapFault.ts +92 -0
- package/src/errors/protocol.ts +19 -0
- package/src/errors/schema.ts +18 -0
- package/src/errors/server.ts +79 -0
- package/src/errors/session.ts +12 -0
- package/src/errors/transport.ts +74 -0
- package/src/index.ts +152 -0
- package/src/internal/platform.ts +22 -0
- package/src/internal/singleFlight.ts +80 -0
- package/src/profiles.ts +386 -0
- package/src/protocol/jsonrpc.ts +162 -0
- package/src/records/index.ts +49 -0
- package/src/records/recordModel.ts +211 -0
- package/src/records/related.ts +80 -0
- package/src/records/relations.ts +192 -0
- package/src/records/spec.ts +96 -0
- package/src/records/typed.ts +180 -0
- package/src/rpc.ts +219 -0
- package/src/services/db.ts +282 -0
- package/src/services/report.ts +165 -0
- package/src/session/cookie.ts +461 -0
- package/src/testing/fakeTransport.ts +84 -0
- package/src/testing/index.ts +9 -0
- package/src/transport.ts +72 -0
- package/src/transports/json2.ts +303 -0
- package/src/transports/jsonrpc.ts +218 -0
- package/src/transports/web.ts +96 -0
- package/src/version-live.ts +67 -0
- package/src/version.ts +102 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Effect, Layer } from "effect";
|
|
2
|
+
import type { SchemaDriftError } from "./errors/schema.js";
|
|
3
|
+
import type { ProtocolUnsupportedError } from "./errors/protocol.js";
|
|
4
|
+
import type { OdooTransportError } from "./errors/transport.js";
|
|
5
|
+
import { type CommonVersionResponse, type ServerVersionInfo, VersionResolver } from "./version.js";
|
|
6
|
+
/**
|
|
7
|
+
* The two version-probe shapes we accept, already boundary-decoded by whichever
|
|
8
|
+
* transport family issued the probe:
|
|
9
|
+
*
|
|
10
|
+
* - {@link CommonVersionResponse} — the `/jsonrpc` `common.version` response.
|
|
11
|
+
* - `{ version, version_info }` — the web `/web/webclient/version_info` shape.
|
|
12
|
+
*
|
|
13
|
+
* Both carry the `server_version_info` tuple under different keys; that tuple is
|
|
14
|
+
* all this resolver needs.
|
|
15
|
+
*/
|
|
16
|
+
export type VersionProbeResponse = CommonVersionResponse | {
|
|
17
|
+
readonly version: string;
|
|
18
|
+
readonly version_info: ServerVersionInfo;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* The typed failures a transport-provided VERSION probe may surface. The
|
|
22
|
+
* `VersionProbe` prefix is deliberate: the bare word "probe" belongs to the
|
|
23
|
+
* application layer's product-capability probing (`fields_get` reachability);
|
|
24
|
+
* this package only ever probes the server version.
|
|
25
|
+
*/
|
|
26
|
+
export type VersionProbeError = OdooTransportError | SchemaDriftError | ProtocolUnsupportedError;
|
|
27
|
+
/**
|
|
28
|
+
* Build a {@link VersionResolver} service from a transport-agnostic `probe`.
|
|
29
|
+
*
|
|
30
|
+
* The `Transport` seam only exposes `call_kw`, so version discovery lives with
|
|
31
|
+
* each transport family (which owns the right endpoint and decode). This
|
|
32
|
+
* resolver stays generic: hand it the decoded probe effect and it success-only
|
|
33
|
+
* single-flight caches the mapped {@link ResolvedVersion}.
|
|
34
|
+
*/
|
|
35
|
+
export declare const make: (probe: Effect.Effect<VersionProbeResponse, VersionProbeError>) => Effect.Effect<typeof VersionResolver.Service, never>;
|
|
36
|
+
/**
|
|
37
|
+
* The {@link VersionResolver} layer over a transport-provided `probe`. Transport
|
|
38
|
+
* packages construct the probe (endpoint + decode) and pass it here.
|
|
39
|
+
*/
|
|
40
|
+
export declare const layer: (probe: Effect.Effect<VersionProbeResponse, VersionProbeError>) => Layer.Layer<VersionResolver>;
|
|
41
|
+
//# sourceMappingURL=version-live.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-live.d.ts","sourceRoot":"","sources":["../src/version-live.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,OAAO,EACL,KAAK,qBAAqB,EAI1B,KAAK,iBAAiB,EACtB,eAAe,EAChB,MAAM,cAAc,CAAC;AAEtB;;;;;;;;;GASG;AACH,MAAM,MAAM,oBAAoB,GAC5B,qBAAqB,GACrB;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,iBAAiB,CAAA;CAAE,CAAC;AAE3E;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,kBAAkB,GAAG,gBAAgB,GAAG,wBAAwB,CAAC;AAUjG;;;;;;;GAOG;AACH,eAAO,MAAM,IAAI,UACR,MAAM,CAAC,MAAM,CAAC,oBAAoB,EAAE,iBAAiB,CAAC,KAC5D,MAAM,CAAC,MAAM,CAAC,OAAO,eAAe,CAAC,OAAO,EAAE,KAAK,CAIlD,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,KAAK,UACT,MAAM,CAAC,MAAM,CAAC,oBAAoB,EAAE,iBAAiB,CAAC,KAC5D,KAAK,CAAC,KAAK,CAAC,eAAe,CAA+C,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Effect, Layer } from "effect";
|
|
2
|
+
import * as SingleFlight from "./internal/singleFlight.js";
|
|
3
|
+
import { deriveWireCapabilities, parseVersionInfo, VersionResolver, } from "./version.js";
|
|
4
|
+
const extractInfo = (response) => "server_version_info" in response ? response.server_version_info : response.version_info;
|
|
5
|
+
const resolveVersion = (response) => {
|
|
6
|
+
const version = parseVersionInfo(extractInfo(response));
|
|
7
|
+
return { version, capabilities: deriveWireCapabilities(version) };
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Build a {@link VersionResolver} service from a transport-agnostic `probe`.
|
|
11
|
+
*
|
|
12
|
+
* The `Transport` seam only exposes `call_kw`, so version discovery lives with
|
|
13
|
+
* each transport family (which owns the right endpoint and decode). This
|
|
14
|
+
* resolver stays generic: hand it the decoded probe effect and it success-only
|
|
15
|
+
* single-flight caches the mapped {@link ResolvedVersion}.
|
|
16
|
+
*/
|
|
17
|
+
export const make = (probe) => Effect.gen(function* () {
|
|
18
|
+
const cache = yield* SingleFlight.make(Effect.map(probe, resolveVersion));
|
|
19
|
+
return { resolve: cache.get };
|
|
20
|
+
});
|
|
21
|
+
/**
|
|
22
|
+
* The {@link VersionResolver} layer over a transport-provided `probe`. Transport
|
|
23
|
+
* packages construct the probe (endpoint + decode) and pass it here.
|
|
24
|
+
*/
|
|
25
|
+
export const layer = (probe) => Layer.effect(VersionResolver, make(probe));
|
|
26
|
+
//# sourceMappingURL=version-live.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-live.js","sourceRoot":"","sources":["../src/version-live.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAIvC,OAAO,KAAK,YAAY,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAEL,sBAAsB,EACtB,gBAAgB,EAGhB,eAAe,GAChB,MAAM,cAAc,CAAC;AAwBtB,MAAM,WAAW,GAAG,CAAC,QAA8B,EAAqB,EAAE,CACxE,qBAAqB,IAAI,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC;AAE3F,MAAM,cAAc,GAAG,CAAC,QAA8B,EAAmB,EAAE;IACzE,MAAM,OAAO,GAAG,gBAAgB,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxD,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,sBAAsB,CAAC,OAAO,CAAC,EAAE,CAAC;AACpE,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAClB,KAA6D,EACP,EAAE,CACxD,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC;IAC1E,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC;AAChC,CAAC,CAAC,CAAC;AAEL;;;GAGG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,CACnB,KAA6D,EAC/B,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Context, type Effect, Schema } from "effect";
|
|
2
|
+
import type { ProtocolUnsupportedError } from "./errors/protocol.js";
|
|
3
|
+
import type { SchemaDriftError } from "./errors/schema.js";
|
|
4
|
+
import type { OdooTransportError } from "./errors/transport.js";
|
|
5
|
+
/**
|
|
6
|
+
* Odoo's `server_version_info`: `[major, minor, micro, releaselevel, serial]`,
|
|
7
|
+
* a heterogeneous tuple (numbers plus a string release level). Modeled
|
|
8
|
+
* leniently as a mixed array so a shape change on a future version surfaces as
|
|
9
|
+
* a decode drift rather than a silent truncation.
|
|
10
|
+
*/
|
|
11
|
+
export declare const ServerVersionInfo: Schema.$Array<Schema.Union<readonly [Schema.Number, Schema.String]>>;
|
|
12
|
+
export type ServerVersionInfo = typeof ServerVersionInfo.Type;
|
|
13
|
+
/**
|
|
14
|
+
* The response of the `common.version` call (`/jsonrpc` service `common`,
|
|
15
|
+
* method `version`). Decoded at the boundary; drift raises `SchemaDriftError`.
|
|
16
|
+
*/
|
|
17
|
+
export declare const CommonVersionResponse: Schema.Struct<{
|
|
18
|
+
readonly server_version: Schema.String;
|
|
19
|
+
readonly server_version_info: Schema.$Array<Schema.Union<readonly [Schema.Number, Schema.String]>>;
|
|
20
|
+
readonly server_serie: Schema.String;
|
|
21
|
+
readonly protocol_version: Schema.Number;
|
|
22
|
+
}>;
|
|
23
|
+
export type CommonVersionResponse = typeof CommonVersionResponse.Type;
|
|
24
|
+
/** A parsed, structured server version. */
|
|
25
|
+
export interface OdooVersion {
|
|
26
|
+
readonly major: number;
|
|
27
|
+
readonly minor: number;
|
|
28
|
+
readonly micro: number;
|
|
29
|
+
readonly releaseLevel: string;
|
|
30
|
+
readonly serial: number;
|
|
31
|
+
readonly raw: ServerVersionInfo;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* What a given server version can and cannot do, ON THE WIRE. This package
|
|
35
|
+
* owns WIRE capabilities derived from the server version; the application
|
|
36
|
+
* layer owns PRODUCT capabilities (derived from `fields_get` reachability,
|
|
37
|
+
* installed modules, …) — the bare words "capabilities"/"probe" belong to the
|
|
38
|
+
* app layer, hence the `Wire`/`VersionProbe` prefixes here.
|
|
39
|
+
*/
|
|
40
|
+
export interface WireCapabilities {
|
|
41
|
+
/** The JSON-2 `/json/2` bearer API exists (Odoo 19+). */
|
|
42
|
+
readonly supportsJson2: boolean;
|
|
43
|
+
/** `/jsonrpc` and `/xmlrpc` are deprecated upstream (Odoo 19+). */
|
|
44
|
+
readonly jsonRpcDeprecated: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* `web_read`/`web_search_read`/`web_save` accept a nested `specification`
|
|
47
|
+
* kwarg (Odoo 17+). This gates the declared-prefetch typed record path
|
|
48
|
+
* (`searchTyped`/`readTyped`/`saveTyped`); on 16 the kwarg is rejected, so a
|
|
49
|
+
* relation-free declared model degrades to `search_read`/`read` and a declared
|
|
50
|
+
* relation fails with `ProtocolUnsupportedError` before any round trip.
|
|
51
|
+
*/
|
|
52
|
+
readonly supportsWebReadSpec: boolean;
|
|
53
|
+
}
|
|
54
|
+
/** A resolved version together with its derived wire capabilities. */
|
|
55
|
+
export interface ResolvedVersion {
|
|
56
|
+
readonly version: OdooVersion;
|
|
57
|
+
readonly capabilities: WireCapabilities;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Turn a raw `server_version_info` tuple into a structured {@link OdooVersion}.
|
|
61
|
+
* Missing trailing elements default to `0` / empty; the raw tuple is retained.
|
|
62
|
+
*/
|
|
63
|
+
export declare const parseVersionInfo: (raw: ServerVersionInfo) => OdooVersion;
|
|
64
|
+
/** Derive wire capabilities from a version. JSON-2 lands, and the legacy RPC
|
|
65
|
+
* routes are deprecated, at major 19. */
|
|
66
|
+
export declare const deriveWireCapabilities: (version: OdooVersion) => WireCapabilities;
|
|
67
|
+
declare const VersionResolver_base: Context.ServiceClass<VersionResolver, "odoo-rpc-ts/VersionResolver", {
|
|
68
|
+
readonly resolve: Effect.Effect<ResolvedVersion, OdooTransportError | SchemaDriftError | ProtocolUnsupportedError>;
|
|
69
|
+
}>;
|
|
70
|
+
/**
|
|
71
|
+
* Resolves (and success-only caches) the server version behind whichever
|
|
72
|
+
* transport is provided. Implementation ships later; this is the seam so the
|
|
73
|
+
* client can gate protocol choices on capabilities.
|
|
74
|
+
*/
|
|
75
|
+
export declare class VersionResolver extends VersionResolver_base {
|
|
76
|
+
}
|
|
77
|
+
export {};
|
|
78
|
+
//# sourceMappingURL=version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACtD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAEhE;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,sEAA6D,CAAC;AAC5F,MAAM,MAAM,iBAAiB,GAAG,OAAO,iBAAiB,CAAC,IAAI,CAAC;AAE9D;;;GAGG;AACH,eAAO,MAAM,qBAAqB;;;;;EAKhC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,OAAO,qBAAqB,CAAC,IAAI,CAAC;AAEtE,2CAA2C;AAC3C,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,iBAAiB,CAAC;CACjC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,mEAAmE;IACnE,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC;;;;;;OAMG;IACH,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;CACvC;AAED,sEAAsE;AACtE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,gBAAgB,CAAC;CACzC;AAKD;;;GAGG;AACH,eAAO,MAAM,gBAAgB,QAAS,iBAAiB,KAAG,WAOxD,CAAC;AAEH;yCACyC;AACzC,eAAO,MAAM,sBAAsB,YAAa,WAAW,KAAG,gBAI5D,CAAC;;sBAUmB,MAAM,CAAC,MAAM,CAC7B,eAAe,EACf,kBAAkB,GAAG,gBAAgB,GAAG,wBAAwB,CACjE;;AAXL;;;;GAIG;AACH,qBAAa,eAAgB,SAAQ,oBAQH;CAAG"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Context, Schema } from "effect";
|
|
2
|
+
/**
|
|
3
|
+
* Odoo's `server_version_info`: `[major, minor, micro, releaselevel, serial]`,
|
|
4
|
+
* a heterogeneous tuple (numbers plus a string release level). Modeled
|
|
5
|
+
* leniently as a mixed array so a shape change on a future version surfaces as
|
|
6
|
+
* a decode drift rather than a silent truncation.
|
|
7
|
+
*/
|
|
8
|
+
export const ServerVersionInfo = Schema.Array(Schema.Union([Schema.Number, Schema.String]));
|
|
9
|
+
/**
|
|
10
|
+
* The response of the `common.version` call (`/jsonrpc` service `common`,
|
|
11
|
+
* method `version`). Decoded at the boundary; drift raises `SchemaDriftError`.
|
|
12
|
+
*/
|
|
13
|
+
export const CommonVersionResponse = Schema.Struct({
|
|
14
|
+
server_version: Schema.String,
|
|
15
|
+
server_version_info: ServerVersionInfo,
|
|
16
|
+
server_serie: Schema.String,
|
|
17
|
+
protocol_version: Schema.Number,
|
|
18
|
+
});
|
|
19
|
+
const asNumber = (value) => typeof value === "number" ? value : 0;
|
|
20
|
+
/**
|
|
21
|
+
* Turn a raw `server_version_info` tuple into a structured {@link OdooVersion}.
|
|
22
|
+
* Missing trailing elements default to `0` / empty; the raw tuple is retained.
|
|
23
|
+
*/
|
|
24
|
+
export const parseVersionInfo = (raw) => ({
|
|
25
|
+
major: asNumber(raw[0]),
|
|
26
|
+
minor: asNumber(raw[1]),
|
|
27
|
+
micro: asNumber(raw[2]),
|
|
28
|
+
releaseLevel: typeof raw[3] === "string" ? raw[3] : "",
|
|
29
|
+
serial: asNumber(raw[4]),
|
|
30
|
+
raw,
|
|
31
|
+
});
|
|
32
|
+
/** Derive wire capabilities from a version. JSON-2 lands, and the legacy RPC
|
|
33
|
+
* routes are deprecated, at major 19. */
|
|
34
|
+
export const deriveWireCapabilities = (version) => ({
|
|
35
|
+
supportsJson2: version.major >= 19,
|
|
36
|
+
jsonRpcDeprecated: version.major >= 19,
|
|
37
|
+
supportsWebReadSpec: version.major >= 17,
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* Resolves (and success-only caches) the server version behind whichever
|
|
41
|
+
* transport is provided. Implementation ships later; this is the seam so the
|
|
42
|
+
* client can gate protocol choices on capabilities.
|
|
43
|
+
*/
|
|
44
|
+
export class VersionResolver extends Context.Service()("odoo-rpc-ts/VersionResolver") {
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAe,MAAM,EAAE,MAAM,QAAQ,CAAC;AAKtD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAG5F;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,CAAC;IACjD,cAAc,EAAE,MAAM,CAAC,MAAM;IAC7B,mBAAmB,EAAE,iBAAiB;IACtC,YAAY,EAAE,MAAM,CAAC,MAAM;IAC3B,gBAAgB,EAAE,MAAM,CAAC,MAAM;CAChC,CAAC,CAAC;AAyCH,MAAM,QAAQ,GAAG,CAAC,KAAkC,EAAU,EAAE,CAC9D,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAExC;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,GAAsB,EAAe,EAAE,CAAC,CAAC;IACxE,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACvB,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACvB,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACvB,YAAY,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;IACtD,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACxB,GAAG;CACJ,CAAC,CAAC;AAEH;yCACyC;AACzC,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,OAAoB,EAAoB,EAAE,CAAC,CAAC;IACjF,aAAa,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;IAClC,iBAAiB,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;IACtC,mBAAmB,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;CACzC,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,OAAO,eAAgB,SAAQ,OAAO,CAAC,OAAO,EAQjD,CAAC,6BAA6B,CAAC;CAAG"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Protocol verification record
|
|
2
|
+
|
|
3
|
+
The protocol contract is derived from Odoo source, not third-party summaries.
|
|
4
|
+
The current Odoo 16–19 claims were reviewed at these immutable public upstream
|
|
5
|
+
snapshots:
|
|
6
|
+
|
|
7
|
+
| Odoo | Source snapshot |
|
|
8
|
+
| ---- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
9
|
+
| 16.0 | [`6aca71c9522b3be5b221847e8b005f233d3ea872`](https://github.com/odoo/odoo/tree/6aca71c9522b3be5b221847e8b005f233d3ea872) |
|
|
10
|
+
| 17.0 | [`c7953a5283e7a07e77b809c521fc372d476c2c67`](https://github.com/odoo/odoo/tree/c7953a5283e7a07e77b809c521fc372d476c2c67) |
|
|
11
|
+
| 18.0 | [`e37f0420450ed2c8f465305b19cbbcfa78162666`](https://github.com/odoo/odoo/tree/e37f0420450ed2c8f465305b19cbbcfa78162666) |
|
|
12
|
+
| 19.0 | [`c5f1a963e6c65cf67b56b7ca2d4b77de66140e78`](https://github.com/odoo/odoo/tree/c5f1a963e6c65cf67b56b7ca2d4b77de66140e78) |
|
|
13
|
+
|
|
14
|
+
## Source map
|
|
15
|
+
|
|
16
|
+
At each snapshot, the shared protocol review covered these paths:
|
|
17
|
+
|
|
18
|
+
- `odoo/http.py`: request dispatch, sessions, JSON-RPC envelopes, and
|
|
19
|
+
serialized failures; Odoo 19 also contains `Json2Dispatcher`.
|
|
20
|
+
- `odoo/service/model.py`: `execute_kw` and model-call dispatch.
|
|
21
|
+
- `odoo/service/db.py`: database-service dispatch, including `exp_restore`.
|
|
22
|
+
- `addons/web/controllers/session.py`: web-session authentication.
|
|
23
|
+
- `addons/web/controllers/dataset.py`: the web `call_kw` route.
|
|
24
|
+
- `addons/web/controllers/report.py`: authenticated report downloads.
|
|
25
|
+
- `addons/web/models/ir_http.py`: session information returned to clients.
|
|
26
|
+
- `odoo/addons/base/models/res_users.py`: authentication and API-key behavior.
|
|
27
|
+
|
|
28
|
+
Odoo 16–18 additionally expose `/jsonrpc` through
|
|
29
|
+
`odoo/addons/base/controllers/rpc.py`. The Odoo 19 protocol entry points and
|
|
30
|
+
JSON-2 fixtures are available at these immutable paths:
|
|
31
|
+
|
|
32
|
+
- [`addons/rpc/controllers/jsonrpc.py`](https://github.com/odoo/odoo/blob/c5f1a963e6c65cf67b56b7ca2d4b77de66140e78/addons/rpc/controllers/jsonrpc.py)
|
|
33
|
+
- [`addons/rpc/controllers/json2.py`](https://github.com/odoo/odoo/blob/c5f1a963e6c65cf67b56b7ca2d4b77de66140e78/addons/rpc/controllers/json2.py)
|
|
34
|
+
- [`odoo/http.py`](https://github.com/odoo/odoo/blob/c5f1a963e6c65cf67b56b7ca2d4b77de66140e78/odoo/http.py)
|
|
35
|
+
- [`odoo/addons/test_http/tests/test_webjson2.py`](https://github.com/odoo/odoo/blob/c5f1a963e6c65cf67b56b7ca2d4b77de66140e78/odoo/addons/test_http/tests/test_webjson2.py)
|
|
36
|
+
|
|
37
|
+
## Reproduce the source review
|
|
38
|
+
|
|
39
|
+
Fetch `https://github.com/odoo/odoo.git`, detach one worktree at each commit
|
|
40
|
+
above, and inspect the listed paths. A protocol change must update this record
|
|
41
|
+
to the exact new commits, identify the affected paths, and add focused fixture
|
|
42
|
+
or integration coverage. Live observations are useful corroboration, but source
|
|
43
|
+
snapshots and checked-in tests are the reproducible basis for repository claims.
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hodeinavarro/odoo-rpc-ts",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Effect-native, strongly-typed Odoo RPC client for TypeScript \u2014 JSON-RPC, JSON-2, and cookie-session transports for Odoo 16\u201319 with a tagged-error taxonomy.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"api-client",
|
|
7
|
+
"effect",
|
|
8
|
+
"effect-ts",
|
|
9
|
+
"erp",
|
|
10
|
+
"json-rpc",
|
|
11
|
+
"odoo",
|
|
12
|
+
"rpc",
|
|
13
|
+
"typescript"
|
|
14
|
+
],
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"author": "Hodei Navarro",
|
|
17
|
+
"packageManager": "pnpm@11.12.0",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/hodeinavarro/odoo-rpc-ts.git"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://github.com/hodeinavarro/odoo-rpc-ts#readme",
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/hodeinavarro/odoo-rpc-ts/issues"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"src",
|
|
29
|
+
"docs/protocol-verification.md"
|
|
30
|
+
],
|
|
31
|
+
"type": "module",
|
|
32
|
+
"sideEffects": false,
|
|
33
|
+
"exports": {
|
|
34
|
+
".": {
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"default": "./dist/index.js"
|
|
37
|
+
},
|
|
38
|
+
"./testing": {
|
|
39
|
+
"types": "./dist/testing/index.d.ts",
|
|
40
|
+
"default": "./dist/testing/index.js"
|
|
41
|
+
},
|
|
42
|
+
"./package.json": "./package.json"
|
|
43
|
+
},
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public",
|
|
46
|
+
"registry": "https://registry.npmjs.org/"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json && node scripts/fix-dts-extensions.mjs",
|
|
50
|
+
"prepack": "pnpm build",
|
|
51
|
+
"check": "tsc --noEmit",
|
|
52
|
+
"harness": "node harness/cli.mjs",
|
|
53
|
+
"test": "vitest run",
|
|
54
|
+
"test:integration": "vitest run --config vitest.integration.config.ts",
|
|
55
|
+
"lint": "oxlint",
|
|
56
|
+
"fmt": "oxfmt"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@effect/platform-node": "4.0.0-beta.93",
|
|
60
|
+
"@effect/vitest": "4.0.0-beta.93",
|
|
61
|
+
"@types/node": "^26.1.1",
|
|
62
|
+
"effect": "4.0.0-beta.93",
|
|
63
|
+
"oxfmt": "^0.58.0",
|
|
64
|
+
"oxlint": "^1.73.0",
|
|
65
|
+
"typescript": "^7.0.2",
|
|
66
|
+
"vitest": "^4.1.10"
|
|
67
|
+
},
|
|
68
|
+
"peerDependencies": {
|
|
69
|
+
"effect": "4.0.0-beta.93"
|
|
70
|
+
}
|
|
71
|
+
}
|