@archont561/qgis-sdk-bridge 0.0.0 → 0.1.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/README.md CHANGED
@@ -1,45 +1,33 @@
1
1
  # @archont561/qgis-sdk-bridge
2
2
 
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
3
+ **TypeScript contract, wire-limit, and error primitives for QGIS `QWebEngineView` plugin interfaces.**
4
4
 
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
5
+ `@archont561/qgis-sdk-bridge` is the TypeScript companion package to [`qgis-sdk`](https://pypi.org/project/qgis-sdk/) in the [QGIS SDK workspace](https://github.com/Archont561/qgis-sdk).
6
6
 
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
7
+ > **Status (`0.1.0` experimental):** Exposes the version 1 plugin/action declaration parser (`parsePluginDescription`, `PluginDescription`, `ActionDescription`), JavaScript-safe integer wire bounds (`MAX_SAFE_INTEGER`, `MIN_SAFE_INTEGER`, `isSafeJsonInteger`), and the `QgisSdk*`-prefixed error hierarchy (`QgisSdkError`, `QgisSdkScopeClosedError`, `QgisSdkUnsupportedCapabilityError`, `QgisSdkDeclarationError`, `QgisSdkContractValidationError`, `QgisSdkValidationIssue`). `QWebChannel` transport bindings, generated operation clients, and React hooks are scheduled for subsequent `0.x` milestones.
8
8
 
9
- ## Purpose
9
+ ## Exports
10
10
 
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `@archont561/qgis-sdk-bridge`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
11
+ ```ts
12
+ import {
13
+ MAX_SAFE_INTEGER,
14
+ MIN_SAFE_INTEGER,
15
+ PLUGIN_DESCRIPTION_SCHEMA_VERSION,
16
+ QgisSdkContractValidationError,
17
+ QgisSdkDeclarationError,
18
+ QgisSdkError,
19
+ QgisSdkScopeClosedError,
20
+ QgisSdkUnsupportedCapabilityError,
21
+ QgisSdkValidationIssue,
22
+ isSafeJsonInteger,
23
+ parsePluginDescription,
24
+ } from "@archont561/qgis-sdk-bridge";
25
+ ```
15
26
 
16
- ## What is OIDC Trusted Publishing?
27
+ - **Safe integer bounds:** `MAX_SAFE_INTEGER` (`9007199254740991`), `MIN_SAFE_INTEGER` (`-9007199254740991`), and `isSafeJsonInteger(value)` mirror `qgis_sdk.models.MAX_SAFE_INTEGER` and `SafeJsonInteger`.
28
+ - **Version 1 plugin descriptions:** `parsePluginDescription(raw)` validates and freezes `PluginDescription` payloads (`schema_version: 1`) produced by Python's `describe_plugin(cls).to_json()`.
29
+ - **Structured SDK errors:** Every SDK exception class begins with `QgisSdk` and carries a stable wire `code` property (`"sdk_error"`, `"scope_closed"`, `"unsupported_capability"`, `"invalid_declaration"`, `"contract_validation_failed"`).
17
30
 
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
31
+ ## License
19
32
 
20
- ## Setup Instructions
21
-
22
- To properly configure OIDC trusted publishing for this package:
23
-
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
28
-
29
- ## DO NOT USE THIS PACKAGE
30
-
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
36
-
37
- ## More Information
38
-
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
42
-
43
- ---
44
-
45
- **Maintained for OIDC setup purposes only**
33
+ MIT
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Public 0.1.0 contract, wire-limit, and error primitives for the QGIS SDK bridge.
3
+ *
4
+ * Mirrors the QGIS-free `qgis_sdk.models` and `qgis_sdk.declarations`
5
+ * (`schema_version = 1`) contracts without importing browser or Qt globals.
6
+ */
7
+ declare const MAX_SAFE_INTEGER: number;
8
+ declare const MIN_SAFE_INTEGER: number;
9
+ declare const PLUGIN_DESCRIPTION_SCHEMA_VERSION: 1;
10
+ type ValidationDirection = "request" | "result";
11
+ interface SerializedValidationIssue {
12
+ readonly path: (string | number)[];
13
+ readonly code: string;
14
+ }
15
+ interface SerializedContractValidationError {
16
+ readonly code: string;
17
+ readonly direction: ValidationDirection;
18
+ readonly issues: SerializedValidationIssue[];
19
+ }
20
+ interface ActionDescription {
21
+ readonly id: string;
22
+ readonly title: string;
23
+ readonly handler: string;
24
+ readonly request: Readonly<Record<string, unknown>>;
25
+ readonly result: Readonly<Record<string, unknown>>;
26
+ }
27
+ interface PluginDescription {
28
+ readonly schema_version: 1;
29
+ readonly id: string;
30
+ readonly title: string;
31
+ readonly actions: readonly ActionDescription[];
32
+ }
33
+ /**
34
+ * Return whether `value` is a finite integer within the JavaScript-safe wire range.
35
+ */
36
+ declare function isSafeJsonInteger(value: unknown): value is number;
37
+ /**
38
+ * Base class for expected SDK errors across the bridge boundary.
39
+ */
40
+ declare class QgisSdkError extends Error {
41
+ readonly code: string;
42
+ constructor(message: string, code?: string);
43
+ }
44
+ /**
45
+ * An operation attempted to use an already disposed owner scope.
46
+ */
47
+ declare class QgisSdkScopeClosedError extends QgisSdkError {
48
+ constructor();
49
+ }
50
+ /**
51
+ * The selected runtime does not offer an explicitly requested capability.
52
+ */
53
+ declare class QgisSdkUnsupportedCapabilityError extends QgisSdkError {
54
+ readonly capability: string;
55
+ constructor(capability: string);
56
+ }
57
+ /**
58
+ * A declaration cannot be represented or parsed in the versioned contract.
59
+ */
60
+ declare class QgisSdkDeclarationError extends QgisSdkError {
61
+ constructor(message: string);
62
+ }
63
+ /**
64
+ * Safe, structured location and category for a rejected contract value.
65
+ */
66
+ declare class QgisSdkValidationIssue {
67
+ readonly path: readonly (string | number)[];
68
+ readonly code: string;
69
+ constructor(path: readonly (string | number)[], code: string);
70
+ toJSON(): SerializedValidationIssue;
71
+ }
72
+ /**
73
+ * A request or result did not satisfy its declared wire contract.
74
+ */
75
+ declare class QgisSdkContractValidationError extends QgisSdkError {
76
+ readonly direction: ValidationDirection;
77
+ readonly issues: readonly QgisSdkValidationIssue[];
78
+ constructor(direction: ValidationDirection, issues: readonly QgisSdkValidationIssue[]);
79
+ toJSON(): SerializedContractValidationError;
80
+ }
81
+ /**
82
+ * Parse and validate a version 1 `PluginDescription` emitted by `describe_plugin`.
83
+ */
84
+ declare function parsePluginDescription(input: string | Readonly<Record<string, unknown>>): PluginDescription;
85
+ export { ActionDescription, MAX_SAFE_INTEGER, MIN_SAFE_INTEGER, PLUGIN_DESCRIPTION_SCHEMA_VERSION, PluginDescription, QgisSdkContractValidationError, QgisSdkDeclarationError, QgisSdkError, QgisSdkScopeClosedError, QgisSdkUnsupportedCapabilityError, QgisSdkValidationIssue, SerializedContractValidationError, SerializedValidationIssue, ValidationDirection, isSafeJsonInteger, parsePluginDescription };
package/dist/index.js ADDED
@@ -0,0 +1,163 @@
1
+ // src/index.ts
2
+ var MAX_SAFE_INTEGER = 9007199254740991;
3
+ var MIN_SAFE_INTEGER = -9007199254740991;
4
+ var PLUGIN_DESCRIPTION_SCHEMA_VERSION = 1;
5
+ function isSafeJsonInteger(value) {
6
+ return typeof value === "number" && Number.isSafeInteger(value);
7
+ }
8
+
9
+ class QgisSdkError extends Error {
10
+ code;
11
+ constructor(message, code = "sdk_error") {
12
+ super(message);
13
+ this.name = new.target.name;
14
+ this.code = code;
15
+ }
16
+ }
17
+
18
+ class QgisSdkScopeClosedError extends QgisSdkError {
19
+ constructor() {
20
+ super("This resource scope has been disposed", "scope_closed");
21
+ }
22
+ }
23
+
24
+ class QgisSdkUnsupportedCapabilityError extends QgisSdkError {
25
+ capability;
26
+ constructor(capability) {
27
+ super(`Capability ${JSON.stringify(capability)} is unavailable in this runtime`, "unsupported_capability");
28
+ this.capability = capability;
29
+ }
30
+ }
31
+
32
+ class QgisSdkDeclarationError extends QgisSdkError {
33
+ constructor(message) {
34
+ super(message, "invalid_declaration");
35
+ }
36
+ }
37
+
38
+ class QgisSdkValidationIssue {
39
+ path;
40
+ code;
41
+ constructor(path, code) {
42
+ this.path = Object.freeze([...path]);
43
+ this.code = code;
44
+ }
45
+ toJSON() {
46
+ return {
47
+ path: [...this.path],
48
+ code: this.code
49
+ };
50
+ }
51
+ }
52
+
53
+ class QgisSdkContractValidationError extends QgisSdkError {
54
+ direction;
55
+ issues;
56
+ constructor(direction, issues) {
57
+ const prefix = direction === "request" ? "Request" : "Result";
58
+ super(`${prefix} contract validation failed`, "contract_validation_failed");
59
+ this.direction = direction;
60
+ this.issues = Object.freeze([...issues]);
61
+ }
62
+ toJSON() {
63
+ return {
64
+ code: this.code,
65
+ direction: this.direction,
66
+ issues: this.issues.map((issue) => issue.toJSON())
67
+ };
68
+ }
69
+ }
70
+ var DECLARATION_ID_PATTERN = /^[a-zA-Z][a-zA-Z0-9_.-]*$/;
71
+ var PYTHON_IDENTIFIER_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
72
+ function isPlainRecord(value) {
73
+ return typeof value === "object" && value !== null && !Array.isArray(value);
74
+ }
75
+ function validateDeclarationId(value, label) {
76
+ if (typeof value !== "string" || !DECLARATION_ID_PATTERN.test(value)) {
77
+ throw new QgisSdkDeclarationError(`Invalid ${label} id: expected [a-zA-Z][a-zA-Z0-9_.-]*`);
78
+ }
79
+ return value;
80
+ }
81
+ function validateNonBlankTitle(value, id) {
82
+ if (typeof value !== "string" || value.trim().length === 0) {
83
+ throw new QgisSdkDeclarationError(`${id}: title must be a nonempty string`);
84
+ }
85
+ return value;
86
+ }
87
+ function parseActionDescription(raw) {
88
+ if (!isPlainRecord(raw)) {
89
+ throw new QgisSdkDeclarationError("Action description must be an object");
90
+ }
91
+ const id = validateDeclarationId(raw.id, "action");
92
+ const title = validateNonBlankTitle(raw.title, id);
93
+ if (typeof raw.handler !== "string" || !PYTHON_IDENTIFIER_PATTERN.test(raw.handler)) {
94
+ throw new QgisSdkDeclarationError(`${id}: handler must be a valid Python identifier`);
95
+ }
96
+ if (!isPlainRecord(raw.request)) {
97
+ throw new QgisSdkDeclarationError(`${id}: request schema must be an object`);
98
+ }
99
+ if (!isPlainRecord(raw.result)) {
100
+ throw new QgisSdkDeclarationError(`${id}: result schema must be an object`);
101
+ }
102
+ return Object.freeze({
103
+ id,
104
+ title,
105
+ handler: raw.handler,
106
+ request: Object.freeze({ ...raw.request }),
107
+ result: Object.freeze({ ...raw.result })
108
+ });
109
+ }
110
+ function parsePluginDescription(input) {
111
+ let parsed = input;
112
+ if (typeof input === "string") {
113
+ try {
114
+ parsed = JSON.parse(input);
115
+ } catch {
116
+ throw new QgisSdkDeclarationError("Plugin description is not valid JSON");
117
+ }
118
+ }
119
+ if (!isPlainRecord(parsed)) {
120
+ throw new QgisSdkDeclarationError("Plugin description must be an object");
121
+ }
122
+ if (parsed.schema_version !== PLUGIN_DESCRIPTION_SCHEMA_VERSION) {
123
+ throw new QgisSdkDeclarationError(`Unsupported plugin description schema_version: ${String(parsed.schema_version)}`);
124
+ }
125
+ const id = validateDeclarationId(parsed.id, "plugin");
126
+ const title = validateNonBlankTitle(parsed.title, id);
127
+ if (!Array.isArray(parsed.actions)) {
128
+ throw new QgisSdkDeclarationError(`${id}: actions must be an array`);
129
+ }
130
+ const seenIds = new Set;
131
+ const actions = [];
132
+ for (const item of parsed.actions) {
133
+ const action = parseActionDescription(item);
134
+ if (seenIds.has(action.id)) {
135
+ throw new QgisSdkDeclarationError(`${id}: duplicate action id ${action.id}`);
136
+ }
137
+ seenIds.add(action.id);
138
+ actions.push(action);
139
+ }
140
+ actions.sort((left, right) => left.id < right.id ? -1 : 1);
141
+ return Object.freeze({
142
+ schema_version: PLUGIN_DESCRIPTION_SCHEMA_VERSION,
143
+ id,
144
+ title,
145
+ actions: Object.freeze(actions)
146
+ });
147
+ }
148
+ export {
149
+ MAX_SAFE_INTEGER,
150
+ MIN_SAFE_INTEGER,
151
+ PLUGIN_DESCRIPTION_SCHEMA_VERSION,
152
+ QgisSdkContractValidationError,
153
+ QgisSdkDeclarationError,
154
+ QgisSdkError,
155
+ QgisSdkScopeClosedError,
156
+ QgisSdkUnsupportedCapabilityError,
157
+ QgisSdkValidationIssue,
158
+ isSafeJsonInteger,
159
+ parsePluginDescription
160
+ };
161
+
162
+ //# debugId=3494C4156313BA2364756E2164756E21
163
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWwogICAgIi8qKlxuICogUHVibGljIDAuMS4wIGNvbnRyYWN0LCB3aXJlLWxpbWl0LCBhbmQgZXJyb3IgcHJpbWl0aXZlcyBmb3IgdGhlIFFHSVMgU0RLIGJyaWRnZS5cbiAqXG4gKiBNaXJyb3JzIHRoZSBRR0lTLWZyZWUgYHFnaXNfc2RrLm1vZGVsc2AgYW5kIGBxZ2lzX3Nkay5kZWNsYXJhdGlvbnNgXG4gKiAoYHNjaGVtYV92ZXJzaW9uID0gMWApIGNvbnRyYWN0cyB3aXRob3V0IGltcG9ydGluZyBicm93c2VyIG9yIFF0IGdsb2JhbHMuXG4gKi9cblxuZXhwb3J0IGNvbnN0IE1BWF9TQUZFX0lOVEVHRVI6IG51bWJlciA9IDlfMDA3XzE5OV8yNTRfNzQwXzk5MTtcbmV4cG9ydCBjb25zdCBNSU5fU0FGRV9JTlRFR0VSOiBudW1iZXIgPSAtOV8wMDdfMTk5XzI1NF83NDBfOTkxO1xuZXhwb3J0IGNvbnN0IFBMVUdJTl9ERVNDUklQVElPTl9TQ0hFTUFfVkVSU0lPTjogMSA9IDE7XG5cbmV4cG9ydCB0eXBlIFZhbGlkYXRpb25EaXJlY3Rpb24gPSBcInJlcXVlc3RcIiB8IFwicmVzdWx0XCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2VyaWFsaXplZFZhbGlkYXRpb25Jc3N1ZSB7XG5cdHJlYWRvbmx5IHBhdGg6IChzdHJpbmcgfCBudW1iZXIpW107XG5cdHJlYWRvbmx5IGNvZGU6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTZXJpYWxpemVkQ29udHJhY3RWYWxpZGF0aW9uRXJyb3Ige1xuXHRyZWFkb25seSBjb2RlOiBzdHJpbmc7XG5cdHJlYWRvbmx5IGRpcmVjdGlvbjogVmFsaWRhdGlvbkRpcmVjdGlvbjtcblx0cmVhZG9ubHkgaXNzdWVzOiBTZXJpYWxpemVkVmFsaWRhdGlvbklzc3VlW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWN0aW9uRGVzY3JpcHRpb24ge1xuXHRyZWFkb25seSBpZDogc3RyaW5nO1xuXHRyZWFkb25seSB0aXRsZTogc3RyaW5nO1xuXHRyZWFkb25seSBoYW5kbGVyOiBzdHJpbmc7XG5cdHJlYWRvbmx5IHJlcXVlc3Q6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Pjtcblx0cmVhZG9ubHkgcmVzdWx0OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGx1Z2luRGVzY3JpcHRpb24ge1xuXHRyZWFkb25seSBzY2hlbWFfdmVyc2lvbjogMTtcblx0cmVhZG9ubHkgaWQ6IHN0cmluZztcblx0cmVhZG9ubHkgdGl0bGU6IHN0cmluZztcblx0cmVhZG9ubHkgYWN0aW9uczogcmVhZG9ubHkgQWN0aW9uRGVzY3JpcHRpb25bXTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gd2hldGhlciBgdmFsdWVgIGlzIGEgZmluaXRlIGludGVnZXIgd2l0aGluIHRoZSBKYXZhU2NyaXB0LXNhZmUgd2lyZSByYW5nZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU2FmZUpzb25JbnRlZ2VyKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgbnVtYmVyIHtcblx0cmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIiAmJiBOdW1iZXIuaXNTYWZlSW50ZWdlcih2YWx1ZSk7XG59XG5cbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgZXhwZWN0ZWQgU0RLIGVycm9ycyBhY3Jvc3MgdGhlIGJyaWRnZSBib3VuZGFyeS5cbiAqL1xuZXhwb3J0IGNsYXNzIFFnaXNTZGtFcnJvciBleHRlbmRzIEVycm9yIHtcblx0cHVibGljIHJlYWRvbmx5IGNvZGU6IHN0cmluZztcblxuXHRwdWJsaWMgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nLCBjb2RlOiBzdHJpbmcgPSBcInNka19lcnJvclwiKSB7XG5cdFx0c3VwZXIobWVzc2FnZSk7XG5cdFx0dGhpcy5uYW1lID0gbmV3LnRhcmdldC5uYW1lO1xuXHRcdHRoaXMuY29kZSA9IGNvZGU7XG5cdH1cbn1cblxuLyoqXG4gKiBBbiBvcGVyYXRpb24gYXR0ZW1wdGVkIHRvIHVzZSBhbiBhbHJlYWR5IGRpc3Bvc2VkIG93bmVyIHNjb3BlLlxuICovXG5leHBvcnQgY2xhc3MgUWdpc1Nka1Njb3BlQ2xvc2VkRXJyb3IgZXh0ZW5kcyBRZ2lzU2RrRXJyb3Ige1xuXHRwdWJsaWMgY29uc3RydWN0b3IoKSB7XG5cdFx0c3VwZXIoXCJUaGlzIHJlc291cmNlIHNjb3BlIGhhcyBiZWVuIGRpc3Bvc2VkXCIsIFwic2NvcGVfY2xvc2VkXCIpO1xuXHR9XG59XG5cbi8qKlxuICogVGhlIHNlbGVjdGVkIHJ1bnRpbWUgZG9lcyBub3Qgb2ZmZXIgYW4gZXhwbGljaXRseSByZXF1ZXN0ZWQgY2FwYWJpbGl0eS5cbiAqL1xuZXhwb3J0IGNsYXNzIFFnaXNTZGtVbnN1cHBvcnRlZENhcGFiaWxpdHlFcnJvciBleHRlbmRzIFFnaXNTZGtFcnJvciB7XG5cdHB1YmxpYyByZWFkb25seSBjYXBhYmlsaXR5OiBzdHJpbmc7XG5cblx0cHVibGljIGNvbnN0cnVjdG9yKGNhcGFiaWxpdHk6IHN0cmluZykge1xuXHRcdHN1cGVyKFxuXHRcdFx0YENhcGFiaWxpdHkgJHtKU09OLnN0cmluZ2lmeShjYXBhYmlsaXR5KX0gaXMgdW5hdmFpbGFibGUgaW4gdGhpcyBydW50aW1lYCxcblx0XHRcdFwidW5zdXBwb3J0ZWRfY2FwYWJpbGl0eVwiLFxuXHRcdCk7XG5cdFx0dGhpcy5jYXBhYmlsaXR5ID0gY2FwYWJpbGl0eTtcblx0fVxufVxuXG4vKipcbiAqIEEgZGVjbGFyYXRpb24gY2Fubm90IGJlIHJlcHJlc2VudGVkIG9yIHBhcnNlZCBpbiB0aGUgdmVyc2lvbmVkIGNvbnRyYWN0LlxuICovXG5leHBvcnQgY2xhc3MgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IgZXh0ZW5kcyBRZ2lzU2RrRXJyb3Ige1xuXHRwdWJsaWMgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG5cdFx0c3VwZXIobWVzc2FnZSwgXCJpbnZhbGlkX2RlY2xhcmF0aW9uXCIpO1xuXHR9XG59XG5cbi8qKlxuICogU2FmZSwgc3RydWN0dXJlZCBsb2NhdGlvbiBhbmQgY2F0ZWdvcnkgZm9yIGEgcmVqZWN0ZWQgY29udHJhY3QgdmFsdWUuXG4gKi9cbmV4cG9ydCBjbGFzcyBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlIHtcblx0cHVibGljIHJlYWRvbmx5IHBhdGg6IHJlYWRvbmx5IChzdHJpbmcgfCBudW1iZXIpW107XG5cdHB1YmxpYyByZWFkb25seSBjb2RlOiBzdHJpbmc7XG5cblx0cHVibGljIGNvbnN0cnVjdG9yKHBhdGg6IHJlYWRvbmx5IChzdHJpbmcgfCBudW1iZXIpW10sIGNvZGU6IHN0cmluZykge1xuXHRcdHRoaXMucGF0aCA9IE9iamVjdC5mcmVlemUoWy4uLnBhdGhdKTtcblx0XHR0aGlzLmNvZGUgPSBjb2RlO1xuXHR9XG5cblx0cHVibGljIHRvSlNPTigpOiBTZXJpYWxpemVkVmFsaWRhdGlvbklzc3VlIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0cGF0aDogWy4uLnRoaXMucGF0aF0sXG5cdFx0XHRjb2RlOiB0aGlzLmNvZGUsXG5cdFx0fTtcblx0fVxufVxuXG4vKipcbiAqIEEgcmVxdWVzdCBvciByZXN1bHQgZGlkIG5vdCBzYXRpc2Z5IGl0cyBkZWNsYXJlZCB3aXJlIGNvbnRyYWN0LlxuICovXG5leHBvcnQgY2xhc3MgUWdpc1Nka0NvbnRyYWN0VmFsaWRhdGlvbkVycm9yIGV4dGVuZHMgUWdpc1Nka0Vycm9yIHtcblx0cHVibGljIHJlYWRvbmx5IGRpcmVjdGlvbjogVmFsaWRhdGlvbkRpcmVjdGlvbjtcblx0cHVibGljIHJlYWRvbmx5IGlzc3VlczogcmVhZG9ubHkgUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZVtdO1xuXG5cdHB1YmxpYyBjb25zdHJ1Y3Rvcihcblx0XHRkaXJlY3Rpb246IFZhbGlkYXRpb25EaXJlY3Rpb24sXG5cdFx0aXNzdWVzOiByZWFkb25seSBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlW10sXG5cdCkge1xuXHRcdGNvbnN0IHByZWZpeCA9IGRpcmVjdGlvbiA9PT0gXCJyZXF1ZXN0XCIgPyBcIlJlcXVlc3RcIiA6IFwiUmVzdWx0XCI7XG5cdFx0c3VwZXIoYCR7cHJlZml4fSBjb250cmFjdCB2YWxpZGF0aW9uIGZhaWxlZGAsIFwiY29udHJhY3RfdmFsaWRhdGlvbl9mYWlsZWRcIik7XG5cdFx0dGhpcy5kaXJlY3Rpb24gPSBkaXJlY3Rpb247XG5cdFx0dGhpcy5pc3N1ZXMgPSBPYmplY3QuZnJlZXplKFsuLi5pc3N1ZXNdKTtcblx0fVxuXG5cdHB1YmxpYyB0b0pTT04oKTogU2VyaWFsaXplZENvbnRyYWN0VmFsaWRhdGlvbkVycm9yIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0Y29kZTogdGhpcy5jb2RlLFxuXHRcdFx0ZGlyZWN0aW9uOiB0aGlzLmRpcmVjdGlvbixcblx0XHRcdGlzc3VlczogdGhpcy5pc3N1ZXMubWFwKChpc3N1ZSkgPT4gaXNzdWUudG9KU09OKCkpLFxuXHRcdH07XG5cdH1cbn1cblxuY29uc3QgREVDTEFSQVRJT05fSURfUEFUVEVSTiA9IC9eW2EtekEtWl1bYS16QS1aMC05Xy4tXSokLztcbmNvbnN0IFBZVEhPTl9JREVOVElGSUVSX1BBVFRFUk4gPSAvXlthLXpBLVpfXVthLXpBLVowLTlfXSokLztcblxuZnVuY3Rpb24gaXNQbGFpblJlY29yZCh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcblx0cmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJiB2YWx1ZSAhPT0gbnVsbCAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlRGVjbGFyYXRpb25JZCh2YWx1ZTogdW5rbm93biwgbGFiZWw6IHN0cmluZyk6IHN0cmluZyB7XG5cdGlmICh0eXBlb2YgdmFsdWUgIT09IFwic3RyaW5nXCIgfHwgIURFQ0xBUkFUSU9OX0lEX1BBVFRFUk4udGVzdCh2YWx1ZSkpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXG5cdFx0XHRgSW52YWxpZCAke2xhYmVsfSBpZDogZXhwZWN0ZWQgW2EtekEtWl1bYS16QS1aMC05Xy4tXSpgLFxuXHRcdCk7XG5cdH1cblx0cmV0dXJuIHZhbHVlO1xufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZU5vbkJsYW5rVGl0bGUodmFsdWU6IHVua25vd24sIGlkOiBzdHJpbmcpOiBzdHJpbmcge1xuXHRpZiAodHlwZW9mIHZhbHVlICE9PSBcInN0cmluZ1wiIHx8IHZhbHVlLnRyaW0oKS5sZW5ndGggPT09IDApIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoYCR7aWR9OiB0aXRsZSBtdXN0IGJlIGEgbm9uZW1wdHkgc3RyaW5nYCk7XG5cdH1cblx0cmV0dXJuIHZhbHVlO1xufVxuXG5mdW5jdGlvbiBwYXJzZUFjdGlvbkRlc2NyaXB0aW9uKHJhdzogdW5rbm93bik6IEFjdGlvbkRlc2NyaXB0aW9uIHtcblx0aWYgKCFpc1BsYWluUmVjb3JkKHJhdykpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXCJBY3Rpb24gZGVzY3JpcHRpb24gbXVzdCBiZSBhbiBvYmplY3RcIik7XG5cdH1cblx0Y29uc3QgaWQgPSB2YWxpZGF0ZURlY2xhcmF0aW9uSWQocmF3LmlkLCBcImFjdGlvblwiKTtcblx0Y29uc3QgdGl0bGUgPSB2YWxpZGF0ZU5vbkJsYW5rVGl0bGUocmF3LnRpdGxlLCBpZCk7XG5cdGlmIChcblx0XHR0eXBlb2YgcmF3LmhhbmRsZXIgIT09IFwic3RyaW5nXCIgfHxcblx0XHQhUFlUSE9OX0lERU5USUZJRVJfUEFUVEVSTi50ZXN0KHJhdy5oYW5kbGVyKVxuXHQpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXG5cdFx0XHRgJHtpZH06IGhhbmRsZXIgbXVzdCBiZSBhIHZhbGlkIFB5dGhvbiBpZGVudGlmaWVyYCxcblx0XHQpO1xuXHR9XG5cdGlmICghaXNQbGFpblJlY29yZChyYXcucmVxdWVzdCkpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXG5cdFx0XHRgJHtpZH06IHJlcXVlc3Qgc2NoZW1hIG11c3QgYmUgYW4gb2JqZWN0YCxcblx0XHQpO1xuXHR9XG5cdGlmICghaXNQbGFpblJlY29yZChyYXcucmVzdWx0KSkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihgJHtpZH06IHJlc3VsdCBzY2hlbWEgbXVzdCBiZSBhbiBvYmplY3RgKTtcblx0fVxuXHRyZXR1cm4gT2JqZWN0LmZyZWV6ZSh7XG5cdFx0aWQsXG5cdFx0dGl0bGUsXG5cdFx0aGFuZGxlcjogcmF3LmhhbmRsZXIsXG5cdFx0cmVxdWVzdDogT2JqZWN0LmZyZWV6ZSh7IC4uLnJhdy5yZXF1ZXN0IH0pLFxuXHRcdHJlc3VsdDogT2JqZWN0LmZyZWV6ZSh7IC4uLnJhdy5yZXN1bHQgfSksXG5cdH0pO1xufVxuXG4vKipcbiAqIFBhcnNlIGFuZCB2YWxpZGF0ZSBhIHZlcnNpb24gMSBgUGx1Z2luRGVzY3JpcHRpb25gIGVtaXR0ZWQgYnkgYGRlc2NyaWJlX3BsdWdpbmAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVBsdWdpbkRlc2NyaXB0aW9uKFxuXHRpbnB1dDogc3RyaW5nIHwgUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+LFxuKTogUGx1Z2luRGVzY3JpcHRpb24ge1xuXHRsZXQgcGFyc2VkOiB1bmtub3duID0gaW5wdXQ7XG5cdGlmICh0eXBlb2YgaW5wdXQgPT09IFwic3RyaW5nXCIpIHtcblx0XHR0cnkge1xuXHRcdFx0cGFyc2VkID0gSlNPTi5wYXJzZShpbnB1dCk7XG5cdFx0fSBjYXRjaCB7XG5cdFx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXCJQbHVnaW4gZGVzY3JpcHRpb24gaXMgbm90IHZhbGlkIEpTT05cIik7XG5cdFx0fVxuXHR9XG5cdGlmICghaXNQbGFpblJlY29yZChwYXJzZWQpKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKFwiUGx1Z2luIGRlc2NyaXB0aW9uIG11c3QgYmUgYW4gb2JqZWN0XCIpO1xuXHR9XG5cdGlmIChwYXJzZWQuc2NoZW1hX3ZlcnNpb24gIT09IFBMVUdJTl9ERVNDUklQVElPTl9TQ0hFTUFfVkVSU0lPTikge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGBVbnN1cHBvcnRlZCBwbHVnaW4gZGVzY3JpcHRpb24gc2NoZW1hX3ZlcnNpb246ICR7U3RyaW5nKHBhcnNlZC5zY2hlbWFfdmVyc2lvbil9YCxcblx0XHQpO1xuXHR9XG5cdGNvbnN0IGlkID0gdmFsaWRhdGVEZWNsYXJhdGlvbklkKHBhcnNlZC5pZCwgXCJwbHVnaW5cIik7XG5cdGNvbnN0IHRpdGxlID0gdmFsaWRhdGVOb25CbGFua1RpdGxlKHBhcnNlZC50aXRsZSwgaWQpO1xuXHRpZiAoIUFycmF5LmlzQXJyYXkocGFyc2VkLmFjdGlvbnMpKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKGAke2lkfTogYWN0aW9ucyBtdXN0IGJlIGFuIGFycmF5YCk7XG5cdH1cblx0Y29uc3Qgc2VlbklkcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXHRjb25zdCBhY3Rpb25zOiBBY3Rpb25EZXNjcmlwdGlvbltdID0gW107XG5cdGZvciAoY29uc3QgaXRlbSBvZiBwYXJzZWQuYWN0aW9ucykge1xuXHRcdGNvbnN0IGFjdGlvbiA9IHBhcnNlQWN0aW9uRGVzY3JpcHRpb24oaXRlbSk7XG5cdFx0aWYgKHNlZW5JZHMuaGFzKGFjdGlvbi5pZCkpIHtcblx0XHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdFx0YCR7aWR9OiBkdXBsaWNhdGUgYWN0aW9uIGlkICR7YWN0aW9uLmlkfWAsXG5cdFx0XHQpO1xuXHRcdH1cblx0XHRzZWVuSWRzLmFkZChhY3Rpb24uaWQpO1xuXHRcdGFjdGlvbnMucHVzaChhY3Rpb24pO1xuXHR9XG5cdGFjdGlvbnMuc29ydCgobGVmdCwgcmlnaHQpID0+IChsZWZ0LmlkIDwgcmlnaHQuaWQgPyAtMSA6IDEpKTtcblx0cmV0dXJuIE9iamVjdC5mcmVlemUoe1xuXHRcdHNjaGVtYV92ZXJzaW9uOiBQTFVHSU5fREVTQ1JJUFRJT05fU0NIRU1BX1ZFUlNJT04sXG5cdFx0aWQsXG5cdFx0dGl0bGUsXG5cdFx0YWN0aW9uczogT2JqZWN0LmZyZWV6ZShhY3Rpb25zKSxcblx0fSk7XG59XG4iCiAgXSwKICAibWFwcGluZ3MiOiAiO0FBT08sSUFBTSxtQkFBMkI7QUFDakMsSUFBTSxtQkFBMkI7QUFDakMsSUFBTSxvQ0FBdUM7QUFpQzdDLFNBQVMsaUJBQWlCLENBQUMsT0FBaUM7QUFBQSxFQUNsRSxPQUFPLE9BQU8sVUFBVSxZQUFZLE9BQU8sY0FBYyxLQUFLO0FBQUE7QUFBQTtBQU14RCxNQUFNLHFCQUFxQixNQUFNO0FBQUEsRUFDdkI7QUFBQSxFQUVULFdBQVcsQ0FBQyxTQUFpQixPQUFlLGFBQWE7QUFBQSxJQUMvRCxNQUFNLE9BQU87QUFBQSxJQUNiLEtBQUssT0FBTyxXQUFXO0FBQUEsSUFDdkIsS0FBSyxPQUFPO0FBQUE7QUFFZDtBQUFBO0FBS08sTUFBTSxnQ0FBZ0MsYUFBYTtBQUFBLEVBQ2xELFdBQVcsR0FBRztBQUFBLElBQ3BCLE1BQU0seUNBQXlDLGNBQWM7QUFBQTtBQUUvRDtBQUFBO0FBS08sTUFBTSwwQ0FBMEMsYUFBYTtBQUFBLEVBQ25EO0FBQUEsRUFFVCxXQUFXLENBQUMsWUFBb0I7QUFBQSxJQUN0QyxNQUNDLGNBQWMsS0FBSyxVQUFVLFVBQVUsb0NBQ3ZDLHdCQUNEO0FBQUEsSUFDQSxLQUFLLGFBQWE7QUFBQTtBQUVwQjtBQUFBO0FBS08sTUFBTSxnQ0FBZ0MsYUFBYTtBQUFBLEVBQ2xELFdBQVcsQ0FBQyxTQUFpQjtBQUFBLElBQ25DLE1BQU0sU0FBUyxxQkFBcUI7QUFBQTtBQUV0QztB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
package/package.json CHANGED
@@ -1,10 +1,35 @@
1
1
  {
2
- "name": "@archont561/qgis-sdk-bridge",
3
- "version": "0.0.0",
4
- "description": "OIDC trusted publishing setup package for @archont561/qgis-sdk-bridge",
5
- "keywords": [
6
- "oidc",
7
- "trusted-publishing",
8
- "setup"
9
- ]
2
+ "name": "@archont561/qgis-sdk-bridge",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript bridge contracts and error primitives for QGIS SDK WebEngine plugin interfaces.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "default": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "README.md"
19
+ ],
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/Archont561/qgis-sdk.git",
23
+ "directory": "packages/qgis-sdk-bridge"
24
+ },
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "scripts": {
29
+ "build": "bunup",
30
+ "test": "bun test",
31
+ "coverage": "bun --cwd=../.. --config=bunfig.toml test --coverage packages/qgis-sdk-bridge/tests",
32
+ "typecheck": "tsc --noEmit",
33
+ "generate:contract-types": "json2ts -i 'tests/contracts/generated/schemas/*.json' -o tests/contracts/generated/types/ && json2ts -i 'tests/contracts/pydantic/generated/schemas/*.json' -o tests/contracts/pydantic/generated/types/"
34
+ }
10
35
  }