From e369992ed63f4295e030d1be0562cc9d16f160d9 Mon Sep 17 00:00:00 2001 From: Andreas Karlsson Date: Wed, 17 Sep 2025 04:22:37 +0200 Subject: [PATCH 1/3] feat: js local resolver --- .../confidence/flags/admin/v1/resolver.proto | 2 + openfeature-provider/js/.editorconfig | 10 + openfeature-provider/js/.gitattributes | 4 + openfeature-provider/js/.gitignore | 10 + openfeature-provider/js/.yarnrc.yml | 1 + openfeature-provider/js/README.md | 1 + openfeature-provider/js/package.json | 51 + openfeature-provider/js/proto/api.proto | 92 + openfeature-provider/js/proto/messages.proto | 14 + .../ConfidenceServerProviderLocal.e2e.test.ts | 98 + .../js/src/ConfidenceServerProviderLocal.ts | 286 ++ openfeature-provider/js/src/StateFetcher.ts | 0 .../js/src/WasmResolver.test.ts | 95 + openfeature-provider/js/src/WasmResolver.ts | 103 + openfeature-provider/js/src/index.browser.ts | 11 + openfeature-provider/js/src/index.node.ts | 14 + openfeature-provider/js/src/lease.ts | 24 + openfeature-provider/js/src/wasm.d.ts | 5 + openfeature-provider/js/tsconfig.json | 12 + openfeature-provider/js/tsdown.config.ts | 25 + openfeature-provider/js/vitest.config.ts | 30 + openfeature-provider/js/yarn.lock | 2589 +++++++++++++++++ wasm-msg/src/sync.rs | 6 +- wasm/node-host/src/index.ts | 8 +- 24 files changed, 3487 insertions(+), 4 deletions(-) create mode 100644 openfeature-provider/js/.editorconfig create mode 100644 openfeature-provider/js/.gitattributes create mode 100644 openfeature-provider/js/.gitignore create mode 100644 openfeature-provider/js/.yarnrc.yml create mode 100644 openfeature-provider/js/README.md create mode 100644 openfeature-provider/js/package.json create mode 100644 openfeature-provider/js/proto/api.proto create mode 100644 openfeature-provider/js/proto/messages.proto create mode 100644 openfeature-provider/js/src/ConfidenceServerProviderLocal.e2e.test.ts create mode 100644 openfeature-provider/js/src/ConfidenceServerProviderLocal.ts create mode 100644 openfeature-provider/js/src/StateFetcher.ts create mode 100644 openfeature-provider/js/src/WasmResolver.test.ts create mode 100644 openfeature-provider/js/src/WasmResolver.ts create mode 100644 openfeature-provider/js/src/index.browser.ts create mode 100644 openfeature-provider/js/src/index.node.ts create mode 100644 openfeature-provider/js/src/lease.ts create mode 100644 openfeature-provider/js/src/wasm.d.ts create mode 100644 openfeature-provider/js/tsconfig.json create mode 100644 openfeature-provider/js/tsdown.config.ts create mode 100644 openfeature-provider/js/vitest.config.ts create mode 100644 openfeature-provider/js/yarn.lock diff --git a/confidence-resolver/protos/confidence/flags/admin/v1/resolver.proto b/confidence-resolver/protos/confidence/flags/admin/v1/resolver.proto index 8e44a1f..5657e71 100644 --- a/confidence-resolver/protos/confidence/flags/admin/v1/resolver.proto +++ b/confidence-resolver/protos/confidence/flags/admin/v1/resolver.proto @@ -56,6 +56,8 @@ message ResolverStateUriResponse { string signed_uri = 1; // At what time the state uri expires google.protobuf.Timestamp expire_time = 2; + // The account the referenced state belongs to + string account = 3; } // Request to get the resolver state for the whole account diff --git a/openfeature-provider/js/.editorconfig b/openfeature-provider/js/.editorconfig new file mode 100644 index 0000000..1ed453a --- /dev/null +++ b/openfeature-provider/js/.editorconfig @@ -0,0 +1,10 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true + +[*.{js,json,yml}] +charset = utf-8 +indent_style = space +indent_size = 2 diff --git a/openfeature-provider/js/.gitattributes b/openfeature-provider/js/.gitattributes new file mode 100644 index 0000000..af3ad12 --- /dev/null +++ b/openfeature-provider/js/.gitattributes @@ -0,0 +1,4 @@ +/.yarn/** linguist-vendored +/.yarn/releases/* binary +/.yarn/plugins/**/* binary +/.pnp.* binary linguist-generated diff --git a/openfeature-provider/js/.gitignore b/openfeature-provider/js/.gitignore new file mode 100644 index 0000000..85bc4ad --- /dev/null +++ b/openfeature-provider/js/.gitignore @@ -0,0 +1,10 @@ +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions +node_modules/ +src/proto/ +dist/ +.env.test \ No newline at end of file diff --git a/openfeature-provider/js/.yarnrc.yml b/openfeature-provider/js/.yarnrc.yml new file mode 100644 index 0000000..3186f3f --- /dev/null +++ b/openfeature-provider/js/.yarnrc.yml @@ -0,0 +1 @@ +nodeLinker: node-modules diff --git a/openfeature-provider/js/README.md b/openfeature-provider/js/README.md new file mode 100644 index 0000000..d7d07d1 --- /dev/null +++ b/openfeature-provider/js/README.md @@ -0,0 +1 @@ +# js diff --git a/openfeature-provider/js/package.json b/openfeature-provider/js/package.json new file mode 100644 index 0000000..9b5cb33 --- /dev/null +++ b/openfeature-provider/js/package.json @@ -0,0 +1,51 @@ +{ + "name": "@spotify-confidence/openfeature-server-provider-local", + "version": "0.0.0", + "private": true, + "description": "Spotify Condfidence Open Feature provider", + "type": "module", + "files": [ + "dist" + ], + "main": "./dist/index.node.js", + "module": "./dist/index.browser.js", + "types": "./dist/index.node.d.ts", + "exports": { + ".": { + "node": { + "types": "./dist/index.node.d.ts", + "default": "./dist/index.node.js" + }, + "browser": { + "types": "./dist/index.browser.d.ts", + "default": "./dist/index.browser.js" + }, + "default": { + "types": "./dist/index.node.d.ts", + "default": "./dist/index.node.js" + } + }, + "./package.json": "./package.json" + }, + "scripts": { + "build": "tsdown", + "dev": "tsdown --watch", + "test": "vitest", + "proto:gen": "mkdir -p src/proto && rm -rf src/proto/* && protoc --plugin=node_modules/.bin/protoc-gen-ts_proto --ts_proto_opt useOptionals=messages --ts_proto_opt esModuleInterop=true --ts_proto_out src/proto -Iproto api.proto messages.proto" + }, + "devDependencies": { + "@openfeature/core": "^1.9.0", + "@openfeature/server-sdk": "^1.19.0", + "@types/node": "^24.0.1", + "@vitest/coverage-v8": "^3.2.4", + "dotenv": "^17.2.2", + "rolldown": "1.0.0-beta.38", + "ts-proto": "^2.7.3", + "tsdown": "latest", + "vitest": "^3.2.4" + }, + "peerDependencies": { + "@openfeature/server-sdk": "^1.19.0" + }, + "packageManager": "yarn@4.6.0" +} diff --git a/openfeature-provider/js/proto/api.proto b/openfeature-provider/js/proto/api.proto new file mode 100644 index 0000000..0d2f5c8 --- /dev/null +++ b/openfeature-provider/js/proto/api.proto @@ -0,0 +1,92 @@ +syntax = "proto3"; + +import "google/protobuf/struct.proto"; +import "google/protobuf/timestamp.proto"; + +message ResolveFlagsRequest { + // If non-empty, the specific flags are resolved, otherwise all flags + // available to the client will be resolved. + repeated string flags = 1; + + // An object that contains data used in the flag resolve. For example, + // the targeting key e.g. the id of the randomization unit, other attributes + // like country or version that are used for targeting. + google.protobuf.Struct evaluation_context = 2; + + // Credentials for the client. It is used to identify the client and find + // the flags that are available to it. + string client_secret = 3; + + // Determines whether the flags should be applied directly as part of the + // resolve, or delayed until `ApplyFlag` is called. A flag is typically + // applied when it is used, if this occurs much later than the resolve, then + // `apply` should likely be set to false. + bool apply = 4; + + // Information about the SDK used to initiate the request. + // Sdk sdk = 5; +} + +message ResolveFlagsResponse { + // The list of all flags that could be resolved. Note: if any flag was + // archived it will not be included in this list. + repeated ResolvedFlag resolved_flags = 1; + + // An opaque token that is used when `apply` is set to false in `ResolveFlags`. + // When `apply` is set to false, the token must be passed to `ApplyFlags`. + bytes resolve_token = 2; + + // Unique identifier for this particular resolve request. + string resolve_id = 3; +} + + +message ResolvedFlag { + // The id of the flag that as resolved. + string flag = 1; + + // The id of the resolved variant has the format `flags/abc/variants/xyz`. + string variant = 2; + + // The value corresponding to the variant. It will always be a json object, + // for example `{ "color": "red", "size": 12 }`. + google.protobuf.Struct value = 3; + + // The schema of the value that was returned. For example: + // ``` + // { + // "schema": { + // "color": { "stringSchema": {} }, + // "size": { "intSchema": {} } + // } + // } + // ``` + // types.v1.FlagSchema.StructFlagSchema flag_schema = 4; + + // The reason to why the flag could be resolved or not. + ResolveReason reason = 5; +} + + +enum ResolveReason { + // Unspecified enum. + RESOLVE_REASON_UNSPECIFIED = 0; + // The flag was successfully resolved because one rule matched. + RESOLVE_REASON_MATCH = 1; + // The flag could not be resolved because no rule matched. + RESOLVE_REASON_NO_SEGMENT_MATCH = 2; + // The flag could not be resolved because the matching rule had no variant + // that could be assigned. + RESOLVE_REASON_NO_TREATMENT_MATCH = 3 [deprecated = true]; + // The flag could not be resolved because it was archived. + RESOLVE_REASON_FLAG_ARCHIVED = 4; + // The flag could not be resolved because the targeting key field was invalid + RESOLVE_REASON_TARGETING_KEY_ERROR = 5; + // Unknown error occurred during the resolve + RESOLVE_REASON_ERROR = 6; +} + +message SetResolverStateRequest { + bytes state = 1; + string account_id = 2; +} diff --git a/openfeature-provider/js/proto/messages.proto b/openfeature-provider/js/proto/messages.proto new file mode 100644 index 0000000..191f941 --- /dev/null +++ b/openfeature-provider/js/proto/messages.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +message Void {} + +message Request { + bytes data = 1; +} + +message Response { + oneof result { + bytes data = 1; + string error = 2; + } +} diff --git a/openfeature-provider/js/src/ConfidenceServerProviderLocal.e2e.test.ts b/openfeature-provider/js/src/ConfidenceServerProviderLocal.e2e.test.ts new file mode 100644 index 0000000..42f7729 --- /dev/null +++ b/openfeature-provider/js/src/ConfidenceServerProviderLocal.e2e.test.ts @@ -0,0 +1,98 @@ +import { afterAll, beforeAll, describe, expect, it } from 'vitest'; +import { OpenFeature } from '@openfeature/server-sdk'; +import { ConfidenceServerProviderLocal } from './ConfidenceServerProviderLocal'; +import { readFileSync } from 'node:fs'; +import { WasmResolver } from './WasmResolver'; + +const { + CONFIDENCE_API_CLIENT_ID, + CONFIDENCE_API_CLIENT_SECRET, +} = requireEnv('CONFIDENCE_API_CLIENT_ID', 'CONFIDENCE_API_CLIENT_SECRET'); + +const moduleBytes = readFileSync(__dirname + '/../../../wasm/confidence_resolver.wasm'); +const module = new WebAssembly.Module(moduleBytes); +const resolver = await WasmResolver.load(module); +const confidenceProvider = new ConfidenceServerProviderLocal(resolver, { + clientKey: 'RxDVTrXvc6op1XxiQ4OaR31dKbJ39aYV', + clientId: CONFIDENCE_API_CLIENT_ID, + clientSecret: CONFIDENCE_API_CLIENT_SECRET +}); + +describe('ConfidenceServerProvider E2E tests', () => { + beforeAll( async () => { + + await OpenFeature.setProviderAndWait(confidenceProvider); + OpenFeature.setContext({ + targetingKey: 'test-a', // control + }); + }); + + afterAll(() => OpenFeature.close()) + + it('should resolve a boolean e2e', async () => { + const client = OpenFeature.getClient(); + + expect(await client.getBooleanValue('web-sdk-e2e-flag.bool', true)).toBeFalsy(); + }); + + it('should resolve an int', async () => { + const client = OpenFeature.getClient(); + + expect(await client.getNumberValue('web-sdk-e2e-flag.int', 10)).toEqual(3); + }); + + it('should resolve a double', async () => { + const client = OpenFeature.getClient(); + + expect(await client.getNumberValue('web-sdk-e2e-flag.double', 10)).toEqual(3.5); + }); + + it('should resolve a string', async () => { + const client = OpenFeature.getClient(); + + expect(await client.getStringValue('web-sdk-e2e-flag.str', 'default')).toEqual('control'); + }); + + it('should resolve a struct', async () => { + const client = OpenFeature.getClient(); + const expectedObject = { + int: 4, + str: 'obj control', + bool: false, + double: 3.6, + ['obj-obj']: {}, + }; + + expect(await client.getObjectValue('web-sdk-e2e-flag.obj', {})).toEqual(expectedObject); + }); + + it('should resolve a sub value from a struct', async () => { + const client = OpenFeature.getClient(); + + expect(await client.getBooleanValue('web-sdk-e2e-flag.obj.bool', true)).toBeFalsy(); + }); + + it('should resolve a sub value from a struct with details with resolve token for client side apply call', async () => { + const client = OpenFeature.getClient(); + const expectedObject = { + flagKey: 'web-sdk-e2e-flag.obj.double', + reason: 'MATCH', + variant: 'flags/web-sdk-e2e-flag/variants/control', + flagMetadata: {}, + value: 3.6, + }; + + expect(await client.getNumberDetails('web-sdk-e2e-flag.obj.double', 1)).toEqual(expectedObject); + }); +}); + +function requireEnv(...names:N): Record { + return names.reduce((acc, name) => { + const value = process.env[name]; + if(!value) throw new Error(`Missing environment variable ${name}`) + return { + ...acc, + [name]: value + }; + }, {}) as Record; +} \ No newline at end of file diff --git a/openfeature-provider/js/src/ConfidenceServerProviderLocal.ts b/openfeature-provider/js/src/ConfidenceServerProviderLocal.ts new file mode 100644 index 0000000..bdc6c66 --- /dev/null +++ b/openfeature-provider/js/src/ConfidenceServerProviderLocal.ts @@ -0,0 +1,286 @@ +import { + ErrorCode, + EvaluationContext, + JsonValue, + Provider, + ProviderMetadata, + ProviderStatus, + ResolutionDetails, + ResolutionReason, + OpenFeature +} from '@openfeature/server-sdk'; +import { WasmResolver } from './WasmResolver'; +import { CachedProvider, Lease, leaseFactory } from './lease'; +import { ResolveReason } from './proto/api'; + +const DEFAULT_STATE_INTERVAL = 10_000; +const DEFAULT_FLUSH_INTERVAL = 10_000; +export interface ProviderOptions { + clientKey:string, + clientId:string, + clientSecret:string, + stateUpdateInterval?:number, + flushInterval?:number, +} + +interface AccessToken { + accessToken: string, + /// lifetime seconds + expiresIn: number +} + +interface ResolveStateUri { + signedUri:string, + expireTime:string, + account: string, +} + +/** + * OpenFeature Provider for Confidence Server SDK (Local Mode) + * @public + */ +export class ConfidenceServerProviderLocal implements Provider { + /** Static data about the provider */ + readonly metadata: ProviderMetadata = { + name: 'ConfidenceServerProviderLocal', + }; + /** Current status of the provider. Can be READY, NOT_READY, ERROR, STALE and FATAL. */ + status: ProviderStatus = ProviderStatus.NOT_READY; + + private tokenProvider:CachedProvider; + private stateUriProvider:CachedProvider<{ signedUri:string, account:string }>; + private flushInterval?:NodeJS.Timeout; + private stateInterval?:NodeJS.Timeout; + private stateEtag:string | null = null; + + + constructor(private resolver:WasmResolver, private options:ProviderOptions) { + // TODO better error handling + // TODO validate options + this.tokenProvider = leaseFactory(async () => { + const { accessToken, expiresIn } = await this.fetchToken(); + return [accessToken, new Date(Date.now() + 1000*expiresIn)] + }); + this.stateUriProvider = leaseFactory(async () => { + const { signedUri, account, expireTime } = await this.fetchResolveStateUri(); + return [{signedUri, account}, new Date(expireTime)]; + }); + } + + async initialize(context?: EvaluationContext): Promise { + await this.updateState(); + this.flushInterval = setInterval(() => this.flush(), this.options.flushInterval ?? DEFAULT_FLUSH_INTERVAL); + if(typeof this.flushInterval.unref === 'function') { + this.flushInterval.unref(); + } + this.stateInterval = setInterval(() => this.updateState(), this.options.stateUpdateInterval ?? DEFAULT_STATE_INTERVAL); + if(typeof this.stateInterval.unref === 'function') { + this.stateInterval.unref(); + } + this.status = ProviderStatus.READY; + } + + onClose(): Promise { + clearInterval(this.flushInterval); + clearInterval(this.stateInterval); + return this.flush(); + } + + evaluate(flagKey: string, defaultValue: T, context: EvaluationContext): ResolutionDetails { + + const [flagName, ...path] = flagKey.split('.') + const { resolvedFlags: [flag]} = this.resolver.resolveFlags({ + flags: [`flags/${flagName}`], + evaluationContext: ConfidenceServerProviderLocal.convertEvaluationContext(context), + apply: true, + clientSecret: this.options.clientKey + }); + if(!flag) { + return { + value: defaultValue, + reason: 'ERROR', + errorCode: ErrorCode.FLAG_NOT_FOUND + } + } + if(flag.reason != ResolveReason.RESOLVE_REASON_MATCH) { + return { + value: defaultValue, + reason: ConfidenceServerProviderLocal.convertReson(flag.reason), + } + } + let value:unknown = flag.value; + for(const step of path) { + if(typeof value !== 'object' || value === null || !hasKey(value, step)) { + return { + value: defaultValue, + reason: 'ERROR', + errorCode: ErrorCode.TYPE_MISMATCH + } + } + value = value[step]; + } + if(!valueMatchesSchema(value, defaultValue)) { + return { + value: defaultValue, + reason: 'ERROR', + errorCode: ErrorCode.TYPE_MISMATCH + } + } + return { + value, + reason: 'MATCH', + variant: flag.variant + }; + } + + async updateState() { + const { signedUri, account } = await this.stateUriProvider(); + const req = new Request(signedUri); + if(this.stateEtag) { + req.headers.set('If-None-Match', this.stateEtag); + } + const resp = await fetch(req); + if(resp.status === 304) { + // not changed + return; + } + if(!resp.ok) { + throw new Error(`Failed to fetch state: ${resp.status} ${resp.statusText}`); + } + this.stateEtag = resp.headers.get('etag'); + const state = new Uint8Array(await resp.arrayBuffer()); + this.resolver.setResolverState({ + accountId: account, + state + }) + } + + async flush() { + const writeFlagLogRequest = this.resolver.flushLogs(); + if(writeFlagLogRequest.length == 0) { + // nothing to send + return; + } + const resp = await fetch('https://resolver.confidence.dev/v1/flagLogs:write', { + method: 'post', + headers: { + 'Content-Type': 'application/x-protobuf', + 'Authorization': `Bearer ${await this.tokenProvider()}` + }, + body: writeFlagLogRequest as Uint8Array + }); + if(resp.ok) { + } else { + } + } + + private async fetchResolveStateUri():Promise { + const resp = await fetch('https://flags.confidence.dev/v1/resolverState:resolverStateUri', { + headers: { + 'Authorization': `Bearer ${await this.tokenProvider()}` + } + }); + if(!resp.ok) { + throw new Error('Failed to get resolve state url'); + } + return resp.json(); + } + + private async fetchToken():Promise { + const resp = await fetch('https://iam.confidence.dev/v1/oauth/token', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + clientId: this.options.clientId, + clientSecret: this.options.clientSecret, + grantType: 'client_credentials' + }) + }) + if(!resp.ok) { + throw new Error('Failed to fetch access token'); + } + return resp.json(); + } + + private static convertReson(reason:ResolveReason):ResolutionReason { + switch(reason) { + case ResolveReason.RESOLVE_REASON_ERROR: + return 'ERROR'; + case ResolveReason.RESOLVE_REASON_FLAG_ARCHIVED: + return 'FLAG_ARCHIVED'; + case ResolveReason.RESOLVE_REASON_MATCH: + return 'MATCH'; + case ResolveReason.RESOLVE_REASON_NO_SEGMENT_MATCH: + return 'NO_SEGMENT_MATCH'; + case ResolveReason.RESOLVE_REASON_TARGETING_KEY_ERROR: + return 'TARGETING_KEY_ERROR'; + case ResolveReason.RESOLVE_REASON_NO_TREATMENT_MATCH: + return 'NO_TREATMENT_MATCH'; + default: + return 'UNSPECIFIED' + } + } + + private static convertEvaluationContext({ targetingKey:targeting_key, ...rest}:EvaluationContext): { [key: string]: any } { + return { + targeting_key, ...rest + } + } + + /** Resolves with an evaluation of a Boolean flag */ + resolveBooleanEvaluation( + flagKey: string, + defaultValue: boolean, + context: EvaluationContext, + ): Promise> { + return Promise.resolve(this.evaluate(flagKey, defaultValue, context)); + } + /** Resolves with an evaluation of a Numbers flag */ + resolveNumberEvaluation( + flagKey: string, + defaultValue: number, + context: EvaluationContext, + ): Promise> { + return Promise.resolve(this.evaluate(flagKey, defaultValue, context)); + } + /** Resolves with an evaluation of an Object flag */ + resolveObjectEvaluation( + flagKey: string, + defaultValue: T, + context: EvaluationContext, + ): Promise> { + return Promise.resolve(this.evaluate(flagKey, defaultValue, context)); + } + /** Resolves with an evaluation of a String flag */ + resolveStringEvaluation( + flagKey: string, + defaultValue: string, + context: EvaluationContext, + ): Promise> { + return Promise.resolve(this.evaluate(flagKey, defaultValue, context)); + } +} + +function hasKey(obj:object, key:K): obj is { [P in K]: unknown } { + return key in obj; +} + +function valueMatchesSchema(value:unknown, schema:T): value is T { + if(typeof schema !== typeof value) return false; + if(typeof value === 'object' && typeof schema === 'object') { + if(schema === null) return value === null; + if(Array.isArray(schema)) { + if(!Array.isArray(value)) return false; + if(schema.length == 0) return true; + return value.every(item => valueMatchesSchema(item, schema[0])); + } + for(const [key, schemaValue] of Object.entries(schema)) { + if(!hasKey(value!, key)) return false; + if(!valueMatchesSchema(value[key], schemaValue)) return false; + } + } + return true; +} + diff --git a/openfeature-provider/js/src/StateFetcher.ts b/openfeature-provider/js/src/StateFetcher.ts new file mode 100644 index 0000000..e69de29 diff --git a/openfeature-provider/js/src/WasmResolver.test.ts b/openfeature-provider/js/src/WasmResolver.test.ts new file mode 100644 index 0000000..b81293a --- /dev/null +++ b/openfeature-provider/js/src/WasmResolver.test.ts @@ -0,0 +1,95 @@ +import { beforeEach, describe, expect, it, test } from 'vitest'; +import { WasmResolver } from './WasmResolver'; +import { readFileSync } from 'node:fs'; +import { ResolveReason } from './proto/api'; +import { spawnSync } from 'node:child_process'; +import { error } from 'node:console'; +import { stderr } from 'node:process'; + +const moduleBytes = readFileSync(__dirname + '/../../../wasm/confidence_resolver.wasm'); +const stateBytes = readFileSync(__dirname + '/../../../wasm/resolver_state.pb'); + +const CLIENT_SECRET = 'mkjJruAATQWjeY7foFIWfVAcBWnci2YF'; + +let wasmResolver: WasmResolver; +beforeEach(async () => { + wasmResolver = await WasmResolver.load(new WebAssembly.Module(moduleBytes)); +}); + +it('should fail to resolve without state', () => { + expect(() => { + wasmResolver.resolveFlags({ flags: [], clientSecret: 'xyz', apply: false }); + }).toThrowError('Resolver state not set'); +}); + +describe('with state', () => { + beforeEach(() => { + wasmResolver.setResolverState({ state: stateBytes, accountId: 'confidence-test' }); + }); + + it('should resolve flags', () => { + try { + const resp = wasmResolver.resolveFlags({ + flags: ['flags/tutorial-feature'], + clientSecret: CLIENT_SECRET, + apply: true, + evaluationContext: { + targeting_key: 'tutorial_visitor', + visitor_id: 'tutorial_visitor', + }, + }); + + expect(resp).toMatchObject({ + resolvedFlags: [ + { + reason: ResolveReason.RESOLVE_REASON_MATCH, + }, + ], + }); + } catch (e) { + console.log('yo', e); + } + }); + + describe('flushLogs', () => { + + it('should be empty before any resolve', () => { + const logs = wasmResolver.flushLogs(); + expect(logs.length).toBe(0); + }) + + it('should contain logs after a resolve', () => { + wasmResolver.resolveFlags({ + flags: ['flags/tutorial-feature'], + clientSecret: CLIENT_SECRET, + apply: true, + evaluationContext: { + targeting_key: 'tutorial_visitor', + visitor_id: 'tutorial_visitor', + }, + }); + + const decoded = decodeBuffer(wasmResolver.flushLogs()); + + expect(decoded).contains('flag_assigned'); + expect(decoded).contains('client_resolve_info'); + expect(decoded).contains('flag_resolve_info'); + }) + }) +}); + + +function decodeBuffer(input:Uint8Array):string { + const res = spawnSync('protoc',[ + `-I${__dirname}/../../../confidence-resolver/protos`, + `--decode=confidence.flags.resolver.v1.WriteFlagLogsRequest`, + `confidence/flags/resolver/v1/internal_api.proto` + ], { input, encoding: 'utf8' }); + if(res.error) { + throw res.error; + } + if(res.status !== 0) { + throw new Error(res.stderr) + } + return res.stdout; +} \ No newline at end of file diff --git a/openfeature-provider/js/src/WasmResolver.ts b/openfeature-provider/js/src/WasmResolver.ts new file mode 100644 index 0000000..d53fe01 --- /dev/null +++ b/openfeature-provider/js/src/WasmResolver.ts @@ -0,0 +1,103 @@ +import { BinaryWriter } from '@bufbuild/protobuf/wire'; +import { Request, Response, Void } from './proto/messages'; +import { Timestamp } from './proto/google/protobuf/timestamp'; +import { ResolveFlagsRequest, ResolveFlagsResponse, SetResolverStateRequest } from './proto/api'; + +type Codec = { + encode(message: T): BinaryWriter; + decode(input: Uint8Array): T; +}; + +export class WasmResolver { + private exports: any; + private imports: any; + + private constructor() { + this.imports = { + wasm_msg: { + wasm_msg_host_current_time: () => { + const ptr = this.transferRequest({ seconds: Date.now(), nanos: 0 }, Timestamp); + return ptr; + }, + }, + }; + } + + resolveFlags(request: ResolveFlagsRequest): ResolveFlagsResponse { + const reqPtr = this.transferRequest(request, ResolveFlagsRequest); + const resPtr = this.exports.wasm_msg_guest_resolve(reqPtr); + return this.consumeResponse(resPtr, ResolveFlagsResponse); + } + + setResolverState(request: SetResolverStateRequest): void { + const reqPtr = this.transferRequest(request, SetResolverStateRequest); + const resPtr = this.exports.wasm_msg_guest_set_resolver_state(reqPtr); + this.consumeResponse(resPtr, Void); + } + + flushLogs():Uint8Array { + const resPtr = this.exports.wasm_msg_guest_flush_logs(0); + const {data, error} = this.consume(resPtr, Response); + if(error) { + throw new Error(error); + } + return data!; + } + + private transferRequest(value: T, codec: Codec): number { + const data = codec.encode(value).finish(); + return this.transfer({ data }, Request); + } + + // private transferResponseSuccess(value: T, codec: Codec): number { + // const data = codec.encode(value).finish(); + // return this.transfer({ data }, Response); + // } + // private transferResponseError(error: string): number { + // return this.transfer({ error }, Response); + // } + + // private consumeRequest(ptr: number, codec: Codec): T { + // const req: Request = this.consume(ptr, Request); + // return codec.decode(req.data); + // } + + private consumeResponse(ptr: number, codec: Codec): T { + const { data, error }: Response = this.consume(ptr, Response); + if (error) { + throw new Error(error); + } + return codec.decode(data!); + } + + private transfer(data: T, codec: Codec): number { + const encoded = codec.encode(data).finish(); + const ptr = this.exports.wasm_msg_alloc(encoded.length); + this.viewBuffer(ptr).set(encoded); + return ptr; + } + + private consume(ptr: number, codec: Codec): T { + const data = this.viewBuffer(ptr); + const res = codec.decode(data); + this.free(ptr); + return res; + } + + private viewBuffer(ptr: number): Uint8Array { + const size = new DataView(this.exports.memory.buffer).getUint32(ptr - 4, true); + const data = new Uint8Array(this.exports.memory.buffer, ptr, size - 4); + return data; + } + + private free(ptr: number) { + this.exports.wasm_msg_free(ptr); + } + + static async load(module: WebAssembly.Module): Promise { + const wasmResolver = new WasmResolver(); + const instance = await WebAssembly.instantiate(module, wasmResolver.imports); + wasmResolver.exports = instance.exports; + return wasmResolver; + } +} diff --git a/openfeature-provider/js/src/index.browser.ts b/openfeature-provider/js/src/index.browser.ts new file mode 100644 index 0000000..6374e61 --- /dev/null +++ b/openfeature-provider/js/src/index.browser.ts @@ -0,0 +1,11 @@ +import { ConfidenceServerProviderLocal, ProviderOptions } from './ConfidenceServerProviderLocal'; +import { WasmResolver } from './WasmResolver'; + +const wasmUrl = new URL('confidence_resolver.wasm', import.meta.url); + +const module = await WebAssembly.compileStreaming(fetch(wasmUrl)); +const resolver = await WasmResolver.load(module); + +export function createConfidenceServerProvider(options:ProviderOptions):ConfidenceServerProviderLocal { + return new ConfidenceServerProviderLocal(resolver, options) +} \ No newline at end of file diff --git a/openfeature-provider/js/src/index.node.ts b/openfeature-provider/js/src/index.node.ts new file mode 100644 index 0000000..ac2d6b0 --- /dev/null +++ b/openfeature-provider/js/src/index.node.ts @@ -0,0 +1,14 @@ +import fs from 'node:fs/promises' +import { fileURLToPath } from 'node:url'; +import { ConfidenceServerProviderLocal, ProviderOptions } from './ConfidenceServerProviderLocal'; +import { WasmResolver } from './WasmResolver'; + +const wasmUrl = new URL('confidence_resolver.wasm', import.meta.url); +const buffer = await fs.readFile(fileURLToPath(wasmUrl)); + +const module = await WebAssembly.compile(buffer as BufferSource); +const resolver = await WasmResolver.load(module); + +export function createConfidenceServerProvider(options:ProviderOptions):ConfidenceServerProviderLocal { + return new ConfidenceServerProviderLocal(resolver, options) +} \ No newline at end of file diff --git a/openfeature-provider/js/src/lease.ts b/openfeature-provider/js/src/lease.ts new file mode 100644 index 0000000..dbf94a4 --- /dev/null +++ b/openfeature-provider/js/src/lease.ts @@ -0,0 +1,24 @@ + +export type Lease = [value:T, expiry:Date]; + + +export type CachedProvider = () => Promise + +export function leaseFactory(renewer:() => Promise>, marginMs = 5000):CachedProvider { + let current:Lease | null = null; + return async () => { + if(!current || isExpired(current)) { + const [value, expiry] = await renewer(); + current = [value, subtractMargin(expiry, marginMs)]; + } + return current[0]; + } +} + +function subtractMargin(expiry:Date, marginMs: number):Date { + return new Date(expiry.valueOf() - marginMs) +} + +function isExpired(lease:Lease):boolean { + return lease[1] < new Date(); +} \ No newline at end of file diff --git a/openfeature-provider/js/src/wasm.d.ts b/openfeature-provider/js/src/wasm.d.ts new file mode 100644 index 0000000..61c514f --- /dev/null +++ b/openfeature-provider/js/src/wasm.d.ts @@ -0,0 +1,5 @@ + +declare module "*.wasm" { + const content: string; + export default content; +} diff --git a/openfeature-provider/js/tsconfig.json b/openfeature-provider/js/tsconfig.json new file mode 100644 index 0000000..c76221d --- /dev/null +++ b/openfeature-provider/js/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "types": ["node"] + }, + "include": ["src/**/*"], +} diff --git a/openfeature-provider/js/tsdown.config.ts b/openfeature-provider/js/tsdown.config.ts new file mode 100644 index 0000000..f2fd855 --- /dev/null +++ b/openfeature-provider/js/tsdown.config.ts @@ -0,0 +1,25 @@ +import { defineConfig } from 'tsdown' + + +const base = defineConfig({ + dts: { + oxc: true, + }, + external: ['@bufbuild/protobuf/wire'], + // inputOptions: { + // moduleTypes: { + // '.wasm':'asset' + // } + // }, +}); + +export default defineConfig([{ + entry: './src/index.node.ts', + platform: 'node', + copy: ['../../wasm/confidence_resolver.wasm'], + ...base +},{ + entry: './src/index.browser.ts', + platform: 'browser', + ...base +}]) diff --git a/openfeature-provider/js/vitest.config.ts b/openfeature-provider/js/vitest.config.ts new file mode 100644 index 0000000..1c133e2 --- /dev/null +++ b/openfeature-provider/js/vitest.config.ts @@ -0,0 +1,30 @@ +import { defineConfig } from 'vitest/config' +import { config, parse } from 'dotenv'; +import { existsSync, readFileSync } from 'fs'; + + +export default defineConfig({ + test: { + environment: 'node', + globals: false, + include: ['src/**/*.{test,spec}.ts'], + silent: false, + watch: false, + env: { + ...readEnv('.env.test') + } + } +}) + +function readEnv(file):Record { + try { + const buf = readFileSync(file); + return parse(buf); + } catch(e) { + if(e.code === 'ENOENT') { + console.log('could not find', file); + return {}; + } + throw e; + } +} \ No newline at end of file diff --git a/openfeature-provider/js/yarn.lock b/openfeature-provider/js/yarn.lock new file mode 100644 index 0000000..e73ee66 --- /dev/null +++ b/openfeature-provider/js/yarn.lock @@ -0,0 +1,2589 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 8 + cacheKey: 10c0 + +"@ampproject/remapping@npm:^2.3.0": + version: 2.3.0 + resolution: "@ampproject/remapping@npm:2.3.0" + dependencies: + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.24" + checksum: 10c0/81d63cca5443e0f0c72ae18b544cc28c7c0ec2cea46e7cb888bb0e0f411a1191d0d6b7af798d54e30777d8d1488b2ec0732aac2be342d3d7d3ffd271c6f489ed + languageName: node + linkType: hard + +"@babel/generator@npm:^7.28.3": + version: 7.28.3 + resolution: "@babel/generator@npm:7.28.3" + dependencies: + "@babel/parser": "npm:^7.28.3" + "@babel/types": "npm:^7.28.2" + "@jridgewell/gen-mapping": "npm:^0.3.12" + "@jridgewell/trace-mapping": "npm:^0.3.28" + jsesc: "npm:^3.0.2" + checksum: 10c0/0ff58bcf04f8803dcc29479b547b43b9b0b828ec1ee0668e92d79f9e90f388c28589056637c5ff2fd7bcf8d153c990d29c448d449d852bf9d1bc64753ca462bc + languageName: node + linkType: hard + +"@babel/helper-string-parser@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-string-parser@npm:7.27.1" + checksum: 10c0/8bda3448e07b5583727c103560bcf9c4c24b3c1051a4c516d4050ef69df37bb9a4734a585fe12725b8c2763de0a265aa1e909b485a4e3270b7cfd3e4dbe4b602 + languageName: node + linkType: hard + +"@babel/helper-validator-identifier@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-validator-identifier@npm:7.27.1" + checksum: 10c0/c558f11c4871d526498e49d07a84752d1800bf72ac0d3dad100309a2eaba24efbf56ea59af5137ff15e3a00280ebe588560534b0e894a4750f8b1411d8f78b84 + languageName: node + linkType: hard + +"@babel/parser@npm:^7.25.4, @babel/parser@npm:^7.28.0, @babel/parser@npm:^7.28.3, @babel/parser@npm:^7.28.4": + version: 7.28.4 + resolution: "@babel/parser@npm:7.28.4" + dependencies: + "@babel/types": "npm:^7.28.4" + bin: + parser: ./bin/babel-parser.js + checksum: 10c0/58b239a5b1477ac7ed7e29d86d675cc81075ca055424eba6485872626db2dc556ce63c45043e5a679cd925e999471dba8a3ed4864e7ab1dbf64306ab72c52707 + languageName: node + linkType: hard + +"@babel/types@npm:^7.25.4, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4": + version: 7.28.4 + resolution: "@babel/types@npm:7.28.4" + dependencies: + "@babel/helper-string-parser": "npm:^7.27.1" + "@babel/helper-validator-identifier": "npm:^7.27.1" + checksum: 10c0/ac6f909d6191319e08c80efbfac7bd9a25f80cc83b43cd6d82e7233f7a6b9d6e7b90236f3af7400a3f83b576895bcab9188a22b584eb0f224e80e6d4e95f4517 + languageName: node + linkType: hard + +"@bcoe/v8-coverage@npm:^1.0.2": + version: 1.0.2 + resolution: "@bcoe/v8-coverage@npm:1.0.2" + checksum: 10c0/1eb1dc93cc17fb7abdcef21a6e7b867d6aa99a7ec88ec8207402b23d9083ab22a8011213f04b2cf26d535f1d22dc26139b7929e6c2134c254bd1e14ba5e678c3 + languageName: node + linkType: hard + +"@bufbuild/protobuf@npm:^2.0.0": + version: 2.8.0 + resolution: "@bufbuild/protobuf@npm:2.8.0" + checksum: 10c0/970faf0b58fd10c3c650224fda51f471b0f2005222fb33b43e6f8894478bc905b5a3bc0577cd7539afd7d2493fa6a6e588b89e67bdabd2750acf26cb40da237f + languageName: node + linkType: hard + +"@emnapi/core@npm:^1.5.0": + version: 1.5.0 + resolution: "@emnapi/core@npm:1.5.0" + dependencies: + "@emnapi/wasi-threads": "npm:1.1.0" + tslib: "npm:^2.4.0" + checksum: 10c0/52ba3485277706d92fa27d92b37e5b4f6ef0742c03ed68f8096f294c6bfa30f0752c82d4c2bfa14bff4dc30d63c9f71a8f9fb64a92743d00807d9e468fafd5ff + languageName: node + linkType: hard + +"@emnapi/runtime@npm:^1.5.0": + version: 1.5.0 + resolution: "@emnapi/runtime@npm:1.5.0" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/a85c9fc4e3af49cbe41e5437e5be2551392a931910cd0a5b5d3572532786927810c9cc1db11b232ec8f9657b33d4e6f7c4f985f1a052917d7cd703b5b2a20faa + languageName: node + linkType: hard + +"@emnapi/wasi-threads@npm:1.1.0": + version: 1.1.0 + resolution: "@emnapi/wasi-threads@npm:1.1.0" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/e6d54bf2b1e64cdd83d2916411e44e579b6ae35d5def0dea61a3c452d9921373044dff32a8b8473ae60c80692bdc39323e98b96a3f3d87ba6886b24dd0ef7ca1 + languageName: node + linkType: hard + +"@esbuild/aix-ppc64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/aix-ppc64@npm:0.25.9" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/android-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/android-arm64@npm:0.25.9" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/android-arm@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/android-arm@npm:0.25.9" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@esbuild/android-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/android-x64@npm:0.25.9" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/darwin-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/darwin-arm64@npm:0.25.9" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/darwin-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/darwin-x64@npm:0.25.9" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/freebsd-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/freebsd-arm64@npm:0.25.9" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/freebsd-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/freebsd-x64@npm:0.25.9" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/linux-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-arm64@npm:0.25.9" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/linux-arm@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-arm@npm:0.25.9" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@esbuild/linux-ia32@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-ia32@npm:0.25.9" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-loong64@npm:0.25.9" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-mips64el@npm:0.25.9" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-ppc64@npm:0.25.9" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-riscv64@npm:0.25.9" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-s390x@npm:0.25.9" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-x64@npm:0.25.9" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/netbsd-arm64@npm:0.25.9" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/netbsd-x64@npm:0.25.9" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/openbsd-arm64@npm:0.25.9" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/openbsd-x64@npm:0.25.9" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openharmony-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/openharmony-arm64@npm:0.25.9" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/sunos-x64@npm:0.25.9" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/win32-arm64@npm:0.25.9" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/win32-ia32@npm:0.25.9" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/win32-x64@npm:0.25.9" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + dependencies: + string-width: "npm:^5.1.2" + string-width-cjs: "npm:string-width@^4.2.0" + strip-ansi: "npm:^7.0.1" + strip-ansi-cjs: "npm:strip-ansi@^6.0.1" + wrap-ansi: "npm:^8.1.0" + wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" + checksum: 10c0/b1bf42535d49f11dc137f18d5e4e63a28c5569de438a221c369483731e9dac9fb797af554e8bf02b6192d1e5eba6e6402cf93900c3d0ac86391d00d04876789e + languageName: node + linkType: hard + +"@isaacs/fs-minipass@npm:^4.0.0": + version: 4.0.1 + resolution: "@isaacs/fs-minipass@npm:4.0.1" + dependencies: + minipass: "npm:^7.0.4" + checksum: 10c0/c25b6dc1598790d5b55c0947a9b7d111cfa92594db5296c3b907e2f533c033666f692a3939eadac17b1c7c40d362d0b0635dc874cbfe3e70db7c2b07cc97a5d2 + languageName: node + linkType: hard + +"@istanbuljs/schema@npm:^0.1.2": + version: 0.1.3 + resolution: "@istanbuljs/schema@npm:0.1.3" + checksum: 10c0/61c5286771676c9ca3eb2bd8a7310a9c063fb6e0e9712225c8471c582d157392c88f5353581c8c9adbe0dff98892317d2fdfc56c3499aa42e0194405206a963a + languageName: node + linkType: hard + +"@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.5": + version: 0.3.13 + resolution: "@jridgewell/gen-mapping@npm:0.3.13" + dependencies: + "@jridgewell/sourcemap-codec": "npm:^1.5.0" + "@jridgewell/trace-mapping": "npm:^0.3.24" + checksum: 10c0/9a7d65fb13bd9aec1fbab74cda08496839b7e2ceb31f5ab922b323e94d7c481ce0fc4fd7e12e2610915ed8af51178bdc61e168e92a8c8b8303b030b03489b13b + languageName: node + linkType: hard + +"@jridgewell/resolve-uri@npm:^3.1.0": + version: 3.1.2 + resolution: "@jridgewell/resolve-uri@npm:3.1.2" + checksum: 10c0/d502e6fb516b35032331406d4e962c21fe77cdf1cbdb49c6142bcbd9e30507094b18972778a6e27cbad756209cfe34b1a27729e6fa08a2eb92b33943f680cf1e + languageName: node + linkType: hard + +"@jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0, @jridgewell/sourcemap-codec@npm:^1.5.5": + version: 1.5.5 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.5" + checksum: 10c0/f9e538f302b63c0ebc06eecb1dd9918dd4289ed36147a0ddce35d6ea4d7ebbda243cda7b2213b6a5e1d8087a298d5cf630fb2bd39329cdecb82017023f6081a0 + languageName: node + linkType: hard + +"@jridgewell/trace-mapping@npm:^0.3.23, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.28, @jridgewell/trace-mapping@npm:^0.3.30": + version: 0.3.31 + resolution: "@jridgewell/trace-mapping@npm:0.3.31" + dependencies: + "@jridgewell/resolve-uri": "npm:^3.1.0" + "@jridgewell/sourcemap-codec": "npm:^1.4.14" + checksum: 10c0/4b30ec8cd56c5fd9a661f088230af01e0c1a3888d11ffb6b47639700f71225be21d1f7e168048d6d4f9449207b978a235c07c8f15c07705685d16dc06280e9d9 + languageName: node + linkType: hard + +"@napi-rs/wasm-runtime@npm:^1.0.5": + version: 1.0.5 + resolution: "@napi-rs/wasm-runtime@npm:1.0.5" + dependencies: + "@emnapi/core": "npm:^1.5.0" + "@emnapi/runtime": "npm:^1.5.0" + "@tybys/wasm-util": "npm:^0.10.1" + checksum: 10c0/8d29299933c57b6ead61f46fad5c3dfabc31e1356bbaf25c3a8ae57be0af0db0006a808f2c1bb16e28925e027f20e0856550dac94e015f56dd6ed53b38f9a385 + languageName: node + linkType: hard + +"@npmcli/agent@npm:^3.0.0": + version: 3.0.0 + resolution: "@npmcli/agent@npm:3.0.0" + dependencies: + agent-base: "npm:^7.1.0" + http-proxy-agent: "npm:^7.0.0" + https-proxy-agent: "npm:^7.0.1" + lru-cache: "npm:^10.0.1" + socks-proxy-agent: "npm:^8.0.3" + checksum: 10c0/efe37b982f30740ee77696a80c196912c274ecd2cb243bc6ae7053a50c733ce0f6c09fda085145f33ecf453be19654acca74b69e81eaad4c90f00ccffe2f9271 + languageName: node + linkType: hard + +"@npmcli/fs@npm:^4.0.0": + version: 4.0.0 + resolution: "@npmcli/fs@npm:4.0.0" + dependencies: + semver: "npm:^7.3.5" + checksum: 10c0/c90935d5ce670c87b6b14fab04a965a3b8137e585f8b2a6257263bd7f97756dd736cb165bb470e5156a9e718ecd99413dccc54b1138c1a46d6ec7cf325982fe5 + languageName: node + linkType: hard + +"@openfeature/core@npm:^1.9.0": + version: 1.9.0 + resolution: "@openfeature/core@npm:1.9.0" + checksum: 10c0/957ee82fff323850e5255e46eb91222b2ec364fce7e8dd8f1277e0b24c0f9464714f9793a9492ede5b5c4f1457f3bfec885a86122d3ee01bfe678ba6b6ddbc08 + languageName: node + linkType: hard + +"@openfeature/server-sdk@npm:^1.19.0": + version: 1.19.0 + resolution: "@openfeature/server-sdk@npm:1.19.0" + peerDependencies: + "@openfeature/core": ^1.9.0 + checksum: 10c0/3b0f2b63123323403d6b93326799c20a2f4ce80f8f39e834857b0685a3beb7a084f1ff316a469cbe006f69b9a4ff75deddf9fabd7ea8e25517c99081d0bfba8c + languageName: node + linkType: hard + +"@oxc-project/types@npm:=0.89.0": + version: 0.89.0 + resolution: "@oxc-project/types@npm:0.89.0" + checksum: 10c0/2e971397f32d28aef443b0863f915eb56bacb0d94ced10da0d8366e076c1a8f9284cbe107f03ad709b7ac65cd2ddfe4c13f754ddf214001f39f079126fa40622 + languageName: node + linkType: hard + +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 10c0/5bd7576bb1b38a47a7fc7b51ac9f38748e772beebc56200450c4a817d712232b8f1d3ef70532c80840243c657d491cf6a6be1e3a214cff907645819fdc34aadd + languageName: node + linkType: hard + +"@quansync/fs@npm:^0.1.5": + version: 0.1.5 + resolution: "@quansync/fs@npm:0.1.5" + dependencies: + quansync: "npm:^0.2.11" + checksum: 10c0/c7f8f654499240be450b23c308a484de87bebcd0a0c8291c1afda8908a4aafafe7bc1b50e43bed0ac82ec53712505be2fa71db60e992d9353fd8ac6e664bc157 + languageName: node + linkType: hard + +"@rolldown/binding-android-arm64@npm:1.0.0-beta.38": + version: 1.0.0-beta.38 + resolution: "@rolldown/binding-android-arm64@npm:1.0.0-beta.38" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@rolldown/binding-darwin-arm64@npm:1.0.0-beta.38": + version: 1.0.0-beta.38 + resolution: "@rolldown/binding-darwin-arm64@npm:1.0.0-beta.38" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@rolldown/binding-darwin-x64@npm:1.0.0-beta.38": + version: 1.0.0-beta.38 + resolution: "@rolldown/binding-darwin-x64@npm:1.0.0-beta.38" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@rolldown/binding-freebsd-x64@npm:1.0.0-beta.38": + version: 1.0.0-beta.38 + resolution: "@rolldown/binding-freebsd-x64@npm:1.0.0-beta.38" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@rolldown/binding-linux-arm-gnueabihf@npm:1.0.0-beta.38": + version: 1.0.0-beta.38 + resolution: "@rolldown/binding-linux-arm-gnueabihf@npm:1.0.0-beta.38" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@rolldown/binding-linux-arm64-gnu@npm:1.0.0-beta.38": + version: 1.0.0-beta.38 + resolution: "@rolldown/binding-linux-arm64-gnu@npm:1.0.0-beta.38" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@rolldown/binding-linux-arm64-musl@npm:1.0.0-beta.38": + version: 1.0.0-beta.38 + resolution: "@rolldown/binding-linux-arm64-musl@npm:1.0.0-beta.38" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@rolldown/binding-linux-x64-gnu@npm:1.0.0-beta.38": + version: 1.0.0-beta.38 + resolution: "@rolldown/binding-linux-x64-gnu@npm:1.0.0-beta.38" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@rolldown/binding-linux-x64-musl@npm:1.0.0-beta.38": + version: 1.0.0-beta.38 + resolution: "@rolldown/binding-linux-x64-musl@npm:1.0.0-beta.38" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@rolldown/binding-openharmony-arm64@npm:1.0.0-beta.38": + version: 1.0.0-beta.38 + resolution: "@rolldown/binding-openharmony-arm64@npm:1.0.0-beta.38" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@rolldown/binding-wasm32-wasi@npm:1.0.0-beta.38": + version: 1.0.0-beta.38 + resolution: "@rolldown/binding-wasm32-wasi@npm:1.0.0-beta.38" + dependencies: + "@napi-rs/wasm-runtime": "npm:^1.0.5" + conditions: cpu=wasm32 + languageName: node + linkType: hard + +"@rolldown/binding-win32-arm64-msvc@npm:1.0.0-beta.38": + version: 1.0.0-beta.38 + resolution: "@rolldown/binding-win32-arm64-msvc@npm:1.0.0-beta.38" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@rolldown/binding-win32-ia32-msvc@npm:1.0.0-beta.38": + version: 1.0.0-beta.38 + resolution: "@rolldown/binding-win32-ia32-msvc@npm:1.0.0-beta.38" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@rolldown/binding-win32-x64-msvc@npm:1.0.0-beta.38": + version: 1.0.0-beta.38 + resolution: "@rolldown/binding-win32-x64-msvc@npm:1.0.0-beta.38" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@rolldown/pluginutils@npm:1.0.0-beta.38": + version: 1.0.0-beta.38 + resolution: "@rolldown/pluginutils@npm:1.0.0-beta.38" + checksum: 10c0/8353ec2528349f79e27d1a3193806725b85830da334e935cbb606d88c1177c58ea6519c578e4e93e5f677f5b22aecb8738894dbed14603e14b6bffe3facf1002 + languageName: node + linkType: hard + +"@rollup/rollup-android-arm-eabi@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.50.2" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@rollup/rollup-android-arm64@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-android-arm64@npm:4.50.2" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-arm64@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-darwin-arm64@npm:4.50.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-x64@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-darwin-x64@npm:4.50.2" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-arm64@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.50.2" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-x64@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-freebsd-x64@npm:4.50.2" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-gnueabihf@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.50.2" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-musleabihf@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.50.2" + conditions: os=linux & cpu=arm & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-gnu@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.50.2" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-musl@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.50.2" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-loong64-gnu@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-loong64-gnu@npm:4.50.2" + conditions: os=linux & cpu=loong64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-ppc64-gnu@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.50.2" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-gnu@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.50.2" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-musl@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.50.2" + conditions: os=linux & cpu=riscv64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-s390x-gnu@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.50.2" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-gnu@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.50.2" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-musl@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.50.2" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-openharmony-arm64@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-openharmony-arm64@npm:4.50.2" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-arm64-msvc@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.50.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-ia32-msvc@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.50.2" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@rollup/rollup-win32-x64-msvc@npm:4.50.2": + version: 4.50.2 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.50.2" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@spotify-confidence/openfeature-server-provider-local@workspace:.": + version: 0.0.0-use.local + resolution: "@spotify-confidence/openfeature-server-provider-local@workspace:." + dependencies: + "@openfeature/core": "npm:^1.9.0" + "@openfeature/server-sdk": "npm:^1.19.0" + "@types/node": "npm:^24.0.1" + "@vitest/coverage-v8": "npm:^3.2.4" + dotenv: "npm:^17.2.2" + rolldown: "npm:1.0.0-beta.38" + ts-proto: "npm:^2.7.3" + tsdown: "npm:latest" + vitest: "npm:^3.2.4" + peerDependencies: + "@openfeature/server-sdk": ^1.19.0 + languageName: unknown + linkType: soft + +"@tybys/wasm-util@npm:^0.10.1": + version: 0.10.1 + resolution: "@tybys/wasm-util@npm:0.10.1" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/b255094f293794c6d2289300c5fbcafbb5532a3aed3a5ffd2f8dc1828e639b88d75f6a376dd8f94347a44813fd7a7149d8463477a9a49525c8b2dcaa38c2d1e8 + languageName: node + linkType: hard + +"@types/chai@npm:^5.2.2": + version: 5.2.2 + resolution: "@types/chai@npm:5.2.2" + dependencies: + "@types/deep-eql": "npm:*" + checksum: 10c0/49282bf0e8246800ebb36f17256f97bd3a8c4fb31f92ad3c0eaa7623518d7e87f1eaad4ad206960fcaf7175854bdff4cb167e4fe96811e0081b4ada83dd533ec + languageName: node + linkType: hard + +"@types/deep-eql@npm:*": + version: 4.0.2 + resolution: "@types/deep-eql@npm:4.0.2" + checksum: 10c0/bf3f811843117900d7084b9d0c852da9a044d12eb40e6de73b552598a6843c21291a8a381b0532644574beecd5e3491c5ff3a0365ab86b15d59862c025384844 + languageName: node + linkType: hard + +"@types/estree@npm:1.0.8, @types/estree@npm:^1.0.0": + version: 1.0.8 + resolution: "@types/estree@npm:1.0.8" + checksum: 10c0/39d34d1afaa338ab9763f37ad6066e3f349444f9052b9676a7cc0252ef9485a41c6d81c9c4e0d26e9077993354edf25efc853f3224dd4b447175ef62bdcc86a5 + languageName: node + linkType: hard + +"@types/node@npm:^24.0.1": + version: 24.5.0 + resolution: "@types/node@npm:24.5.0" + dependencies: + undici-types: "npm:~7.12.0" + checksum: 10c0/c5beff68481e2cc667279a1478b34a1cfd048dbff914219cb5888967938d134907836b6c4d6d141dc862489cb09ef28f7d446c7a3b475181fd126c0fcd2916fa + languageName: node + linkType: hard + +"@vitest/coverage-v8@npm:^3.2.4": + version: 3.2.4 + resolution: "@vitest/coverage-v8@npm:3.2.4" + dependencies: + "@ampproject/remapping": "npm:^2.3.0" + "@bcoe/v8-coverage": "npm:^1.0.2" + ast-v8-to-istanbul: "npm:^0.3.3" + debug: "npm:^4.4.1" + istanbul-lib-coverage: "npm:^3.2.2" + istanbul-lib-report: "npm:^3.0.1" + istanbul-lib-source-maps: "npm:^5.0.6" + istanbul-reports: "npm:^3.1.7" + magic-string: "npm:^0.30.17" + magicast: "npm:^0.3.5" + std-env: "npm:^3.9.0" + test-exclude: "npm:^7.0.1" + tinyrainbow: "npm:^2.0.0" + peerDependencies: + "@vitest/browser": 3.2.4 + vitest: 3.2.4 + peerDependenciesMeta: + "@vitest/browser": + optional: true + checksum: 10c0/cae3e58d81d56e7e1cdecd7b5baab7edd0ad9dee8dec9353c52796e390e452377d3f04174d40b6986b17c73241a5e773e422931eaa8102dcba0605ff24b25193 + languageName: node + linkType: hard + +"@vitest/expect@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/expect@npm:3.2.4" + dependencies: + "@types/chai": "npm:^5.2.2" + "@vitest/spy": "npm:3.2.4" + "@vitest/utils": "npm:3.2.4" + chai: "npm:^5.2.0" + tinyrainbow: "npm:^2.0.0" + checksum: 10c0/7586104e3fd31dbe1e6ecaafb9a70131e4197dce2940f727b6a84131eee3decac7b10f9c7c72fa5edbdb68b6f854353bd4c0fa84779e274207fb7379563b10db + languageName: node + linkType: hard + +"@vitest/mocker@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/mocker@npm:3.2.4" + dependencies: + "@vitest/spy": "npm:3.2.4" + estree-walker: "npm:^3.0.3" + magic-string: "npm:^0.30.17" + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + checksum: 10c0/f7a4aea19bbbf8f15905847ee9143b6298b2c110f8b64789224cb0ffdc2e96f9802876aa2ca83f1ec1b6e1ff45e822abb34f0054c24d57b29ab18add06536ccd + languageName: node + linkType: hard + +"@vitest/pretty-format@npm:3.2.4, @vitest/pretty-format@npm:^3.2.4": + version: 3.2.4 + resolution: "@vitest/pretty-format@npm:3.2.4" + dependencies: + tinyrainbow: "npm:^2.0.0" + checksum: 10c0/5ad7d4278e067390d7d633e307fee8103958806a419ca380aec0e33fae71b44a64415f7a9b4bc11635d3c13d4a9186111c581d3cef9c65cc317e68f077456887 + languageName: node + linkType: hard + +"@vitest/runner@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/runner@npm:3.2.4" + dependencies: + "@vitest/utils": "npm:3.2.4" + pathe: "npm:^2.0.3" + strip-literal: "npm:^3.0.0" + checksum: 10c0/e8be51666c72b3668ae3ea348b0196656a4a5adb836cb5e270720885d9517421815b0d6c98bfdf1795ed02b994b7bfb2b21566ee356a40021f5bf4f6ed4e418a + languageName: node + linkType: hard + +"@vitest/snapshot@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/snapshot@npm:3.2.4" + dependencies: + "@vitest/pretty-format": "npm:3.2.4" + magic-string: "npm:^0.30.17" + pathe: "npm:^2.0.3" + checksum: 10c0/f8301a3d7d1559fd3d59ed51176dd52e1ed5c2d23aa6d8d6aa18787ef46e295056bc726a021698d8454c16ed825ecba163362f42fa90258bb4a98cfd2c9424fc + languageName: node + linkType: hard + +"@vitest/spy@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/spy@npm:3.2.4" + dependencies: + tinyspy: "npm:^4.0.3" + checksum: 10c0/6ebf0b4697dc238476d6b6a60c76ba9eb1dd8167a307e30f08f64149612fd50227682b876420e4c2e09a76334e73f72e3ebf0e350714dc22474258292e202024 + languageName: node + linkType: hard + +"@vitest/utils@npm:3.2.4": + version: 3.2.4 + resolution: "@vitest/utils@npm:3.2.4" + dependencies: + "@vitest/pretty-format": "npm:3.2.4" + loupe: "npm:^3.1.4" + tinyrainbow: "npm:^2.0.0" + checksum: 10c0/024a9b8c8bcc12cf40183c246c244b52ecff861c6deb3477cbf487ac8781ad44c68a9c5fd69f8c1361878e55b97c10d99d511f2597f1f7244b5e5101d028ba64 + languageName: node + linkType: hard + +"abbrev@npm:^3.0.0": + version: 3.0.1 + resolution: "abbrev@npm:3.0.1" + checksum: 10c0/21ba8f574ea57a3106d6d35623f2c4a9111d9ee3e9a5be47baed46ec2457d2eac46e07a5c4a60186f88cb98abbe3e24f2d4cca70bc2b12f1692523e2209a9ccf + languageName: node + linkType: hard + +"agent-base@npm:^7.1.0, agent-base@npm:^7.1.2": + version: 7.1.4 + resolution: "agent-base@npm:7.1.4" + checksum: 10c0/c2c9ab7599692d594b6a161559ada307b7a624fa4c7b03e3afdb5a5e31cd0e53269115b620fcab024c5ac6a6f37fa5eb2e004f076ad30f5f7e6b8b671f7b35fe + languageName: node + linkType: hard + +"ansi-regex@npm:^5.0.1": + version: 5.0.1 + resolution: "ansi-regex@npm:5.0.1" + checksum: 10c0/9a64bb8627b434ba9327b60c027742e5d17ac69277960d041898596271d992d4d52ba7267a63ca10232e29f6107fc8a835f6ce8d719b88c5f8493f8254813737 + languageName: node + linkType: hard + +"ansi-regex@npm:^6.0.1": + version: 6.2.2 + resolution: "ansi-regex@npm:6.2.2" + checksum: 10c0/05d4acb1d2f59ab2cf4b794339c7b168890d44dda4bf0ce01152a8da0213aca207802f930442ce8cd22d7a92f44907664aac6508904e75e038fa944d2601b30f + languageName: node + linkType: hard + +"ansi-styles@npm:^4.0.0": + version: 4.3.0 + resolution: "ansi-styles@npm:4.3.0" + dependencies: + color-convert: "npm:^2.0.1" + checksum: 10c0/895a23929da416f2bd3de7e9cb4eabd340949328ab85ddd6e484a637d8f6820d485f53933446f5291c3b760cbc488beb8e88573dd0f9c7daf83dccc8fe81b041 + languageName: node + linkType: hard + +"ansi-styles@npm:^6.1.0": + version: 6.2.3 + resolution: "ansi-styles@npm:6.2.3" + checksum: 10c0/23b8a4ce14e18fb854693b95351e286b771d23d8844057ed2e7d083cd3e708376c3323707ec6a24365f7d7eda3ca00327fe04092e29e551499ec4c8b7bfac868 + languageName: node + linkType: hard + +"ansis@npm:^4.0.0, ansis@npm:^4.1.0": + version: 4.1.0 + resolution: "ansis@npm:4.1.0" + checksum: 10c0/df62d017a7791babdaf45b93f930d2cfd6d1dab5568b610735c11434c9a5ef8f513740e7cfd80bcbc3530fc8bd892b88f8476f26621efc251230e53cbd1a2c24 + languageName: node + linkType: hard + +"assertion-error@npm:^2.0.1": + version: 2.0.1 + resolution: "assertion-error@npm:2.0.1" + checksum: 10c0/bbbcb117ac6480138f8c93cf7f535614282dea9dc828f540cdece85e3c665e8f78958b96afac52f29ff883c72638e6a87d469ecc9fe5bc902df03ed24a55dba8 + languageName: node + linkType: hard + +"ast-kit@npm:^2.1.2": + version: 2.1.2 + resolution: "ast-kit@npm:2.1.2" + dependencies: + "@babel/parser": "npm:^7.28.0" + pathe: "npm:^2.0.3" + checksum: 10c0/7034c2d98de971cd689f5e098837c08f4f1b96a4fab14ab8d54ddc3b877e5e677f6851bef7e1625f0c714196f85ba2a0417446afe571ae34db1a4e34d788b25c + languageName: node + linkType: hard + +"ast-v8-to-istanbul@npm:^0.3.3": + version: 0.3.5 + resolution: "ast-v8-to-istanbul@npm:0.3.5" + dependencies: + "@jridgewell/trace-mapping": "npm:^0.3.30" + estree-walker: "npm:^3.0.3" + js-tokens: "npm:^9.0.1" + checksum: 10c0/6796d2e79dc82302543f8109a6d75944278903cee6269b46df4a7d923c289754f1c97390df48536657741d387046e11dbedcda8ce2e6441bcbe26f8586a6d715 + languageName: node + linkType: hard + +"balanced-match@npm:^1.0.0": + version: 1.0.2 + resolution: "balanced-match@npm:1.0.2" + checksum: 10c0/9308baf0a7e4838a82bbfd11e01b1cb0f0cf2893bc1676c27c2a8c0e70cbae1c59120c3268517a8ae7fb6376b4639ef81ca22582611dbee4ed28df945134aaee + languageName: node + linkType: hard + +"birpc@npm:^2.5.0": + version: 2.5.0 + resolution: "birpc@npm:2.5.0" + checksum: 10c0/8caed5ad86b71e0b4af6a1c5e8ed006f451d3b378ce52c2fa613fe68f15bb3df1357ad69f7fb0251e4261f39b2926995e34307ac06397f993665b16ba569dc54 + languageName: node + linkType: hard + +"brace-expansion@npm:^2.0.1": + version: 2.0.2 + resolution: "brace-expansion@npm:2.0.2" + dependencies: + balanced-match: "npm:^1.0.0" + checksum: 10c0/6d117a4c793488af86b83172deb6af143e94c17bc53b0b3cec259733923b4ca84679d506ac261f4ba3c7ed37c46018e2ff442f9ce453af8643ecd64f4a54e6cf + languageName: node + linkType: hard + +"cac@npm:^6.7.14": + version: 6.7.14 + resolution: "cac@npm:6.7.14" + checksum: 10c0/4ee06aaa7bab8981f0d54e5f5f9d4adcd64058e9697563ce336d8a3878ed018ee18ebe5359b2430eceae87e0758e62ea2019c3f52ae6e211b1bd2e133856cd10 + languageName: node + linkType: hard + +"cacache@npm:^19.0.1": + version: 19.0.1 + resolution: "cacache@npm:19.0.1" + dependencies: + "@npmcli/fs": "npm:^4.0.0" + fs-minipass: "npm:^3.0.0" + glob: "npm:^10.2.2" + lru-cache: "npm:^10.0.1" + minipass: "npm:^7.0.3" + minipass-collect: "npm:^2.0.1" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + p-map: "npm:^7.0.2" + ssri: "npm:^12.0.0" + tar: "npm:^7.4.3" + unique-filename: "npm:^4.0.0" + checksum: 10c0/01f2134e1bd7d3ab68be851df96c8d63b492b1853b67f2eecb2c37bb682d37cb70bb858a16f2f0554d3c0071be6dfe21456a1ff6fa4b7eed996570d6a25ffe9c + languageName: node + linkType: hard + +"case-anything@npm:^2.1.13": + version: 2.1.13 + resolution: "case-anything@npm:2.1.13" + checksum: 10c0/b02ffa51d7d58b9a32df7b40973836e16afad131eae7d343e64cb3ca7be57a936bf3d6c9d57a7aa242cf2f545d9a33990b755e93bcac2517761d77773a4a6a30 + languageName: node + linkType: hard + +"chai@npm:^5.2.0": + version: 5.3.3 + resolution: "chai@npm:5.3.3" + dependencies: + assertion-error: "npm:^2.0.1" + check-error: "npm:^2.1.1" + deep-eql: "npm:^5.0.1" + loupe: "npm:^3.1.0" + pathval: "npm:^2.0.0" + checksum: 10c0/b360fd4d38861622e5010c2f709736988b05c7f31042305fa3f4e9911f6adb80ccfb4e302068bf8ed10e835c2e2520cba0f5edc13d878b886987e5aa62483f53 + languageName: node + linkType: hard + +"check-error@npm:^2.1.1": + version: 2.1.1 + resolution: "check-error@npm:2.1.1" + checksum: 10c0/979f13eccab306cf1785fa10941a590b4e7ea9916ea2a4f8c87f0316fc3eab07eabefb6e587424ef0f88cbcd3805791f172ea739863ca3d7ce2afc54641c7f0e + languageName: node + linkType: hard + +"chokidar@npm:^4.0.3": + version: 4.0.3 + resolution: "chokidar@npm:4.0.3" + dependencies: + readdirp: "npm:^4.0.1" + checksum: 10c0/a58b9df05bb452f7d105d9e7229ac82fa873741c0c40ddcc7bb82f8a909fbe3f7814c9ebe9bc9a2bef9b737c0ec6e2d699d179048ef06ad3ec46315df0ebe6ad + languageName: node + linkType: hard + +"chownr@npm:^3.0.0": + version: 3.0.0 + resolution: "chownr@npm:3.0.0" + checksum: 10c0/43925b87700f7e3893296c8e9c56cc58f926411cce3a6e5898136daaf08f08b9a8eb76d37d3267e707d0dcc17aed2e2ebdf5848c0c3ce95cf910a919935c1b10 + languageName: node + linkType: hard + +"color-convert@npm:^2.0.1": + version: 2.0.1 + resolution: "color-convert@npm:2.0.1" + dependencies: + color-name: "npm:~1.1.4" + checksum: 10c0/37e1150172f2e311fe1b2df62c6293a342ee7380da7b9cfdba67ea539909afbd74da27033208d01d6d5cfc65ee7868a22e18d7e7648e004425441c0f8a15a7d7 + languageName: node + linkType: hard + +"color-name@npm:~1.1.4": + version: 1.1.4 + resolution: "color-name@npm:1.1.4" + checksum: 10c0/a1a3f914156960902f46f7f56bc62effc6c94e84b2cae157a526b1c1f74b677a47ec602bf68a61abfa2b42d15b7c5651c6dbe72a43af720bc588dff885b10f95 + languageName: node + linkType: hard + +"cross-spawn@npm:^7.0.6": + version: 7.0.6 + resolution: "cross-spawn@npm:7.0.6" + dependencies: + path-key: "npm:^3.1.0" + shebang-command: "npm:^2.0.0" + which: "npm:^2.0.1" + checksum: 10c0/053ea8b2135caff68a9e81470e845613e374e7309a47731e81639de3eaeb90c3d01af0e0b44d2ab9d50b43467223b88567dfeb3262db942dc063b9976718ffc1 + languageName: node + linkType: hard + +"debug@npm:4, debug@npm:^4.1.1, debug@npm:^4.3.4, debug@npm:^4.4.1": + version: 4.4.3 + resolution: "debug@npm:4.4.3" + dependencies: + ms: "npm:^2.1.3" + peerDependenciesMeta: + supports-color: + optional: true + checksum: 10c0/d79136ec6c83ecbefd0f6a5593da6a9c91ec4d7ddc4b54c883d6e71ec9accb5f67a1a5e96d00a328196b5b5c86d365e98d8a3a70856aaf16b4e7b1985e67f5a6 + languageName: node + linkType: hard + +"deep-eql@npm:^5.0.1": + version: 5.0.2 + resolution: "deep-eql@npm:5.0.2" + checksum: 10c0/7102cf3b7bb719c6b9c0db2e19bf0aa9318d141581befe8c7ce8ccd39af9eaa4346e5e05adef7f9bd7015da0f13a3a25dcfe306ef79dc8668aedbecb658dd247 + languageName: node + linkType: hard + +"defu@npm:^6.1.4": + version: 6.1.4 + resolution: "defu@npm:6.1.4" + checksum: 10c0/2d6cc366262dc0cb8096e429368e44052fdf43ed48e53ad84cc7c9407f890301aa5fcb80d0995abaaf842b3949f154d060be4160f7a46cb2bc2f7726c81526f5 + languageName: node + linkType: hard + +"detect-libc@npm:^1.0.3": + version: 1.0.3 + resolution: "detect-libc@npm:1.0.3" + bin: + detect-libc: ./bin/detect-libc.js + checksum: 10c0/4da0deae9f69e13bc37a0902d78bf7169480004b1fed3c19722d56cff578d16f0e11633b7fbf5fb6249181236c72e90024cbd68f0b9558ae06e281f47326d50d + languageName: node + linkType: hard + +"diff@npm:^8.0.2": + version: 8.0.2 + resolution: "diff@npm:8.0.2" + checksum: 10c0/abfb387f033e089df3ec3be960205d17b54df8abf0924d982a7ced3a94c557a4e6cbff2e78b121f216b85f466b3d8d041673a386177c311aaea41459286cc9bc + languageName: node + linkType: hard + +"dotenv@npm:^17.2.2": + version: 17.2.2 + resolution: "dotenv@npm:17.2.2" + checksum: 10c0/be66513504590aff6eccb14167625aed9bd42ce80547f4fe5d195860211971a7060949b57108dfaeaf90658f79e40edccd3f233f0a978bff507b5b1565ae162b + languageName: node + linkType: hard + +"dprint-node@npm:^1.0.8": + version: 1.0.8 + resolution: "dprint-node@npm:1.0.8" + dependencies: + detect-libc: "npm:^1.0.3" + checksum: 10c0/39c1f8511833226cde773129afc5862dfd05babe062375e6b1f5824e221a5743a4d9c48626f32f7c2080113566270fe80521a50acb9029a20a2e80a3cd5e4106 + languageName: node + linkType: hard + +"dts-resolver@npm:^2.1.2": + version: 2.1.2 + resolution: "dts-resolver@npm:2.1.2" + peerDependencies: + oxc-resolver: ">=11.0.0" + peerDependenciesMeta: + oxc-resolver: + optional: true + checksum: 10c0/521986fc9a7922e972c5d603bc2a2e1e2a0d7aa4902533947e2d63362d3ac6ac5b6ca22a75e82ee1ff7a3de9480eb050b1a584f3d2c653b3fe8091413f99f69f + languageName: node + linkType: hard + +"eastasianwidth@npm:^0.2.0": + version: 0.2.0 + resolution: "eastasianwidth@npm:0.2.0" + checksum: 10c0/26f364ebcdb6395f95124fda411f63137a4bfb5d3a06453f7f23dfe52502905bd84e0488172e0f9ec295fdc45f05c23d5d91baf16bd26f0fe9acd777a188dc39 + languageName: node + linkType: hard + +"emoji-regex@npm:^8.0.0": + version: 8.0.0 + resolution: "emoji-regex@npm:8.0.0" + checksum: 10c0/b6053ad39951c4cf338f9092d7bfba448cdfd46fe6a2a034700b149ac9ffbc137e361cbd3c442297f86bed2e5f7576c1b54cc0a6bf8ef5106cc62f496af35010 + languageName: node + linkType: hard + +"emoji-regex@npm:^9.2.2": + version: 9.2.2 + resolution: "emoji-regex@npm:9.2.2" + checksum: 10c0/af014e759a72064cf66e6e694a7fc6b0ed3d8db680427b021a89727689671cefe9d04151b2cad51dbaf85d5ba790d061cd167f1cf32eb7b281f6368b3c181639 + languageName: node + linkType: hard + +"empathic@npm:^2.0.0": + version: 2.0.0 + resolution: "empathic@npm:2.0.0" + checksum: 10c0/7d3b14b04a93b35c47bcc950467ec914fd241cd9acc0269b0ea160f13026ec110f520c90fae64720fde72cc1757b57f3f292fb606617b7fccac1f4d008a76506 + languageName: node + linkType: hard + +"encoding@npm:^0.1.13": + version: 0.1.13 + resolution: "encoding@npm:0.1.13" + dependencies: + iconv-lite: "npm:^0.6.2" + checksum: 10c0/36d938712ff00fe1f4bac88b43bcffb5930c1efa57bbcdca9d67e1d9d6c57cfb1200fb01efe0f3109b2ce99b231f90779532814a81370a1bd3274a0f58585039 + languageName: node + linkType: hard + +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 10c0/285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4 + languageName: node + linkType: hard + +"err-code@npm:^2.0.2": + version: 2.0.3 + resolution: "err-code@npm:2.0.3" + checksum: 10c0/b642f7b4dd4a376e954947550a3065a9ece6733ab8e51ad80db727aaae0817c2e99b02a97a3d6cecc648a97848305e728289cf312d09af395403a90c9d4d8a66 + languageName: node + linkType: hard + +"es-module-lexer@npm:^1.7.0": + version: 1.7.0 + resolution: "es-module-lexer@npm:1.7.0" + checksum: 10c0/4c935affcbfeba7fb4533e1da10fa8568043df1e3574b869385980de9e2d475ddc36769891936dbb07036edb3c3786a8b78ccf44964cd130dedc1f2c984b6c7b + languageName: node + linkType: hard + +"esbuild@npm:^0.25.0": + version: 0.25.9 + resolution: "esbuild@npm:0.25.9" + dependencies: + "@esbuild/aix-ppc64": "npm:0.25.9" + "@esbuild/android-arm": "npm:0.25.9" + "@esbuild/android-arm64": "npm:0.25.9" + "@esbuild/android-x64": "npm:0.25.9" + "@esbuild/darwin-arm64": "npm:0.25.9" + "@esbuild/darwin-x64": "npm:0.25.9" + "@esbuild/freebsd-arm64": "npm:0.25.9" + "@esbuild/freebsd-x64": "npm:0.25.9" + "@esbuild/linux-arm": "npm:0.25.9" + "@esbuild/linux-arm64": "npm:0.25.9" + "@esbuild/linux-ia32": "npm:0.25.9" + "@esbuild/linux-loong64": "npm:0.25.9" + "@esbuild/linux-mips64el": "npm:0.25.9" + "@esbuild/linux-ppc64": "npm:0.25.9" + "@esbuild/linux-riscv64": "npm:0.25.9" + "@esbuild/linux-s390x": "npm:0.25.9" + "@esbuild/linux-x64": "npm:0.25.9" + "@esbuild/netbsd-arm64": "npm:0.25.9" + "@esbuild/netbsd-x64": "npm:0.25.9" + "@esbuild/openbsd-arm64": "npm:0.25.9" + "@esbuild/openbsd-x64": "npm:0.25.9" + "@esbuild/openharmony-arm64": "npm:0.25.9" + "@esbuild/sunos-x64": "npm:0.25.9" + "@esbuild/win32-arm64": "npm:0.25.9" + "@esbuild/win32-ia32": "npm:0.25.9" + "@esbuild/win32-x64": "npm:0.25.9" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-arm64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/openharmony-arm64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10c0/aaa1284c75fcf45c82f9a1a117fe8dc5c45628e3386bda7d64916ae27730910b51c5aec7dd45a6ba19256be30ba2935e64a8f011a3f0539833071e06bf76d5b3 + languageName: node + linkType: hard + +"estree-walker@npm:^3.0.3": + version: 3.0.3 + resolution: "estree-walker@npm:3.0.3" + dependencies: + "@types/estree": "npm:^1.0.0" + checksum: 10c0/c12e3c2b2642d2bcae7d5aa495c60fa2f299160946535763969a1c83fc74518ffa9c2cd3a8b69ac56aea547df6a8aac25f729a342992ef0bbac5f1c73e78995d + languageName: node + linkType: hard + +"expect-type@npm:^1.2.1": + version: 1.2.2 + resolution: "expect-type@npm:1.2.2" + checksum: 10c0/6019019566063bbc7a690d9281d920b1a91284a4a093c2d55d71ffade5ac890cf37a51e1da4602546c4b56569d2ad2fc175a2ccee77d1ae06cb3af91ef84f44b + languageName: node + linkType: hard + +"exponential-backoff@npm:^3.1.1": + version: 3.1.2 + resolution: "exponential-backoff@npm:3.1.2" + checksum: 10c0/d9d3e1eafa21b78464297df91f1776f7fbaa3d5e3f7f0995648ca5b89c069d17055033817348d9f4a43d1c20b0eab84f75af6991751e839df53e4dfd6f22e844 + languageName: node + linkType: hard + +"fdir@npm:^6.5.0": + version: 6.5.0 + resolution: "fdir@npm:6.5.0" + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + checksum: 10c0/e345083c4306b3aed6cb8ec551e26c36bab5c511e99ea4576a16750ddc8d3240e63826cc624f5ae17ad4dc82e68a253213b60d556c11bfad064b7607847ed07f + languageName: node + linkType: hard + +"foreground-child@npm:^3.1.0": + version: 3.3.1 + resolution: "foreground-child@npm:3.3.1" + dependencies: + cross-spawn: "npm:^7.0.6" + signal-exit: "npm:^4.0.1" + checksum: 10c0/8986e4af2430896e65bc2788d6679067294d6aee9545daefc84923a0a4b399ad9c7a3ea7bd8c0b2b80fdf4a92de4c69df3f628233ff3224260e9c1541a9e9ed3 + languageName: node + linkType: hard + +"fs-minipass@npm:^3.0.0": + version: 3.0.3 + resolution: "fs-minipass@npm:3.0.3" + dependencies: + minipass: "npm:^7.0.3" + checksum: 10c0/63e80da2ff9b621e2cb1596abcb9207f1cf82b968b116ccd7b959e3323144cce7fb141462200971c38bbf2ecca51695069db45265705bed09a7cd93ae5b89f94 + languageName: node + linkType: hard + +"fsevents@npm:~2.3.2, fsevents@npm:~2.3.3": + version: 2.3.3 + resolution: "fsevents@npm:2.3.3" + dependencies: + node-gyp: "npm:latest" + checksum: 10c0/a1f0c44595123ed717febbc478aa952e47adfc28e2092be66b8ab1635147254ca6cfe1df792a8997f22716d4cbafc73309899ff7bfac2ac3ad8cf2e4ecc3ec60 + conditions: os=darwin + languageName: node + linkType: hard + +"fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin": + version: 2.3.3 + resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" + dependencies: + node-gyp: "npm:latest" + conditions: os=darwin + languageName: node + linkType: hard + +"get-tsconfig@npm:^4.10.1": + version: 4.10.1 + resolution: "get-tsconfig@npm:4.10.1" + dependencies: + resolve-pkg-maps: "npm:^1.0.0" + checksum: 10c0/7f8e3dabc6a49b747920a800fb88e1952fef871cdf51b79e98db48275a5de6cdaf499c55ee67df5fa6fe7ce65f0063e26de0f2e53049b408c585aa74d39ffa21 + languageName: node + linkType: hard + +"glob@npm:^10.2.2, glob@npm:^10.4.1": + version: 10.4.5 + resolution: "glob@npm:10.4.5" + dependencies: + foreground-child: "npm:^3.1.0" + jackspeak: "npm:^3.1.2" + minimatch: "npm:^9.0.4" + minipass: "npm:^7.1.2" + package-json-from-dist: "npm:^1.0.0" + path-scurry: "npm:^1.11.1" + bin: + glob: dist/esm/bin.mjs + checksum: 10c0/19a9759ea77b8e3ca0a43c2f07ecddc2ad46216b786bb8f993c445aee80d345925a21e5280c7b7c6c59e860a0154b84e4b2b60321fea92cd3c56b4a7489f160e + languageName: node + linkType: hard + +"graceful-fs@npm:^4.2.6": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 + languageName: node + linkType: hard + +"has-flag@npm:^4.0.0": + version: 4.0.0 + resolution: "has-flag@npm:4.0.0" + checksum: 10c0/2e789c61b7888d66993e14e8331449e525ef42aac53c627cc53d1c3334e768bcb6abdc4f5f0de1478a25beec6f0bd62c7549058b7ac53e924040d4f301f02fd1 + languageName: node + linkType: hard + +"hookable@npm:^5.5.3": + version: 5.5.3 + resolution: "hookable@npm:5.5.3" + checksum: 10c0/275f4cc84d27f8d48c5a5cd5685b6c0fea9291be9deea5bff0cfa72856ed566abde1dcd8cb1da0f9a70b4da3d7ec0d60dc3554c4edbba647058cc38816eced3d + languageName: node + linkType: hard + +"html-escaper@npm:^2.0.0": + version: 2.0.2 + resolution: "html-escaper@npm:2.0.2" + checksum: 10c0/208e8a12de1a6569edbb14544f4567e6ce8ecc30b9394fcaa4e7bb1e60c12a7c9a1ed27e31290817157e8626f3a4f29e76c8747030822eb84a6abb15c255f0a0 + languageName: node + linkType: hard + +"http-cache-semantics@npm:^4.1.1": + version: 4.2.0 + resolution: "http-cache-semantics@npm:4.2.0" + checksum: 10c0/45b66a945cf13ec2d1f29432277201313babf4a01d9e52f44b31ca923434083afeca03f18417f599c9ab3d0e7b618ceb21257542338b57c54b710463b4a53e37 + languageName: node + linkType: hard + +"http-proxy-agent@npm:^7.0.0": + version: 7.0.2 + resolution: "http-proxy-agent@npm:7.0.2" + dependencies: + agent-base: "npm:^7.1.0" + debug: "npm:^4.3.4" + checksum: 10c0/4207b06a4580fb85dd6dff521f0abf6db517489e70863dca1a0291daa7f2d3d2d6015a57bd702af068ea5cf9f1f6ff72314f5f5b4228d299c0904135d2aef921 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^7.0.1": + version: 7.0.6 + resolution: "https-proxy-agent@npm:7.0.6" + dependencies: + agent-base: "npm:^7.1.2" + debug: "npm:4" + checksum: 10c0/f729219bc735edb621fa30e6e84e60ee5d00802b8247aac0d7b79b0bd6d4b3294737a337b93b86a0bd9e68099d031858a39260c976dc14cdbba238ba1f8779ac + languageName: node + linkType: hard + +"iconv-lite@npm:^0.6.2": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 10c0/98102bc66b33fcf5ac044099d1257ba0b7ad5e3ccd3221f34dd508ab4070edff183276221684e1e0555b145fce0850c9f7d2b60a9fcac50fbb4ea0d6e845a3b1 + languageName: node + linkType: hard + +"imurmurhash@npm:^0.1.4": + version: 0.1.4 + resolution: "imurmurhash@npm:0.1.4" + checksum: 10c0/8b51313850dd33605c6c9d3fd9638b714f4c4c40250cff658209f30d40da60f78992fb2df5dabee4acf589a6a82bbc79ad5486550754bd9ec4e3fc0d4a57d6a6 + languageName: node + linkType: hard + +"ip-address@npm:^10.0.1": + version: 10.0.1 + resolution: "ip-address@npm:10.0.1" + checksum: 10c0/1634d79dae18394004775cb6d699dc46b7c23df6d2083164025a2b15240c1164fccde53d0e08bd5ee4fc53913d033ab6b5e395a809ad4b956a940c446e948843 + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^3.0.0": + version: 3.0.0 + resolution: "is-fullwidth-code-point@npm:3.0.0" + checksum: 10c0/bb11d825e049f38e04c06373a8d72782eee0205bda9d908cc550ccb3c59b99d750ff9537982e01733c1c94a58e35400661f57042158ff5e8f3e90cf936daf0fc + languageName: node + linkType: hard + +"isexe@npm:^2.0.0": + version: 2.0.0 + resolution: "isexe@npm:2.0.0" + checksum: 10c0/228cfa503fadc2c31596ab06ed6aa82c9976eec2bfd83397e7eaf06d0ccf42cd1dfd6743bf9aeb01aebd4156d009994c5f76ea898d2832c1fe342da923ca457d + languageName: node + linkType: hard + +"isexe@npm:^3.1.1": + version: 3.1.1 + resolution: "isexe@npm:3.1.1" + checksum: 10c0/9ec257654093443eb0a528a9c8cbba9c0ca7616ccb40abd6dde7202734d96bb86e4ac0d764f0f8cd965856aacbff2f4ce23e730dc19dfb41e3b0d865ca6fdcc7 + languageName: node + linkType: hard + +"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.2": + version: 3.2.2 + resolution: "istanbul-lib-coverage@npm:3.2.2" + checksum: 10c0/6c7ff2106769e5f592ded1fb418f9f73b4411fd5a084387a5410538332b6567cd1763ff6b6cadca9b9eb2c443cce2f7ea7d7f1b8d315f9ce58539793b1e0922b + languageName: node + linkType: hard + +"istanbul-lib-report@npm:^3.0.0, istanbul-lib-report@npm:^3.0.1": + version: 3.0.1 + resolution: "istanbul-lib-report@npm:3.0.1" + dependencies: + istanbul-lib-coverage: "npm:^3.0.0" + make-dir: "npm:^4.0.0" + supports-color: "npm:^7.1.0" + checksum: 10c0/84323afb14392de8b6a5714bd7e9af845cfbd56cfe71ed276cda2f5f1201aea673c7111901227ee33e68e4364e288d73861eb2ed48f6679d1e69a43b6d9b3ba7 + languageName: node + linkType: hard + +"istanbul-lib-source-maps@npm:^5.0.6": + version: 5.0.6 + resolution: "istanbul-lib-source-maps@npm:5.0.6" + dependencies: + "@jridgewell/trace-mapping": "npm:^0.3.23" + debug: "npm:^4.1.1" + istanbul-lib-coverage: "npm:^3.0.0" + checksum: 10c0/ffe75d70b303a3621ee4671554f306e0831b16f39ab7f4ab52e54d356a5d33e534d97563e318f1333a6aae1d42f91ec49c76b6cd3f3fb378addcb5c81da0255f + languageName: node + linkType: hard + +"istanbul-reports@npm:^3.1.7": + version: 3.2.0 + resolution: "istanbul-reports@npm:3.2.0" + dependencies: + html-escaper: "npm:^2.0.0" + istanbul-lib-report: "npm:^3.0.0" + checksum: 10c0/d596317cfd9c22e1394f22a8d8ba0303d2074fe2e971887b32d870e4b33f8464b10f8ccbe6847808f7db485f084eba09e6c2ed706b3a978e4b52f07085b8f9bc + languageName: node + linkType: hard + +"jackspeak@npm:^3.1.2": + version: 3.4.3 + resolution: "jackspeak@npm:3.4.3" + dependencies: + "@isaacs/cliui": "npm:^8.0.2" + "@pkgjs/parseargs": "npm:^0.11.0" + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: 10c0/6acc10d139eaefdbe04d2f679e6191b3abf073f111edf10b1de5302c97ec93fffeb2fdd8681ed17f16268aa9dd4f8c588ed9d1d3bffbbfa6e8bf897cbb3149b9 + languageName: node + linkType: hard + +"jiti@npm:^2.5.1": + version: 2.5.1 + resolution: "jiti@npm:2.5.1" + bin: + jiti: lib/jiti-cli.mjs + checksum: 10c0/f0a38d7d8842cb35ffe883038166aa2d52ffd21f1a4fc839ae4076ea7301c22a1f11373f8fc52e2667de7acde8f3e092835620dd6f72a0fbe9296b268b0874bb + languageName: node + linkType: hard + +"js-tokens@npm:^9.0.1": + version: 9.0.1 + resolution: "js-tokens@npm:9.0.1" + checksum: 10c0/68dcab8f233dde211a6b5fd98079783cbcd04b53617c1250e3553ee16ab3e6134f5e65478e41d82f6d351a052a63d71024553933808570f04dbf828d7921e80e + languageName: node + linkType: hard + +"jsesc@npm:^3.0.2": + version: 3.1.0 + resolution: "jsesc@npm:3.1.0" + bin: + jsesc: bin/jsesc + checksum: 10c0/531779df5ec94f47e462da26b4cbf05eb88a83d9f08aac2ba04206508fc598527a153d08bd462bae82fc78b3eaa1a908e1a4a79f886e9238641c4cdefaf118b1 + languageName: node + linkType: hard + +"loupe@npm:^3.1.0, loupe@npm:^3.1.4": + version: 3.2.1 + resolution: "loupe@npm:3.2.1" + checksum: 10c0/910c872cba291309664c2d094368d31a68907b6f5913e989d301b5c25f30e97d76d77f23ab3bf3b46d0f601ff0b6af8810c10c31b91d2c6b2f132809ca2cc705 + languageName: node + linkType: hard + +"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": + version: 10.4.3 + resolution: "lru-cache@npm:10.4.3" + checksum: 10c0/ebd04fbca961e6c1d6c0af3799adcc966a1babe798f685bb84e6599266599cd95d94630b10262f5424539bc4640107e8a33aa28585374abf561d30d16f4b39fb + languageName: node + linkType: hard + +"magic-string@npm:^0.30.17, magic-string@npm:^0.30.19": + version: 0.30.19 + resolution: "magic-string@npm:0.30.19" + dependencies: + "@jridgewell/sourcemap-codec": "npm:^1.5.5" + checksum: 10c0/db23fd2e2ee98a1aeb88a4cdb2353137fcf05819b883c856dd79e4c7dfb25151e2a5a4d5dbd88add5e30ed8ae5c51bcf4accbc6becb75249d924ec7b4fbcae27 + languageName: node + linkType: hard + +"magicast@npm:^0.3.5": + version: 0.3.5 + resolution: "magicast@npm:0.3.5" + dependencies: + "@babel/parser": "npm:^7.25.4" + "@babel/types": "npm:^7.25.4" + source-map-js: "npm:^1.2.0" + checksum: 10c0/a6cacc0a848af84f03e3f5bda7b0de75e4d0aa9ddce5517fd23ed0f31b5ddd51b2d0ff0b7e09b51f7de0f4053c7a1107117edda6b0732dca3e9e39e6c5a68c64 + languageName: node + linkType: hard + +"make-dir@npm:^4.0.0": + version: 4.0.0 + resolution: "make-dir@npm:4.0.0" + dependencies: + semver: "npm:^7.5.3" + checksum: 10c0/69b98a6c0b8e5c4fe9acb61608a9fbcfca1756d910f51e5dbe7a9e5cfb74fca9b8a0c8a0ffdf1294a740826c1ab4871d5bf3f62f72a3049e5eac6541ddffed68 + languageName: node + linkType: hard + +"make-fetch-happen@npm:^14.0.3": + version: 14.0.3 + resolution: "make-fetch-happen@npm:14.0.3" + dependencies: + "@npmcli/agent": "npm:^3.0.0" + cacache: "npm:^19.0.1" + http-cache-semantics: "npm:^4.1.1" + minipass: "npm:^7.0.2" + minipass-fetch: "npm:^4.0.0" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + negotiator: "npm:^1.0.0" + proc-log: "npm:^5.0.0" + promise-retry: "npm:^2.0.1" + ssri: "npm:^12.0.0" + checksum: 10c0/c40efb5e5296e7feb8e37155bde8eb70bc57d731b1f7d90e35a092fde403d7697c56fb49334d92d330d6f1ca29a98142036d6480a12681133a0a1453164cb2f0 + languageName: node + linkType: hard + +"minimatch@npm:^9.0.4": + version: 9.0.5 + resolution: "minimatch@npm:9.0.5" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 10c0/de96cf5e35bdf0eab3e2c853522f98ffbe9a36c37797778d2665231ec1f20a9447a7e567cb640901f89e4daaa95ae5d70c65a9e8aa2bb0019b6facbc3c0575ed + languageName: node + linkType: hard + +"minipass-collect@npm:^2.0.1": + version: 2.0.1 + resolution: "minipass-collect@npm:2.0.1" + dependencies: + minipass: "npm:^7.0.3" + checksum: 10c0/5167e73f62bb74cc5019594709c77e6a742051a647fe9499abf03c71dca75515b7959d67a764bdc4f8b361cf897fbf25e2d9869ee039203ed45240f48b9aa06e + languageName: node + linkType: hard + +"minipass-fetch@npm:^4.0.0": + version: 4.0.1 + resolution: "minipass-fetch@npm:4.0.1" + dependencies: + encoding: "npm:^0.1.13" + minipass: "npm:^7.0.3" + minipass-sized: "npm:^1.0.3" + minizlib: "npm:^3.0.1" + dependenciesMeta: + encoding: + optional: true + checksum: 10c0/a3147b2efe8e078c9bf9d024a0059339c5a09c5b1dded6900a219c218cc8b1b78510b62dae556b507304af226b18c3f1aeb1d48660283602d5b6586c399eed5c + languageName: node + linkType: hard + +"minipass-flush@npm:^1.0.5": + version: 1.0.5 + resolution: "minipass-flush@npm:1.0.5" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10c0/2a51b63feb799d2bb34669205eee7c0eaf9dce01883261a5b77410c9408aa447e478efd191b4de6fc1101e796ff5892f8443ef20d9544385819093dbb32d36bd + languageName: node + linkType: hard + +"minipass-pipeline@npm:^1.2.4": + version: 1.2.4 + resolution: "minipass-pipeline@npm:1.2.4" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10c0/cbda57cea20b140b797505dc2cac71581a70b3247b84480c1fed5ca5ba46c25ecc25f68bfc9e6dcb1a6e9017dab5c7ada5eab73ad4f0a49d84e35093e0c643f2 + languageName: node + linkType: hard + +"minipass-sized@npm:^1.0.3": + version: 1.0.3 + resolution: "minipass-sized@npm:1.0.3" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10c0/298f124753efdc745cfe0f2bdfdd81ba25b9f4e753ca4a2066eb17c821f25d48acea607dfc997633ee5bf7b6dfffb4eee4f2051eb168663f0b99fad2fa4829cb + languageName: node + linkType: hard + +"minipass@npm:^3.0.0": + version: 3.3.6 + resolution: "minipass@npm:3.3.6" + dependencies: + yallist: "npm:^4.0.0" + checksum: 10c0/a114746943afa1dbbca8249e706d1d38b85ed1298b530f5808ce51f8e9e941962e2a5ad2e00eae7dd21d8a4aae6586a66d4216d1a259385e9d0358f0c1eba16c + languageName: node + linkType: hard + +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2": + version: 7.1.2 + resolution: "minipass@npm:7.1.2" + checksum: 10c0/b0fd20bb9fb56e5fa9a8bfac539e8915ae07430a619e4b86ff71f5fc757ef3924b23b2c4230393af1eda647ed3d75739e4e0acb250a6b1eb277cf7f8fe449557 + languageName: node + linkType: hard + +"minizlib@npm:^3.0.1": + version: 3.0.2 + resolution: "minizlib@npm:3.0.2" + dependencies: + minipass: "npm:^7.1.2" + checksum: 10c0/9f3bd35e41d40d02469cb30470c55ccc21cae0db40e08d1d0b1dff01cc8cc89a6f78e9c5d2b7c844e485ec0a8abc2238111213fdc5b2038e6d1012eacf316f78 + languageName: node + linkType: hard + +"mkdirp@npm:^3.0.1": + version: 3.0.1 + resolution: "mkdirp@npm:3.0.1" + bin: + mkdirp: dist/cjs/src/bin.js + checksum: 10c0/9f2b975e9246351f5e3a40dcfac99fcd0baa31fbfab615fe059fb11e51f10e4803c63de1f384c54d656e4db31d000e4767e9ef076a22e12a641357602e31d57d + languageName: node + linkType: hard + +"ms@npm:^2.1.3": + version: 2.1.3 + resolution: "ms@npm:2.1.3" + checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48 + languageName: node + linkType: hard + +"nanoid@npm:^3.3.11": + version: 3.3.11 + resolution: "nanoid@npm:3.3.11" + bin: + nanoid: bin/nanoid.cjs + checksum: 10c0/40e7f70b3d15f725ca072dfc4f74e81fcf1fbb02e491cf58ac0c79093adc9b0a73b152bcde57df4b79cd097e13023d7504acb38404a4da7bc1cd8e887b82fe0b + languageName: node + linkType: hard + +"negotiator@npm:^1.0.0": + version: 1.0.0 + resolution: "negotiator@npm:1.0.0" + checksum: 10c0/4c559dd52669ea48e1914f9d634227c561221dd54734070791f999c52ed0ff36e437b2e07d5c1f6e32909fc625fe46491c16e4a8f0572567d4dd15c3a4fda04b + languageName: node + linkType: hard + +"node-gyp@npm:latest": + version: 11.4.2 + resolution: "node-gyp@npm:11.4.2" + dependencies: + env-paths: "npm:^2.2.0" + exponential-backoff: "npm:^3.1.1" + graceful-fs: "npm:^4.2.6" + make-fetch-happen: "npm:^14.0.3" + nopt: "npm:^8.0.0" + proc-log: "npm:^5.0.0" + semver: "npm:^7.3.5" + tar: "npm:^7.4.3" + tinyglobby: "npm:^0.2.12" + which: "npm:^5.0.0" + bin: + node-gyp: bin/node-gyp.js + checksum: 10c0/0bfd3e96770ed70f07798d881dd37b4267708966d868a0e585986baac487d9cf5831285579fd629a83dc4e434f53e6416ce301097f2ee464cb74d377e4d8bdbe + languageName: node + linkType: hard + +"nopt@npm:^8.0.0": + version: 8.1.0 + resolution: "nopt@npm:8.1.0" + dependencies: + abbrev: "npm:^3.0.0" + bin: + nopt: bin/nopt.js + checksum: 10c0/62e9ea70c7a3eb91d162d2c706b6606c041e4e7b547cbbb48f8b3695af457dd6479904d7ace600856bf923dd8d1ed0696f06195c8c20f02ac87c1da0e1d315ef + languageName: node + linkType: hard + +"p-map@npm:^7.0.2": + version: 7.0.3 + resolution: "p-map@npm:7.0.3" + checksum: 10c0/46091610da2b38ce47bcd1d8b4835a6fa4e832848a6682cf1652bc93915770f4617afc844c10a77d1b3e56d2472bb2d5622353fa3ead01a7f42b04fc8e744a5c + languageName: node + linkType: hard + +"package-json-from-dist@npm:^1.0.0": + version: 1.0.1 + resolution: "package-json-from-dist@npm:1.0.1" + checksum: 10c0/62ba2785eb655fec084a257af34dbe24292ab74516d6aecef97ef72d4897310bc6898f6c85b5cd22770eaa1ce60d55a0230e150fb6a966e3ecd6c511e23d164b + languageName: node + linkType: hard + +"path-key@npm:^3.1.0": + version: 3.1.1 + resolution: "path-key@npm:3.1.1" + checksum: 10c0/748c43efd5a569c039d7a00a03b58eecd1d75f3999f5a28303d75f521288df4823bc057d8784eb72358b2895a05f29a070bc9f1f17d28226cc4e62494cc58c4c + languageName: node + linkType: hard + +"path-scurry@npm:^1.11.1": + version: 1.11.1 + resolution: "path-scurry@npm:1.11.1" + dependencies: + lru-cache: "npm:^10.2.0" + minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" + checksum: 10c0/32a13711a2a505616ae1cc1b5076801e453e7aae6ac40ab55b388bb91b9d0547a52f5aaceff710ea400205f18691120d4431e520afbe4266b836fadede15872d + languageName: node + linkType: hard + +"pathe@npm:^2.0.3": + version: 2.0.3 + resolution: "pathe@npm:2.0.3" + checksum: 10c0/c118dc5a8b5c4166011b2b70608762e260085180bb9e33e80a50dcdb1e78c010b1624f4280c492c92b05fc276715a4c357d1f9edc570f8f1b3d90b6839ebaca1 + languageName: node + linkType: hard + +"pathval@npm:^2.0.0": + version: 2.0.1 + resolution: "pathval@npm:2.0.1" + checksum: 10c0/460f4709479fbf2c45903a65655fc8f0a5f6d808f989173aeef5fdea4ff4f303dc13f7870303999add60ec49d4c14733895c0a869392e9866f1091fa64fd7581 + languageName: node + linkType: hard + +"picocolors@npm:^1.1.1": + version: 1.1.1 + resolution: "picocolors@npm:1.1.1" + checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58 + languageName: node + linkType: hard + +"picomatch@npm:^4.0.2, picomatch@npm:^4.0.3": + version: 4.0.3 + resolution: "picomatch@npm:4.0.3" + checksum: 10c0/9582c951e95eebee5434f59e426cddd228a7b97a0161a375aed4be244bd3fe8e3a31b846808ea14ef2c8a2527a6eeab7b3946a67d5979e81694654f939473ae2 + languageName: node + linkType: hard + +"postcss@npm:^8.5.6": + version: 8.5.6 + resolution: "postcss@npm:8.5.6" + dependencies: + nanoid: "npm:^3.3.11" + picocolors: "npm:^1.1.1" + source-map-js: "npm:^1.2.1" + checksum: 10c0/5127cc7c91ed7a133a1b7318012d8bfa112da9ef092dddf369ae699a1f10ebbd89b1b9f25f3228795b84585c72aabd5ced5fc11f2ba467eedf7b081a66fad024 + languageName: node + linkType: hard + +"proc-log@npm:^5.0.0": + version: 5.0.0 + resolution: "proc-log@npm:5.0.0" + checksum: 10c0/bbe5edb944b0ad63387a1d5b1911ae93e05ce8d0f60de1035b218cdcceedfe39dbd2c697853355b70f1a090f8f58fe90da487c85216bf9671f9499d1a897e9e3 + languageName: node + linkType: hard + +"promise-retry@npm:^2.0.1": + version: 2.0.1 + resolution: "promise-retry@npm:2.0.1" + dependencies: + err-code: "npm:^2.0.2" + retry: "npm:^0.12.0" + checksum: 10c0/9c7045a1a2928094b5b9b15336dcd2a7b1c052f674550df63cc3f36cd44028e5080448175b6f6ca32b642de81150f5e7b1a98b728f15cb069f2dd60ac2616b96 + languageName: node + linkType: hard + +"quansync@npm:^0.2.11": + version: 0.2.11 + resolution: "quansync@npm:0.2.11" + checksum: 10c0/cb9a1f8ebce074069f2f6a78578873ffedd9de9f6aa212039b44c0870955c04a71c3b1311b5d97f8ac2f2ec476de202d0a5c01160cb12bc0a11b7ef36d22ef56 + languageName: node + linkType: hard + +"readdirp@npm:^4.0.1": + version: 4.1.2 + resolution: "readdirp@npm:4.1.2" + checksum: 10c0/60a14f7619dec48c9c850255cd523e2717001b0e179dc7037cfa0895da7b9e9ab07532d324bfb118d73a710887d1e35f79c495fa91582784493e085d18c72c62 + languageName: node + linkType: hard + +"resolve-pkg-maps@npm:^1.0.0": + version: 1.0.0 + resolution: "resolve-pkg-maps@npm:1.0.0" + checksum: 10c0/fb8f7bbe2ca281a73b7ef423a1cbc786fb244bd7a95cbe5c3fba25b27d327150beca8ba02f622baea65919a57e061eb5005204daa5f93ed590d9b77463a567ab + languageName: node + linkType: hard + +"retry@npm:^0.12.0": + version: 0.12.0 + resolution: "retry@npm:0.12.0" + checksum: 10c0/59933e8501727ba13ad73ef4a04d5280b3717fd650408460c987392efe9d7be2040778ed8ebe933c5cbd63da3dcc37919c141ef8af0a54a6e4fca5a2af177bfe + languageName: node + linkType: hard + +"rolldown-plugin-dts@npm:^0.16.5": + version: 0.16.5 + resolution: "rolldown-plugin-dts@npm:0.16.5" + dependencies: + "@babel/generator": "npm:^7.28.3" + "@babel/parser": "npm:^7.28.4" + "@babel/types": "npm:^7.28.4" + ast-kit: "npm:^2.1.2" + birpc: "npm:^2.5.0" + debug: "npm:^4.4.1" + dts-resolver: "npm:^2.1.2" + get-tsconfig: "npm:^4.10.1" + magic-string: "npm:^0.30.19" + peerDependencies: + "@ts-macro/tsc": ^0.3.6 + "@typescript/native-preview": ">=7.0.0-dev.20250601.1" + rolldown: ^1.0.0-beta.9 + typescript: ^5.0.0 + vue-tsc: ~3.0.3 + peerDependenciesMeta: + "@ts-macro/tsc": + optional: true + "@typescript/native-preview": + optional: true + typescript: + optional: true + vue-tsc: + optional: true + checksum: 10c0/f15ba5ef752cb56db9289d71d62f371a06a04159d266efd7d19f7ff4a961730f4a2367f4f80d59322fbf6d2f3d5c7b36a2f3412c36e2cc49101976f5720939c8 + languageName: node + linkType: hard + +"rolldown@npm:1.0.0-beta.38, rolldown@npm:latest": + version: 1.0.0-beta.38 + resolution: "rolldown@npm:1.0.0-beta.38" + dependencies: + "@oxc-project/types": "npm:=0.89.0" + "@rolldown/binding-android-arm64": "npm:1.0.0-beta.38" + "@rolldown/binding-darwin-arm64": "npm:1.0.0-beta.38" + "@rolldown/binding-darwin-x64": "npm:1.0.0-beta.38" + "@rolldown/binding-freebsd-x64": "npm:1.0.0-beta.38" + "@rolldown/binding-linux-arm-gnueabihf": "npm:1.0.0-beta.38" + "@rolldown/binding-linux-arm64-gnu": "npm:1.0.0-beta.38" + "@rolldown/binding-linux-arm64-musl": "npm:1.0.0-beta.38" + "@rolldown/binding-linux-x64-gnu": "npm:1.0.0-beta.38" + "@rolldown/binding-linux-x64-musl": "npm:1.0.0-beta.38" + "@rolldown/binding-openharmony-arm64": "npm:1.0.0-beta.38" + "@rolldown/binding-wasm32-wasi": "npm:1.0.0-beta.38" + "@rolldown/binding-win32-arm64-msvc": "npm:1.0.0-beta.38" + "@rolldown/binding-win32-ia32-msvc": "npm:1.0.0-beta.38" + "@rolldown/binding-win32-x64-msvc": "npm:1.0.0-beta.38" + "@rolldown/pluginutils": "npm:1.0.0-beta.38" + ansis: "npm:^4.0.0" + dependenciesMeta: + "@rolldown/binding-android-arm64": + optional: true + "@rolldown/binding-darwin-arm64": + optional: true + "@rolldown/binding-darwin-x64": + optional: true + "@rolldown/binding-freebsd-x64": + optional: true + "@rolldown/binding-linux-arm-gnueabihf": + optional: true + "@rolldown/binding-linux-arm64-gnu": + optional: true + "@rolldown/binding-linux-arm64-musl": + optional: true + "@rolldown/binding-linux-x64-gnu": + optional: true + "@rolldown/binding-linux-x64-musl": + optional: true + "@rolldown/binding-openharmony-arm64": + optional: true + "@rolldown/binding-wasm32-wasi": + optional: true + "@rolldown/binding-win32-arm64-msvc": + optional: true + "@rolldown/binding-win32-ia32-msvc": + optional: true + "@rolldown/binding-win32-x64-msvc": + optional: true + bin: + rolldown: bin/cli.mjs + checksum: 10c0/5c77fe444585d9d06c2383dbb0480e9ef4c8c565c8f87119f8ee8d7f9e63df749eb24f3342c66273510635fd32aedda7cbad94f4c40c9ffed2e9e76097c0961e + languageName: node + linkType: hard + +"rollup@npm:^4.43.0": + version: 4.50.2 + resolution: "rollup@npm:4.50.2" + dependencies: + "@rollup/rollup-android-arm-eabi": "npm:4.50.2" + "@rollup/rollup-android-arm64": "npm:4.50.2" + "@rollup/rollup-darwin-arm64": "npm:4.50.2" + "@rollup/rollup-darwin-x64": "npm:4.50.2" + "@rollup/rollup-freebsd-arm64": "npm:4.50.2" + "@rollup/rollup-freebsd-x64": "npm:4.50.2" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.50.2" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.50.2" + "@rollup/rollup-linux-arm64-gnu": "npm:4.50.2" + "@rollup/rollup-linux-arm64-musl": "npm:4.50.2" + "@rollup/rollup-linux-loong64-gnu": "npm:4.50.2" + "@rollup/rollup-linux-ppc64-gnu": "npm:4.50.2" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.50.2" + "@rollup/rollup-linux-riscv64-musl": "npm:4.50.2" + "@rollup/rollup-linux-s390x-gnu": "npm:4.50.2" + "@rollup/rollup-linux-x64-gnu": "npm:4.50.2" + "@rollup/rollup-linux-x64-musl": "npm:4.50.2" + "@rollup/rollup-openharmony-arm64": "npm:4.50.2" + "@rollup/rollup-win32-arm64-msvc": "npm:4.50.2" + "@rollup/rollup-win32-ia32-msvc": "npm:4.50.2" + "@rollup/rollup-win32-x64-msvc": "npm:4.50.2" + "@types/estree": "npm:1.0.8" + fsevents: "npm:~2.3.2" + dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-freebsd-arm64": + optional: true + "@rollup/rollup-freebsd-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm-musleabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-loong64-gnu": + optional: true + "@rollup/rollup-linux-ppc64-gnu": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-riscv64-musl": + optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-openharmony-arm64": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 10c0/5415d0a5ae6f37fa5f10997b3c5cff20c2ea6bd1636db90e59672969a4f83b29f6168bf9dd26c1276c2e37e1d55674472758da90cbc46c8b08ada5d0ec60eb9b + languageName: node + linkType: hard + +"safer-buffer@npm:>= 2.1.2 < 3.0.0": + version: 2.1.2 + resolution: "safer-buffer@npm:2.1.2" + checksum: 10c0/7e3c8b2e88a1841c9671094bbaeebd94448111dd90a81a1f606f3f67708a6ec57763b3b47f06da09fc6054193e0e6709e77325415dc8422b04497a8070fa02d4 + languageName: node + linkType: hard + +"semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.7.2": + version: 7.7.2 + resolution: "semver@npm:7.7.2" + bin: + semver: bin/semver.js + checksum: 10c0/aca305edfbf2383c22571cb7714f48cadc7ac95371b4b52362fb8eeffdfbc0de0669368b82b2b15978f8848f01d7114da65697e56cd8c37b0dab8c58e543f9ea + languageName: node + linkType: hard + +"shebang-command@npm:^2.0.0": + version: 2.0.0 + resolution: "shebang-command@npm:2.0.0" + dependencies: + shebang-regex: "npm:^3.0.0" + checksum: 10c0/a41692e7d89a553ef21d324a5cceb5f686d1f3c040759c50aab69688634688c5c327f26f3ecf7001ebfd78c01f3c7c0a11a7c8bfd0a8bc9f6240d4f40b224e4e + languageName: node + linkType: hard + +"shebang-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "shebang-regex@npm:3.0.0" + checksum: 10c0/1dbed0726dd0e1152a92696c76c7f06084eb32a90f0528d11acd764043aacf76994b2fb30aa1291a21bd019d6699164d048286309a278855ee7bec06cf6fb690 + languageName: node + linkType: hard + +"siginfo@npm:^2.0.0": + version: 2.0.0 + resolution: "siginfo@npm:2.0.0" + checksum: 10c0/3def8f8e516fbb34cb6ae415b07ccc5d9c018d85b4b8611e3dc6f8be6d1899f693a4382913c9ed51a06babb5201639d76453ab297d1c54a456544acf5c892e34 + languageName: node + linkType: hard + +"signal-exit@npm:^4.0.1": + version: 4.1.0 + resolution: "signal-exit@npm:4.1.0" + checksum: 10c0/41602dce540e46d599edba9d9860193398d135f7ff72cab629db5171516cfae628d21e7bfccde1bbfdf11c48726bc2a6d1a8fb8701125852fbfda7cf19c6aa83 + languageName: node + linkType: hard + +"smart-buffer@npm:^4.2.0": + version: 4.2.0 + resolution: "smart-buffer@npm:4.2.0" + checksum: 10c0/a16775323e1404dd43fabafe7460be13a471e021637bc7889468eb45ce6a6b207261f454e4e530a19500cc962c4cc5348583520843b363f4193cee5c00e1e539 + languageName: node + linkType: hard + +"socks-proxy-agent@npm:^8.0.3": + version: 8.0.5 + resolution: "socks-proxy-agent@npm:8.0.5" + dependencies: + agent-base: "npm:^7.1.2" + debug: "npm:^4.3.4" + socks: "npm:^2.8.3" + checksum: 10c0/5d2c6cecba6821389aabf18728325730504bf9bb1d9e342e7987a5d13badd7a98838cc9a55b8ed3cb866ad37cc23e1086f09c4d72d93105ce9dfe76330e9d2a6 + languageName: node + linkType: hard + +"socks@npm:^2.8.3": + version: 2.8.7 + resolution: "socks@npm:2.8.7" + dependencies: + ip-address: "npm:^10.0.1" + smart-buffer: "npm:^4.2.0" + checksum: 10c0/2805a43a1c4bcf9ebf6e018268d87b32b32b06fbbc1f9282573583acc155860dc361500f89c73bfbb157caa1b4ac78059eac0ef15d1811eb0ca75e0bdadbc9d2 + languageName: node + linkType: hard + +"source-map-js@npm:^1.2.0, source-map-js@npm:^1.2.1": + version: 1.2.1 + resolution: "source-map-js@npm:1.2.1" + checksum: 10c0/7bda1fc4c197e3c6ff17de1b8b2c20e60af81b63a52cb32ec5a5d67a20a7d42651e2cb34ebe93833c5a2a084377e17455854fee3e21e7925c64a51b6a52b0faf + languageName: node + linkType: hard + +"ssri@npm:^12.0.0": + version: 12.0.0 + resolution: "ssri@npm:12.0.0" + dependencies: + minipass: "npm:^7.0.3" + checksum: 10c0/caddd5f544b2006e88fa6b0124d8d7b28208b83c72d7672d5ade44d794525d23b540f3396108c4eb9280dcb7c01f0bef50682f5b4b2c34291f7c5e211fd1417d + languageName: node + linkType: hard + +"stackback@npm:0.0.2": + version: 0.0.2 + resolution: "stackback@npm:0.0.2" + checksum: 10c0/89a1416668f950236dd5ac9f9a6b2588e1b9b62b1b6ad8dff1bfc5d1a15dbf0aafc9b52d2226d00c28dffff212da464eaeebfc6b7578b9d180cef3e3782c5983 + languageName: node + linkType: hard + +"std-env@npm:^3.9.0": + version: 3.9.0 + resolution: "std-env@npm:3.9.0" + checksum: 10c0/4a6f9218aef3f41046c3c7ecf1f98df00b30a07f4f35c6d47b28329bc2531eef820828951c7d7b39a1c5eb19ad8a46e3ddfc7deb28f0a2f3ceebee11bab7ba50 + languageName: node + linkType: hard + +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0": + version: 4.2.3 + resolution: "string-width@npm:4.2.3" + dependencies: + emoji-regex: "npm:^8.0.0" + is-fullwidth-code-point: "npm:^3.0.0" + strip-ansi: "npm:^6.0.1" + checksum: 10c0/1e525e92e5eae0afd7454086eed9c818ee84374bb80328fc41217ae72ff5f065ef1c9d7f72da41de40c75fa8bb3dee63d92373fd492c84260a552c636392a47b + languageName: node + linkType: hard + +"string-width@npm:^5.0.1, string-width@npm:^5.1.2": + version: 5.1.2 + resolution: "string-width@npm:5.1.2" + dependencies: + eastasianwidth: "npm:^0.2.0" + emoji-regex: "npm:^9.2.2" + strip-ansi: "npm:^7.0.1" + checksum: 10c0/ab9c4264443d35b8b923cbdd513a089a60de339216d3b0ed3be3ba57d6880e1a192b70ae17225f764d7adbf5994e9bb8df253a944736c15a0240eff553c678ca + languageName: node + linkType: hard + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: "npm:^5.0.1" + checksum: 10c0/1ae5f212a126fe5b167707f716942490e3933085a5ff6c008ab97ab2f272c8025d3aa218b7bd6ab25729ca20cc81cddb252102f8751e13482a5199e873680952 + languageName: node + linkType: hard + +"strip-ansi@npm:^7.0.1": + version: 7.1.2 + resolution: "strip-ansi@npm:7.1.2" + dependencies: + ansi-regex: "npm:^6.0.1" + checksum: 10c0/0d6d7a023de33368fd042aab0bf48f4f4077abdfd60e5393e73c7c411e85e1b3a83507c11af2e656188511475776215df9ca589b4da2295c9455cc399ce1858b + languageName: node + linkType: hard + +"strip-literal@npm:^3.0.0": + version: 3.0.0 + resolution: "strip-literal@npm:3.0.0" + dependencies: + js-tokens: "npm:^9.0.1" + checksum: 10c0/d81657f84aba42d4bbaf2a677f7e7f34c1f3de5a6726db8bc1797f9c0b303ba54d4660383a74bde43df401cf37cce1dff2c842c55b077a4ceee11f9e31fba828 + languageName: node + linkType: hard + +"supports-color@npm:^7.1.0": + version: 7.2.0 + resolution: "supports-color@npm:7.2.0" + dependencies: + has-flag: "npm:^4.0.0" + checksum: 10c0/afb4c88521b8b136b5f5f95160c98dee7243dc79d5432db7efc27efb219385bbc7d9427398e43dd6cc730a0f87d5085ce1652af7efbe391327bc0a7d0f7fc124 + languageName: node + linkType: hard + +"tar@npm:^7.4.3": + version: 7.4.3 + resolution: "tar@npm:7.4.3" + dependencies: + "@isaacs/fs-minipass": "npm:^4.0.0" + chownr: "npm:^3.0.0" + minipass: "npm:^7.1.2" + minizlib: "npm:^3.0.1" + mkdirp: "npm:^3.0.1" + yallist: "npm:^5.0.0" + checksum: 10c0/d4679609bb2a9b48eeaf84632b6d844128d2412b95b6de07d53d8ee8baf4ca0857c9331dfa510390a0727b550fd543d4d1a10995ad86cdf078423fbb8d99831d + languageName: node + linkType: hard + +"test-exclude@npm:^7.0.1": + version: 7.0.1 + resolution: "test-exclude@npm:7.0.1" + dependencies: + "@istanbuljs/schema": "npm:^0.1.2" + glob: "npm:^10.4.1" + minimatch: "npm:^9.0.4" + checksum: 10c0/6d67b9af4336a2e12b26a68c83308c7863534c65f27ed4ff7068a56f5a58f7ac703e8fc80f698a19bb154fd8f705cdf7ec347d9512b2c522c737269507e7b263 + languageName: node + linkType: hard + +"tinybench@npm:^2.9.0": + version: 2.9.0 + resolution: "tinybench@npm:2.9.0" + checksum: 10c0/c3500b0f60d2eb8db65250afe750b66d51623057ee88720b7f064894a6cb7eb93360ca824a60a31ab16dab30c7b1f06efe0795b352e37914a9d4bad86386a20c + languageName: node + linkType: hard + +"tinyexec@npm:^0.3.2": + version: 0.3.2 + resolution: "tinyexec@npm:0.3.2" + checksum: 10c0/3efbf791a911be0bf0821eab37a3445c2ba07acc1522b1fa84ae1e55f10425076f1290f680286345ed919549ad67527d07281f1c19d584df3b74326909eb1f90 + languageName: node + linkType: hard + +"tinyexec@npm:^1.0.1": + version: 1.0.1 + resolution: "tinyexec@npm:1.0.1" + checksum: 10c0/e1ec3c8194a0427ce001ba69fd933d0c957e2b8994808189ed8020d3e0c01299aea8ecf0083cc514ecbf90754695895f2b5c0eac07eb2d0c406f7d4fbb8feade + languageName: node + linkType: hard + +"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.14, tinyglobby@npm:^0.2.15": + version: 0.2.15 + resolution: "tinyglobby@npm:0.2.15" + dependencies: + fdir: "npm:^6.5.0" + picomatch: "npm:^4.0.3" + checksum: 10c0/869c31490d0d88eedb8305d178d4c75e7463e820df5a9b9d388291daf93e8b1eb5de1dad1c1e139767e4269fe75f3b10d5009b2cc14db96ff98986920a186844 + languageName: node + linkType: hard + +"tinypool@npm:^1.1.1": + version: 1.1.1 + resolution: "tinypool@npm:1.1.1" + checksum: 10c0/bf26727d01443061b04fa863f571016950888ea994ba0cd8cba3a1c51e2458d84574341ab8dbc3664f1c3ab20885c8cf9ff1cc4b18201f04c2cde7d317fff69b + languageName: node + linkType: hard + +"tinyrainbow@npm:^2.0.0": + version: 2.0.0 + resolution: "tinyrainbow@npm:2.0.0" + checksum: 10c0/c83c52bef4e0ae7fb8ec6a722f70b5b6fa8d8be1c85792e829f56c0e1be94ab70b293c032dc5048d4d37cfe678f1f5babb04bdc65fd123098800148ca989184f + languageName: node + linkType: hard + +"tinyspy@npm:^4.0.3": + version: 4.0.3 + resolution: "tinyspy@npm:4.0.3" + checksum: 10c0/0a92a18b5350945cc8a1da3a22c9ad9f4e2945df80aaa0c43e1b3a3cfb64d8501e607ebf0305e048e3c3d3e0e7f8eb10cea27dc17c21effb73e66c4a3be36373 + languageName: node + linkType: hard + +"tree-kill@npm:^1.2.2": + version: 1.2.2 + resolution: "tree-kill@npm:1.2.2" + bin: + tree-kill: cli.js + checksum: 10c0/7b1b7c7f17608a8f8d20a162e7957ac1ef6cd1636db1aba92f4e072dc31818c2ff0efac1e3d91064ede67ed5dc57c565420531a8134090a12ac10cf792ab14d2 + languageName: node + linkType: hard + +"ts-poet@npm:^6.12.0": + version: 6.12.0 + resolution: "ts-poet@npm:6.12.0" + dependencies: + dprint-node: "npm:^1.0.8" + checksum: 10c0/605ac770055259b618ba657b88995f7851d8a6106d9c335e71c8442be51a9b8a87c501aa7ab4babb43700a32ff47dc1cd877f78892c15166ded87c311c878735 + languageName: node + linkType: hard + +"ts-proto-descriptors@npm:2.0.0": + version: 2.0.0 + resolution: "ts-proto-descriptors@npm:2.0.0" + dependencies: + "@bufbuild/protobuf": "npm:^2.0.0" + checksum: 10c0/a4f47a6db7de6b328a5b22bb0bed2a0dac929c28002567613db7980e0a8392b9148530e432a602a8c6b2cfda9909be9568a2e5c545f5624bb5d5eba52031c059 + languageName: node + linkType: hard + +"ts-proto@npm:^2.7.3": + version: 2.7.7 + resolution: "ts-proto@npm:2.7.7" + dependencies: + "@bufbuild/protobuf": "npm:^2.0.0" + case-anything: "npm:^2.1.13" + ts-poet: "npm:^6.12.0" + ts-proto-descriptors: "npm:2.0.0" + bin: + protoc-gen-ts_proto: protoc-gen-ts_proto + checksum: 10c0/fa0daf0b6d635ab87c950c4a1c79722d80cd3d3800e950a6dd36aad68cec4c39a2bb66b96f45c8fe0302672dbb571ffa5a6baa0a05702642e729a382efdc0dbc + languageName: node + linkType: hard + +"tsdown@npm:latest": + version: 0.15.1 + resolution: "tsdown@npm:0.15.1" + dependencies: + ansis: "npm:^4.1.0" + cac: "npm:^6.7.14" + chokidar: "npm:^4.0.3" + debug: "npm:^4.4.1" + diff: "npm:^8.0.2" + empathic: "npm:^2.0.0" + hookable: "npm:^5.5.3" + rolldown: "npm:latest" + rolldown-plugin-dts: "npm:^0.16.5" + semver: "npm:^7.7.2" + tinyexec: "npm:^1.0.1" + tinyglobby: "npm:^0.2.15" + tree-kill: "npm:^1.2.2" + unconfig: "npm:^7.3.3" + peerDependencies: + "@arethetypeswrong/core": ^0.18.1 + publint: ^0.3.0 + typescript: ^5.0.0 + unplugin-lightningcss: ^0.4.0 + unplugin-unused: ^0.5.0 + peerDependenciesMeta: + "@arethetypeswrong/core": + optional: true + publint: + optional: true + typescript: + optional: true + unplugin-lightningcss: + optional: true + unplugin-unused: + optional: true + bin: + tsdown: dist/run.mjs + checksum: 10c0/10aadb974df6bebb28dd952c880c283e92bdf29192044c6995f96b1ccddd0d7d3a26b89d855351381c62a55d462fad79a68000659ce0de4d423efee23b6e13f2 + languageName: node + linkType: hard + +"tslib@npm:^2.4.0": + version: 2.8.1 + resolution: "tslib@npm:2.8.1" + checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 + languageName: node + linkType: hard + +"unconfig@npm:^7.3.3": + version: 7.3.3 + resolution: "unconfig@npm:7.3.3" + dependencies: + "@quansync/fs": "npm:^0.1.5" + defu: "npm:^6.1.4" + jiti: "npm:^2.5.1" + quansync: "npm:^0.2.11" + checksum: 10c0/7c1b0688ce7ba36a92cfeb36f248a61b86e27807b25a4504acc3e0fbf19a217fc74ba80fe45e3205def7648666de51d2b28551e61c86d1c54dcb8e129a011e58 + languageName: node + linkType: hard + +"undici-types@npm:~7.12.0": + version: 7.12.0 + resolution: "undici-types@npm:7.12.0" + checksum: 10c0/326e455bbc0026db1d6b81c76a1cf10c63f7e2f9821db2e24fdc258f482814e5bfa8481f8910d07c68e305937c5c049610fdc441c5e8b7bb0daca7154fb8a306 + languageName: node + linkType: hard + +"unique-filename@npm:^4.0.0": + version: 4.0.0 + resolution: "unique-filename@npm:4.0.0" + dependencies: + unique-slug: "npm:^5.0.0" + checksum: 10c0/38ae681cceb1408ea0587b6b01e29b00eee3c84baee1e41fd5c16b9ed443b80fba90c40e0ba69627e30855570a34ba8b06702d4a35035d4b5e198bf5a64c9ddc + languageName: node + linkType: hard + +"unique-slug@npm:^5.0.0": + version: 5.0.0 + resolution: "unique-slug@npm:5.0.0" + dependencies: + imurmurhash: "npm:^0.1.4" + checksum: 10c0/d324c5a44887bd7e105ce800fcf7533d43f29c48757ac410afd42975de82cc38ea2035c0483f4de82d186691bf3208ef35c644f73aa2b1b20b8e651be5afd293 + languageName: node + linkType: hard + +"vite-node@npm:3.2.4": + version: 3.2.4 + resolution: "vite-node@npm:3.2.4" + dependencies: + cac: "npm:^6.7.14" + debug: "npm:^4.4.1" + es-module-lexer: "npm:^1.7.0" + pathe: "npm:^2.0.3" + vite: "npm:^5.0.0 || ^6.0.0 || ^7.0.0-0" + bin: + vite-node: vite-node.mjs + checksum: 10c0/6ceca67c002f8ef6397d58b9539f80f2b5d79e103a18367288b3f00a8ab55affa3d711d86d9112fce5a7fa658a212a087a005a045eb8f4758947dd99af2a6c6b + languageName: node + linkType: hard + +"vite@npm:^5.0.0 || ^6.0.0 || ^7.0.0-0": + version: 7.1.5 + resolution: "vite@npm:7.1.5" + dependencies: + esbuild: "npm:^0.25.0" + fdir: "npm:^6.5.0" + fsevents: "npm:~2.3.3" + picomatch: "npm:^4.0.3" + postcss: "npm:^8.5.6" + rollup: "npm:^4.43.0" + tinyglobby: "npm:^0.2.15" + peerDependencies: + "@types/node": ^20.19.0 || >=22.12.0 + jiti: ">=1.21.0" + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: ">=0.54.8" + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + dependenciesMeta: + fsevents: + optional: true + peerDependenciesMeta: + "@types/node": + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + bin: + vite: bin/vite.js + checksum: 10c0/782d2f20c25541b26d1fb39bef5f194149caff39dc25b7836e25f049ca919f2e2ce186bddb21f3f20f6195354b3579ec637a8ca08d65b117f8b6f81e3e730a9c + languageName: node + linkType: hard + +"vitest@npm:^3.2.4": + version: 3.2.4 + resolution: "vitest@npm:3.2.4" + dependencies: + "@types/chai": "npm:^5.2.2" + "@vitest/expect": "npm:3.2.4" + "@vitest/mocker": "npm:3.2.4" + "@vitest/pretty-format": "npm:^3.2.4" + "@vitest/runner": "npm:3.2.4" + "@vitest/snapshot": "npm:3.2.4" + "@vitest/spy": "npm:3.2.4" + "@vitest/utils": "npm:3.2.4" + chai: "npm:^5.2.0" + debug: "npm:^4.4.1" + expect-type: "npm:^1.2.1" + magic-string: "npm:^0.30.17" + pathe: "npm:^2.0.3" + picomatch: "npm:^4.0.2" + std-env: "npm:^3.9.0" + tinybench: "npm:^2.9.0" + tinyexec: "npm:^0.3.2" + tinyglobby: "npm:^0.2.14" + tinypool: "npm:^1.1.1" + tinyrainbow: "npm:^2.0.0" + vite: "npm:^5.0.0 || ^6.0.0 || ^7.0.0-0" + vite-node: "npm:3.2.4" + why-is-node-running: "npm:^2.3.0" + peerDependencies: + "@edge-runtime/vm": "*" + "@types/debug": ^4.1.12 + "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 + "@vitest/browser": 3.2.4 + "@vitest/ui": 3.2.4 + happy-dom: "*" + jsdom: "*" + peerDependenciesMeta: + "@edge-runtime/vm": + optional: true + "@types/debug": + optional: true + "@types/node": + optional: true + "@vitest/browser": + optional: true + "@vitest/ui": + optional: true + happy-dom: + optional: true + jsdom: + optional: true + bin: + vitest: vitest.mjs + checksum: 10c0/5bf53ede3ae6a0e08956d72dab279ae90503f6b5a05298a6a5e6ef47d2fd1ab386aaf48fafa61ed07a0ebfe9e371772f1ccbe5c258dd765206a8218bf2eb79eb + languageName: node + linkType: hard + +"which@npm:^2.0.1": + version: 2.0.2 + resolution: "which@npm:2.0.2" + dependencies: + isexe: "npm:^2.0.0" + bin: + node-which: ./bin/node-which + checksum: 10c0/66522872a768b60c2a65a57e8ad184e5372f5b6a9ca6d5f033d4b0dc98aff63995655a7503b9c0a2598936f532120e81dd8cc155e2e92ed662a2b9377cc4374f + languageName: node + linkType: hard + +"which@npm:^5.0.0": + version: 5.0.0 + resolution: "which@npm:5.0.0" + dependencies: + isexe: "npm:^3.1.1" + bin: + node-which: bin/which.js + checksum: 10c0/e556e4cd8b7dbf5df52408c9a9dd5ac6518c8c5267c8953f5b0564073c66ed5bf9503b14d876d0e9c7844d4db9725fb0dcf45d6e911e17e26ab363dc3965ae7b + languageName: node + linkType: hard + +"why-is-node-running@npm:^2.3.0": + version: 2.3.0 + resolution: "why-is-node-running@npm:2.3.0" + dependencies: + siginfo: "npm:^2.0.0" + stackback: "npm:0.0.2" + bin: + why-is-node-running: cli.js + checksum: 10c0/1cde0b01b827d2cf4cb11db962f3958b9175d5d9e7ac7361d1a7b0e2dc6069a263e69118bd974c4f6d0a890ef4eedfe34cf3d5167ec14203dbc9a18620537054 + languageName: node + linkType: hard + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" + dependencies: + ansi-styles: "npm:^4.0.0" + string-width: "npm:^4.1.0" + strip-ansi: "npm:^6.0.0" + checksum: 10c0/d15fc12c11e4cbc4044a552129ebc75ee3f57aa9c1958373a4db0292d72282f54373b536103987a4a7594db1ef6a4f10acf92978f79b98c49306a4b58c77d4da + languageName: node + linkType: hard + +"wrap-ansi@npm:^8.1.0": + version: 8.1.0 + resolution: "wrap-ansi@npm:8.1.0" + dependencies: + ansi-styles: "npm:^6.1.0" + string-width: "npm:^5.0.1" + strip-ansi: "npm:^7.0.1" + checksum: 10c0/138ff58a41d2f877eae87e3282c0630fc2789012fc1af4d6bd626eeb9a2f9a65ca92005e6e69a75c7b85a68479fe7443c7dbe1eb8fbaa681a4491364b7c55c60 + languageName: node + linkType: hard + +"yallist@npm:^4.0.0": + version: 4.0.0 + resolution: "yallist@npm:4.0.0" + checksum: 10c0/2286b5e8dbfe22204ab66e2ef5cc9bbb1e55dfc873bbe0d568aa943eb255d131890dfd5bf243637273d31119b870f49c18fcde2c6ffbb7a7a092b870dc90625a + languageName: node + linkType: hard + +"yallist@npm:^5.0.0": + version: 5.0.0 + resolution: "yallist@npm:5.0.0" + checksum: 10c0/a499c81ce6d4a1d260d4ea0f6d49ab4da09681e32c3f0472dee16667ed69d01dae63a3b81745a24bd78476ec4fcf856114cb4896ace738e01da34b2c42235416 + languageName: node + linkType: hard diff --git a/wasm-msg/src/sync.rs b/wasm-msg/src/sync.rs index 87174cf..3cd49b7 100644 --- a/wasm-msg/src/sync.rs +++ b/wasm-msg/src/sync.rs @@ -8,7 +8,11 @@ where Req: prost::Message + Default, Res: prost::Message, { - let request = message::consume_request::(ptr); + let request = if ptr.is_null() { + Req::default() + } else { + message::consume_request::(ptr) + }; let result = handler(request); message::transfer_response(result) } diff --git a/wasm/node-host/src/index.ts b/wasm/node-host/src/index.ts index ba72028..74a122c 100644 --- a/wasm/node-host/src/index.ts +++ b/wasm/node-host/src/index.ts @@ -22,9 +22,8 @@ const wasmModule = new WebAssembly.Module(wasmBuffer); const api = new ApiBuilder() .guest('set_resolver_state', SetResolverStateRequest, Void, false) + .guestRaw('flush_logs') .guest('resolve', ResolveFlagsRequest, ResolveFlagsResponse, false) - .host('log_resolve', Void, Void, false, () => ({})) - .host('log_assign', Void, Void, false, () => ({})) .host('current_time', Void, Timestamp, false, () => { const now = Date.now(); return { seconds: Math.floor(now / 1000), nanos: (now % 1000) * 1000000 } @@ -40,7 +39,7 @@ api.set_resolver_state({ { const resp = api.resolve({ clientSecret: 'mkjJruAATQWjeY7foFIWfVAcBWnci2YF', - apply: false, + apply: true, evaluationContext: { targeting_key: 'tutorial_visitor', visitor_id: 'tutorial_visitor', @@ -71,5 +70,8 @@ api.set_resolver_state({ } } console.log(`tutorial-feature verified: reason=RESOLVE_REASON_MATCH variant=${rf.variant} title=${titleVal}`); + + const buf = api.flush_logs(new Uint8Array(0)); + fs.writeFileSync('events.bin', buf); } // Done: single flag verified above \ No newline at end of file From 496a36d1d0be92a7d74bf75e82b1c1c7692757ac Mon Sep 17 00:00:00 2001 From: Andreas Karlsson Date: Wed, 24 Sep 2025 02:41:48 +0200 Subject: [PATCH 2/3] fix: missing return types --- openfeature-provider/js/src/ConfidenceServerProviderLocal.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openfeature-provider/js/src/ConfidenceServerProviderLocal.ts b/openfeature-provider/js/src/ConfidenceServerProviderLocal.ts index bdc6c66..cf6b592 100644 --- a/openfeature-provider/js/src/ConfidenceServerProviderLocal.ts +++ b/openfeature-provider/js/src/ConfidenceServerProviderLocal.ts @@ -133,7 +133,7 @@ export class ConfidenceServerProviderLocal implements Provider { }; } - async updateState() { + async updateState():Promise { const { signedUri, account } = await this.stateUriProvider(); const req = new Request(signedUri); if(this.stateEtag) { @@ -155,7 +155,7 @@ export class ConfidenceServerProviderLocal implements Provider { }) } - async flush() { + async flush():Promise { const writeFlagLogRequest = this.resolver.flushLogs(); if(writeFlagLogRequest.length == 0) { // nothing to send From a500483fd822a1c8d7c4d3a6e636df75825db09b Mon Sep 17 00:00:00 2001 From: Nicklas Lundin Date: Thu, 25 Sep 2025 16:02:55 +0200 Subject: [PATCH 3/3] build(js): build js + wasm --- .../workflows/ci-js-openfeature-provider.yml | 68 +++++++++++++++++++ .github/workflows/ci-wasm.yml | 6 ++ 2 files changed, 74 insertions(+) create mode 100644 .github/workflows/ci-js-openfeature-provider.yml diff --git a/.github/workflows/ci-js-openfeature-provider.yml b/.github/workflows/ci-js-openfeature-provider.yml new file mode 100644 index 0000000..c5b7320 --- /dev/null +++ b/.github/workflows/ci-js-openfeature-provider.yml @@ -0,0 +1,68 @@ +name: JS OpenFeature Provider CI + +on: + workflow_run: + workflows: ["WASM CI"] + types: + - completed + branches: [ main ] + pull_request: + paths: + - 'openfeature-provider/js/**' + - '.github/workflows/ci-js-openfeature-provider.yml' + +jobs: + wasm-build: + uses: ./.github/workflows/ci-wasm.yml + if: ${{ github.event_name == 'pull_request' }} + + js-openfeature-provider: + runs-on: ubuntu-latest + needs: wasm-build + if: ${{ always() && (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') || (github.event_name == 'pull_request' && needs.wasm-build.result == 'success') }} + defaults: + run: + working-directory: openfeature-provider/js + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download WASM artifacts (from workflow run) + if: ${{ github.event_name == 'workflow_run' }} + uses: actions/download-artifact@v4 + with: + name: wasm-artifacts + path: wasm/ + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + + - name: Download WASM artifacts (from PR build) + if: ${{ github.event_name == 'pull_request' }} + uses: actions/download-artifact@v4 + with: + name: wasm-artifacts + path: wasm/ + + - name: Setup protoc + uses: arduino/setup-protoc@v3 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + + - name: Enable Corepack + run: corepack enable + + - name: Install dependencies + run: yarn install --immutable + + - name: Generate protobuf types + run: yarn proto:gen + + - name: Build + run: yarn build + + - name: Test + run: yarn test \ No newline at end of file diff --git a/.github/workflows/ci-wasm.yml b/.github/workflows/ci-wasm.yml index a486ccb..3500926 100644 --- a/.github/workflows/ci-wasm.yml +++ b/.github/workflows/ci-wasm.yml @@ -55,3 +55,9 @@ jobs: - name: clippy run: make lint + + - name: Upload WASM artifacts + uses: actions/upload-artifact@v4 + with: + name: wasm-artifacts + path: wasm/confidence_resolver.wasm