@soda-gql/common 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/canonical-id-BFcryTw5.cjs +2 -1
- package/dist/canonical-id-BFcryTw5.cjs.map +1 -0
- package/dist/{canonical-id/index.cjs → canonical-id.cjs} +2 -2
- package/dist/{canonical-id/index.d.cts → canonical-id.d.cts} +1 -1
- package/dist/{canonical-id/index.d.mts → canonical-id.d.mts} +1 -1
- package/dist/{canonical-id/index.mjs → canonical-id.mjs} +2 -2
- package/dist/index.cjs +2 -1
- package/dist/index.cjs.map +1 -0
- package/dist/portable-C_7gJWmz.cjs +2 -1
- package/dist/portable-C_7gJWmz.cjs.map +1 -0
- package/dist/portable-Dbo3u2CQ.mjs.map +1 -1
- package/dist/{portable/index.cjs → portable.cjs} +1 -1
- package/dist/{portable/index.d.cts → portable.d.cts} +1 -1
- package/dist/{portable/index.d.mts → portable.d.mts} +1 -1
- package/dist/{portable/index.mjs → portable.mjs} +1 -1
- package/dist/utils-CmLf7LU5.cjs +2 -1
- package/dist/utils-CmLf7LU5.cjs.map +1 -0
- package/dist/{utils/index.cjs → utils.cjs} +1 -1
- package/dist/{utils/index.d.cts → utils.d.cts} +1 -1
- package/dist/{utils/index.d.mts → utils.d.mts} +1 -1
- package/dist/{utils/index.mjs → utils.mjs} +1 -1
- package/dist/zod-CynYgOoN.cjs +2 -1
- package/dist/zod-CynYgOoN.cjs.map +1 -0
- package/dist/zod.cjs +3 -0
- package/dist/zod.d.cts +2 -0
- package/dist/zod.d.mts +2 -0
- package/dist/zod.mjs +3 -0
- package/package.json +49 -29
- package/dist/zod/index.cjs +0 -3
- package/dist/zod/index.d.cts +0 -2
- package/dist/zod/index.d.mts +0 -2
- package/dist/zod/index.mjs +0 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonical-id-BFcryTw5.cjs","names":["CanonicalIdSchema: z.ZodType<CanonicalId>","z","normalizePath","scopeStack: ScopeFrame[]","frame: ScopeFrame","exportBinding: string | undefined"],"sources":["../src/canonical-id/canonical-id.ts","../src/canonical-id/path-tracker.ts"],"sourcesContent":["import { isAbsolute, resolve } from \"node:path\";\nimport z from \"zod\";\nimport { normalizePath } from \"../utils\";\n\nexport type CanonicalId = string & { readonly __brand: \"CanonicalId\" };\n\nconst canonicalIdSeparator = \"::\" as const;\n\nexport const CanonicalIdSchema: z.ZodType<CanonicalId> = z.string() as unknown as z.ZodType<CanonicalId>;\n\n// Type-safe schema for CanonicalId - validates as string but types as branded\nexport const createCanonicalId = (filePath: string, astPath: string): CanonicalId => {\n if (!isAbsolute(filePath)) {\n throw new Error(\"[INTERNAL] CANONICAL_ID_REQUIRES_ABSOLUTE_PATH\");\n }\n\n const resolved = resolve(filePath);\n const normalized = normalizePath(resolved);\n\n // Create a 2-part ID: {absPath}::{astPath}\n // astPath uniquely identifies the definition's location in the AST (e.g., \"MyComponent.useQuery.def\")\n const idParts = [normalized, astPath];\n\n return idParts.join(canonicalIdSeparator) as CanonicalId;\n};\n","/**\n * Canonical path tracker for AST traversal.\n *\n * This module provides a stateful helper that tracks scope information during\n * AST traversal to generate canonical IDs. It's designed to integrate with\n * existing plugin visitor patterns (Babel, SWC, TypeScript) without requiring\n * a separate AST traversal.\n *\n * Usage pattern:\n * 1. Plugin creates tracker at file/program entry\n * 2. Plugin calls enterScope/exitScope during its traversal\n * 3. Plugin calls registerDefinition when discovering GQL definitions\n * 4. Tracker provides canonical ID information\n */\n\nimport type { CanonicalId } from \"./canonical-id\";\nimport { createCanonicalId } from \"./canonical-id\";\n\n/**\n * Scope frame for tracking AST path segments\n */\nexport type ScopeFrame = {\n /** Name segment (e.g., \"MyComponent\", \"useQuery\", \"arrow#1\") */\n readonly nameSegment: string;\n /** Kind of scope */\n readonly kind: \"function\" | \"class\" | \"variable\" | \"property\" | \"method\" | \"expression\";\n /** Occurrence index for disambiguation */\n readonly occurrence: number;\n};\n\n/**\n * Opaque handle for scope tracking\n */\nexport type ScopeHandle = {\n readonly __brand: \"ScopeHandle\";\n readonly depth: number;\n};\n\n/**\n * Canonical path tracker interface\n */\nexport interface CanonicalPathTracker {\n /**\n * Enter a new scope during traversal\n * @param options Scope information\n * @returns Handle to use when exiting the scope\n */\n enterScope(options: { segment: string; kind: ScopeFrame[\"kind\"]; stableKey?: string }): ScopeHandle;\n\n /**\n * Exit a scope during traversal\n * @param handle Handle returned from enterScope\n */\n exitScope(handle: ScopeHandle): void;\n\n /**\n * Register a definition discovered during traversal\n * @returns Definition metadata including astPath and canonical ID information\n */\n registerDefinition(): {\n astPath: string;\n isTopLevel: boolean;\n exportBinding?: string;\n };\n\n /**\n * Resolve a canonical ID from an astPath\n * @param astPath AST path string\n * @returns Canonical ID\n */\n resolveCanonicalId(astPath: string): CanonicalId;\n\n /**\n * Register an export binding\n * @param local Local variable name\n * @param exported Exported name\n */\n registerExportBinding(local: string, exported: string): void;\n\n /**\n * Get current scope depth\n * @returns Current depth (0 = top level)\n */\n currentDepth(): number;\n}\n\n/**\n * Build AST path from scope stack (internal helper)\n */\nconst _buildAstPath = (stack: readonly ScopeFrame[]): string => {\n return stack.map((frame) => frame.nameSegment).join(\".\");\n};\n\n/**\n * Create a canonical path tracker\n *\n * @param options Configuration options\n * @returns Tracker instance\n *\n * @example\n * ```typescript\n * // In a Babel plugin\n * const tracker = createCanonicalTracker({ filePath: state.filename });\n *\n * const visitor = {\n * FunctionDeclaration: {\n * enter(path) {\n * const handle = tracker.enterScope({\n * segment: path.node.id.name,\n * kind: 'function'\n * });\n * },\n * exit(path) {\n * tracker.exitScope(handle);\n * }\n * }\n * };\n * ```\n */\nexport const createCanonicalTracker = (options: {\n filePath: string;\n getExportName?: (localName: string) => string | undefined;\n}): CanonicalPathTracker => {\n const { filePath, getExportName } = options;\n\n // Scope stack\n const scopeStack: ScopeFrame[] = [];\n\n // Occurrence counters for disambiguating duplicate names\n const occurrenceCounters = new Map<string, number>();\n\n // Used paths for ensuring uniqueness\n const usedPaths = new Set<string>();\n\n // Export bindings map\n const exportBindings = new Map<string, string>();\n\n const getNextOccurrence = (key: string): number => {\n const current = occurrenceCounters.get(key) ?? 0;\n occurrenceCounters.set(key, current + 1);\n return current;\n };\n\n const ensureUniquePath = (basePath: string): string => {\n let path = basePath;\n let suffix = 0;\n while (usedPaths.has(path)) {\n suffix++;\n path = `${basePath}$${suffix}`;\n }\n usedPaths.add(path);\n return path;\n };\n\n return {\n enterScope({ segment, kind, stableKey }): ScopeHandle {\n const key = stableKey ?? `${kind}:${segment}`;\n const occurrence = getNextOccurrence(key);\n\n const frame: ScopeFrame = {\n nameSegment: segment,\n kind,\n occurrence,\n };\n\n scopeStack.push(frame);\n\n return {\n __brand: \"ScopeHandle\",\n depth: scopeStack.length - 1,\n } as ScopeHandle;\n },\n\n exitScope(handle: ScopeHandle): void {\n // Validate handle depth matches current stack\n if (handle.depth !== scopeStack.length - 1) {\n throw new Error(`[INTERNAL] Invalid scope exit: expected depth ${scopeStack.length - 1}, got ${handle.depth}`);\n }\n scopeStack.pop();\n },\n\n registerDefinition(): {\n astPath: string;\n isTopLevel: boolean;\n exportBinding?: string;\n } {\n const basePath = _buildAstPath(scopeStack);\n const astPath = ensureUniquePath(basePath);\n const isTopLevel = scopeStack.length === 0;\n\n // Check export binding if provided\n let exportBinding: string | undefined;\n if (getExportName && isTopLevel) {\n // For top-level definitions, try to get export name\n // This is a simplified version - real logic depends on how the definition is bound\n exportBinding = undefined;\n }\n\n return {\n astPath,\n isTopLevel,\n exportBinding,\n };\n },\n\n resolveCanonicalId(astPath: string): CanonicalId {\n return createCanonicalId(filePath, astPath);\n },\n\n registerExportBinding(local: string, exported: string): void {\n exportBindings.set(local, exported);\n },\n\n currentDepth(): number {\n return scopeStack.length;\n },\n };\n};\n\n/**\n * Helper to create occurrence tracker (for backward compatibility)\n */\nexport const createOccurrenceTracker = (): {\n getNextOccurrence: (key: string) => number;\n} => {\n const occurrenceCounters = new Map<string, number>();\n\n return {\n getNextOccurrence(key: string): number {\n const current = occurrenceCounters.get(key) ?? 0;\n occurrenceCounters.set(key, current + 1);\n return current;\n },\n };\n};\n\n/**\n * Helper to create path tracker (for backward compatibility)\n */\nexport const createPathTracker = (): {\n ensureUniquePath: (basePath: string) => string;\n} => {\n const usedPaths = new Set<string>();\n\n return {\n ensureUniquePath(basePath: string): string {\n let path = basePath;\n let suffix = 0;\n while (usedPaths.has(path)) {\n suffix++;\n path = `${basePath}$${suffix}`;\n }\n usedPaths.add(path);\n return path;\n },\n };\n};\n\n/**\n * Build AST path from scope stack (for backward compatibility)\n */\nexport const buildAstPath = (stack: readonly ScopeFrame[]): string => {\n return stack.map((frame) => frame.nameSegment).join(\".\");\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,MAAM,uBAAuB;AAE7B,MAAaA,oBAA4CC,YAAE,QAAQ;AAGnE,MAAa,qBAAqB,UAAkB,YAAiC;AACnF,KAAI,2BAAY,SAAS,EAAE;AACzB,QAAM,IAAI,MAAM,iDAAiD;;CAGnE,MAAM,kCAAmB,SAAS;CAClC,MAAM,aAAaC,4BAAc,SAAS;CAI1C,MAAM,UAAU,CAAC,YAAY,QAAQ;AAErC,QAAO,QAAQ,KAAK,qBAAqB;;;;;;;;ACkE3C,MAAM,iBAAiB,UAAyC;AAC9D,QAAO,MAAM,KAAK,UAAU,MAAM,YAAY,CAAC,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6B1D,MAAa,0BAA0B,YAGX;CAC1B,MAAM,EAAE,UAAU,kBAAkB;CAGpC,MAAMC,aAA2B,EAAE;CAGnC,MAAM,qBAAqB,IAAI,KAAqB;CAGpD,MAAM,YAAY,IAAI,KAAa;CAGnC,MAAM,iBAAiB,IAAI,KAAqB;CAEhD,MAAM,qBAAqB,QAAwB;EACjD,MAAM,UAAU,mBAAmB,IAAI,IAAI,IAAI;AAC/C,qBAAmB,IAAI,KAAK,UAAU,EAAE;AACxC,SAAO;;CAGT,MAAM,oBAAoB,aAA6B;EACrD,IAAI,OAAO;EACX,IAAI,SAAS;AACb,SAAO,UAAU,IAAI,KAAK,EAAE;AAC1B;AACA,UAAO,GAAG,SAAS,GAAG;;AAExB,YAAU,IAAI,KAAK;AACnB,SAAO;;AAGT,QAAO;EACL,WAAW,EAAE,SAAS,MAAM,aAA0B;GACpD,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG;GACpC,MAAM,aAAa,kBAAkB,IAAI;GAEzC,MAAMC,QAAoB;IACxB,aAAa;IACb;IACA;IACD;AAED,cAAW,KAAK,MAAM;AAEtB,UAAO;IACL,SAAS;IACT,OAAO,WAAW,SAAS;IAC5B;;EAGH,UAAU,QAA2B;AAEnC,OAAI,OAAO,UAAU,WAAW,SAAS,GAAG;AAC1C,UAAM,IAAI,MAAM,iDAAiD,WAAW,SAAS,EAAE,QAAQ,OAAO,QAAQ;;AAEhH,cAAW,KAAK;;EAGlB,qBAIE;GACA,MAAM,WAAW,cAAc,WAAW;GAC1C,MAAM,UAAU,iBAAiB,SAAS;GAC1C,MAAM,aAAa,WAAW,WAAW;GAGzC,IAAIC;AACJ,OAAI,iBAAiB,YAAY;AAG/B,oBAAgB;;AAGlB,UAAO;IACL;IACA;IACA;IACD;;EAGH,mBAAmB,SAA8B;AAC/C,UAAO,kBAAkB,UAAU,QAAQ;;EAG7C,sBAAsB,OAAe,UAAwB;AAC3D,kBAAe,IAAI,OAAO,SAAS;;EAGrC,eAAuB;AACrB,UAAO,WAAW;;EAErB;;;;;AAMH,MAAa,gCAER;CACH,MAAM,qBAAqB,IAAI,KAAqB;AAEpD,QAAO,EACL,kBAAkB,KAAqB;EACrC,MAAM,UAAU,mBAAmB,IAAI,IAAI,IAAI;AAC/C,qBAAmB,IAAI,KAAK,UAAU,EAAE;AACxC,SAAO;IAEV;;;;;AAMH,MAAa,0BAER;CACH,MAAM,YAAY,IAAI,KAAa;AAEnC,QAAO,EACL,iBAAiB,UAA0B;EACzC,IAAI,OAAO;EACX,IAAI,SAAS;AACb,SAAO,UAAU,IAAI,KAAK,EAAE;AAC1B;AACA,UAAO,GAAG,SAAS,GAAG;;AAExB,YAAU,IAAI,KAAK;AACnB,SAAO;IAEV;;;;;AAMH,MAAa,gBAAgB,UAAyC;AACpE,QAAO,MAAM,KAAK,UAAU,MAAM,YAAY,CAAC,KAAK,IAAI"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const require_canonical_id = require('
|
|
2
|
-
require('
|
|
1
|
+
const require_canonical_id = require('./canonical-id-BFcryTw5.cjs');
|
|
2
|
+
require('./utils-CmLf7LU5.cjs');
|
|
3
3
|
|
|
4
4
|
exports.CanonicalIdSchema = require_canonical_id.CanonicalIdSchema;
|
|
5
5
|
exports.buildAstPath = require_canonical_id.buildAstPath;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as createCanonicalTracker, c as CanonicalId, i as buildAstPath, l as CanonicalIdSchema, n as ScopeFrame, o as createOccurrenceTracker, r as ScopeHandle, s as createPathTracker, t as CanonicalPathTracker, u as createCanonicalId } from "
|
|
1
|
+
import { a as createCanonicalTracker, c as CanonicalId, i as buildAstPath, l as CanonicalIdSchema, n as ScopeFrame, o as createOccurrenceTracker, r as ScopeHandle, s as createPathTracker, t as CanonicalPathTracker, u as createCanonicalId } from "./index-BG7Aiges.cjs";
|
|
2
2
|
export { CanonicalId, CanonicalIdSchema, CanonicalPathTracker, ScopeFrame, ScopeHandle, buildAstPath, createCanonicalId, createCanonicalTracker, createOccurrenceTracker, createPathTracker };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as createCanonicalTracker, c as CanonicalId, i as buildAstPath, l as CanonicalIdSchema, n as ScopeFrame, o as createOccurrenceTracker, r as ScopeHandle, s as createPathTracker, t as CanonicalPathTracker, u as createCanonicalId } from "
|
|
1
|
+
import { a as createCanonicalTracker, c as CanonicalId, i as buildAstPath, l as CanonicalIdSchema, n as ScopeFrame, o as createOccurrenceTracker, r as ScopeHandle, s as createPathTracker, t as CanonicalPathTracker, u as createCanonicalId } from "./index-C4t2Wbzs.mjs";
|
|
2
2
|
export { CanonicalId, CanonicalIdSchema, CanonicalPathTracker, ScopeFrame, ScopeHandle, buildAstPath, createCanonicalId, createCanonicalTracker, createOccurrenceTracker, createPathTracker };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "
|
|
2
|
-
import { a as CanonicalIdSchema, i as createPathTracker, n as createCanonicalTracker, o as createCanonicalId, r as createOccurrenceTracker, t as buildAstPath } from "
|
|
1
|
+
import "./utils-DLEgAn7q.mjs";
|
|
2
|
+
import { a as CanonicalIdSchema, i as createPathTracker, n as createCanonicalTracker, o as createCanonicalId, r as createOccurrenceTracker, t as buildAstPath } from "./canonical-id-BFnyQGST.mjs";
|
|
3
3
|
|
|
4
4
|
export { CanonicalIdSchema, buildAstPath, createCanonicalId, createCanonicalTracker, createOccurrenceTracker, createPathTracker };
|
package/dist/index.cjs
CHANGED
|
@@ -290,4 +290,5 @@ exports.resetPortableForTests = require_portable.resetPortableForTests;
|
|
|
290
290
|
exports.resolveRelativeImportWithExistenceCheck = require_utils.resolveRelativeImportWithExistenceCheck;
|
|
291
291
|
exports.resolveRelativeImportWithReferences = require_utils.resolveRelativeImportWithReferences;
|
|
292
292
|
exports.runtime = require_portable.runtime;
|
|
293
|
-
exports.spawn = require_portable.spawn;
|
|
293
|
+
exports.spawn = require_portable.spawn;
|
|
294
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["isSchedulerError","pureValue: T","promise: Promise<T>","effects: readonly Effect<unknown>[]"],"sources":["../src/scheduler/types.ts","../src/scheduler/async-scheduler.ts","../src/scheduler/effect.ts","../src/scheduler/sync-scheduler.ts"],"sourcesContent":["import type { Result } from \"neverthrow\";\n\n/**\n * Abstract base class for all effects.\n * Effects encapsulate both the data and the execution logic.\n *\n * @template TResult - The type of value this effect produces when executed\n *\n * @example\n * ```typescript\n * function* myGenerator() {\n * const value = yield* new PureEffect(42).run();\n * return value; // 42\n * }\n * ```\n */\nexport abstract class Effect<TResult = unknown> {\n /**\n * Execute the effect synchronously and return the result.\n */\n executeSync(): TResult {\n return this._executeSync();\n }\n\n /**\n * Execute the effect asynchronously and return the result.\n */\n async executeAsync(): Promise<TResult> {\n return this._executeAsync();\n }\n\n /**\n * Returns a generator that yields this effect and returns the result.\n * Enables the `yield*` pattern for cleaner effect handling.\n *\n * @example\n * ```typescript\n * const value = yield* effect.run();\n * ```\n */\n *run(): Generator<Effect<TResult>, TResult, EffectReturn> {\n return EffectReturn.unwrap((yield this) as EffectReturn<TResult>);\n }\n\n /**\n * Internal synchronous execution logic.\n * Subclasses must implement this method.\n */\n protected abstract _executeSync(): TResult;\n\n /**\n * Internal asynchronous execution logic.\n * Subclasses must implement this method.\n */\n protected abstract _executeAsync(): Promise<TResult>;\n}\n\nconst EFFECT_RETURN = Symbol(\"EffectReturn\");\nexport class EffectReturn<TResult = unknown> {\n private readonly [EFFECT_RETURN]: TResult;\n\n private constructor(value: TResult) {\n this[EFFECT_RETURN] = value;\n }\n\n static wrap<TResult>(value: TResult): EffectReturn<TResult> {\n return new EffectReturn(value);\n }\n\n static unwrap<TResult>(value: EffectReturn<TResult>): TResult {\n return value[EFFECT_RETURN];\n }\n}\n\n/**\n * Extract the result type from an Effect.\n */\nexport type EffectResult<E> = E extends Effect<infer T> ? T : never;\n\n/**\n * Generator type that yields Effects.\n */\nexport type EffectGenerator<TReturn> = Generator<Effect, TReturn, EffectReturn>;\n\n/**\n * Generator function type that creates an EffectGenerator.\n */\nexport type EffectGeneratorFn<TReturn> = () => EffectGenerator<TReturn>;\n\n/**\n * Error type for scheduler operations.\n */\nexport type SchedulerError = {\n readonly kind: \"scheduler-error\";\n readonly message: string;\n readonly cause?: unknown;\n};\n\n/**\n * Create a SchedulerError.\n */\nexport const createSchedulerError = (message: string, cause?: unknown): SchedulerError => ({\n kind: \"scheduler-error\",\n message,\n cause,\n});\n\n/**\n * Synchronous scheduler interface.\n * Throws if an async-only effect (defer, yield) is encountered.\n */\nexport interface SyncScheduler {\n run<TReturn>(generatorFn: EffectGeneratorFn<TReturn>): Result<TReturn, SchedulerError>;\n}\n\n/**\n * Asynchronous scheduler interface.\n * Handles all effect types including defer, yield, and parallel.\n */\nexport interface AsyncScheduler {\n run<TReturn>(generatorFn: EffectGeneratorFn<TReturn>): Promise<Result<TReturn, SchedulerError>>;\n}\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { AsyncScheduler, Effect, EffectGeneratorFn, SchedulerError } from \"./types\";\nimport { createSchedulerError, EffectReturn } from \"./types\";\n\n/**\n * Create an asynchronous scheduler.\n *\n * This scheduler can handle all effect types including defer and yield.\n * Parallel effects are executed concurrently using Promise.all.\n *\n * @returns An AsyncScheduler instance\n *\n * @example\n * const scheduler = createAsyncScheduler();\n * const result = await scheduler.run(function* () {\n * const data = yield* new DeferEffect(fetch('/api/data').then(r => r.json())).run();\n * yield* new YieldEffect().run(); // Yield to event loop\n * return data;\n * });\n */\nexport const createAsyncScheduler = (): AsyncScheduler => {\n const run = async <TReturn>(generatorFn: EffectGeneratorFn<TReturn>): Promise<Result<TReturn, SchedulerError>> => {\n try {\n const generator = generatorFn();\n let result = generator.next();\n\n while (!result.done) {\n const effect = result.value as Effect<unknown>;\n const effectResult = await effect.executeAsync();\n result = generator.next(EffectReturn.wrap(effectResult));\n }\n\n return ok(result.value);\n } catch (error) {\n if (isSchedulerError(error)) {\n return err(error);\n }\n return err(createSchedulerError(error instanceof Error ? error.message : String(error), error));\n }\n };\n\n return { run };\n};\n\n/**\n * Type guard for SchedulerError.\n */\nconst isSchedulerError = (error: unknown): error is SchedulerError => {\n return typeof error === \"object\" && error !== null && (error as SchedulerError).kind === \"scheduler-error\";\n};\n","import { Effect } from \"./types\";\n\n/**\n * Pure effect - returns a value immediately.\n * Works in both sync and async schedulers.\n *\n * @example\n * const result = yield* new PureEffect(42).run(); // 42\n */\nexport class PureEffect<T> extends Effect<T> {\n constructor(readonly pureValue: T) {\n super();\n }\n\n protected _executeSync(): T {\n return this.pureValue;\n }\n\n protected _executeAsync(): Promise<T> {\n return Promise.resolve(this.pureValue);\n }\n}\n\n/**\n * Defer effect - wraps a Promise for async execution.\n * Only works in async schedulers; throws in sync schedulers.\n *\n * @example\n * const data = yield* new DeferEffect(fetch('/api/data').then(r => r.json())).run();\n */\nexport class DeferEffect<T> extends Effect<T> {\n constructor(readonly promise: Promise<T>) {\n super();\n }\n\n protected _executeSync(): T {\n throw new Error(\"DeferEffect is not supported in sync scheduler. Use AsyncScheduler instead.\");\n }\n\n protected _executeAsync(): Promise<T> {\n return this.promise;\n }\n}\n\n/**\n * Parallel effect - executes multiple effects concurrently.\n * In sync schedulers, effects are executed sequentially.\n * In async schedulers, effects are executed with Promise.all.\n *\n * @example\n * const results = yield* new ParallelEffect([new PureEffect(1), new PureEffect(2)]).run(); // [1, 2]\n */\nexport class ParallelEffect extends Effect<readonly unknown[]> {\n constructor(readonly effects: readonly Effect<unknown>[]) {\n super();\n }\n\n protected _executeSync(): readonly unknown[] {\n return this.effects.map((e) => e.executeSync());\n }\n\n protected async _executeAsync(): Promise<readonly unknown[]> {\n return Promise.all(this.effects.map((e) => e.executeAsync()));\n }\n}\n\n/**\n * Yield effect - yields control back to the event loop.\n * This helps prevent blocking the event loop in long-running operations.\n * Only works in async schedulers; throws in sync schedulers.\n *\n * @example\n * for (let i = 0; i < 10000; i++) {\n * doWork(i);\n * if (i % 100 === 0) {\n * yield* new YieldEffect().run();\n * }\n * }\n */\nexport class YieldEffect extends Effect<void> {\n protected _executeSync(): void {\n throw new Error(\"YieldEffect is not supported in sync scheduler. Use AsyncScheduler instead.\");\n }\n\n protected async _executeAsync(): Promise<void> {\n await new Promise<void>((resolve) => {\n if (typeof setImmediate !== \"undefined\") {\n setImmediate(resolve);\n } else {\n setTimeout(resolve, 0);\n }\n });\n }\n}\n\n/**\n * Effect factory namespace for convenience.\n * Provides static methods to create effects.\n */\nexport const Effects = {\n /**\n * Create a pure effect that returns a value immediately.\n */\n pure: <T>(value: T): PureEffect<T> => new PureEffect(value),\n\n /**\n * Create a defer effect that wraps a Promise.\n */\n defer: <T>(promise: Promise<T>): DeferEffect<T> => new DeferEffect(promise),\n\n /**\n * Create a parallel effect that executes multiple effects concurrently.\n */\n parallel: (effects: readonly Effect<unknown>[]): ParallelEffect => new ParallelEffect(effects),\n\n /**\n * Create a yield effect that returns control to the event loop.\n */\n yield: (): YieldEffect => new YieldEffect(),\n} as const;\n","import { err, ok, type Result } from \"neverthrow\";\nimport type { Effect, EffectGeneratorFn, SchedulerError, SyncScheduler } from \"./types\";\nimport { createSchedulerError, EffectReturn } from \"./types\";\n\n/**\n * Create a synchronous scheduler.\n *\n * This scheduler executes generators synchronously.\n * It throws an error if an async-only effect (defer, yield) is encountered.\n *\n * @returns A SyncScheduler instance\n *\n * @example\n * const scheduler = createSyncScheduler();\n * const result = scheduler.run(function* () {\n * const a = yield* new PureEffect(1).run();\n * const b = yield* new PureEffect(2).run();\n * return a + b;\n * });\n * // result = ok(3)\n */\nexport const createSyncScheduler = (): SyncScheduler => {\n const run = <TReturn>(generatorFn: EffectGeneratorFn<TReturn>): Result<TReturn, SchedulerError> => {\n try {\n const generator = generatorFn();\n let result = generator.next();\n\n while (!result.done) {\n const effect = result.value as Effect<unknown>;\n const effectResult = effect.executeSync();\n result = generator.next(EffectReturn.wrap(effectResult));\n }\n\n return ok(result.value);\n } catch (error) {\n if (isSchedulerError(error)) {\n return err(error);\n }\n return err(createSchedulerError(error instanceof Error ? error.message : String(error), error));\n }\n };\n\n return { run };\n};\n\n/**\n * Type guard for SchedulerError.\n */\nconst isSchedulerError = (error: unknown): error is SchedulerError => {\n return typeof error === \"object\" && error !== null && (error as SchedulerError).kind === \"scheduler-error\";\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portable-C_7gJWmz.cjs","names":["result: T | undefined","fsInstance: PortableFS | null","crypto","hasherInstance: PortableHasher | null","crypto","execOptions: {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n encoding: BufferEncoding;\n }","error: unknown"],"sources":["../src/portable/runtime.ts","../src/portable/fs.ts","../src/portable/hash.ts","../src/portable/id.ts","../src/portable/spawn.ts"],"sourcesContent":["/**\n * Runtime detection utilities for portable API implementation\n */\n\nexport const runtime = {\n isBun: typeof Bun !== \"undefined\",\n isNode: typeof process !== \"undefined\" && typeof Bun === \"undefined\",\n supportsWebCrypto: typeof crypto !== \"undefined\" && typeof crypto.subtle !== \"undefined\",\n} as const;\n\n/**\n * Helper to cache module imports to avoid repeated dynamic imports\n */\nexport function once<T>(fn: () => T): () => T {\n let result: T | undefined;\n let called = false;\n\n return () => {\n if (!called) {\n result = fn();\n called = true;\n }\n return result as T;\n };\n}\n\n/**\n * Reset runtime state for testing purposes only\n * @internal\n */\nexport function resetPortableForTests(): void {\n // This is a marker function that portable modules can use\n // to reset their singleton state in tests\n}\n","/**\n * Portable filesystem API that works on both Bun and Node.js\n */\n\nimport { once, runtime } from \"./runtime\";\n\nexport interface PortableFS {\n readFile(path: string): Promise<string>;\n writeFile(path: string, content: string): Promise<void>;\n exists(path: string): Promise<boolean>;\n stat(path: string): Promise<{ mtime: Date; size: number }>;\n rename(oldPath: string, newPath: string): Promise<void>;\n mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;\n}\n\ninterface FSPromises {\n readFile: (path: string, encoding: string) => Promise<string>;\n writeFile: (path: string, content: string, encoding: string) => Promise<void>;\n access: (path: string) => Promise<void>;\n stat: (path: string) => Promise<{\n mtime: Date;\n size: number;\n isDirectory: () => boolean;\n }>;\n rename: (oldPath: string, newPath: string) => Promise<void>;\n mkdir: (path: string, options?: { recursive?: boolean }) => Promise<void>;\n}\n\n// Cache the fs/promises import\nconst getNodeFS = once(async (): Promise<FSPromises> => {\n const fs = await import(\"node:fs/promises\");\n return fs as FSPromises;\n});\n\nexport function createPortableFS(): PortableFS {\n if (runtime.isBun) {\n return {\n async readFile(path) {\n const file = Bun.file(path);\n return await file.text();\n },\n\n async writeFile(path, content) {\n // Bun.write auto-creates parent directories\n await Bun.write(path, content);\n },\n\n async exists(path) {\n // Bun.file().exists() only works for files, use fs.stat for both files and dirs\n const nodeFS = await getNodeFS();\n try {\n await nodeFS.stat(path);\n return true;\n } catch {\n return false;\n }\n },\n\n async stat(path) {\n const file = Bun.file(path);\n const size = file.size;\n // Bun doesn't expose mtime directly, use Node fs.stat\n const nodeFS = await getNodeFS();\n const { mtime } = await nodeFS.stat(path);\n return { mtime, size };\n },\n\n async rename(oldPath, newPath) {\n const nodeFS = await getNodeFS();\n await nodeFS.rename(oldPath, newPath);\n },\n\n async mkdir(path, options) {\n const nodeFS = await getNodeFS();\n await nodeFS.mkdir(path, options);\n },\n };\n }\n\n // Node.js implementation\n return {\n async readFile(path) {\n const nodeFS = await getNodeFS();\n return await nodeFS.readFile(path, \"utf-8\");\n },\n\n async writeFile(path, content) {\n const nodeFS = await getNodeFS();\n // Auto-create parent directories like Bun.write does\n const pathModule = await import(\"node:path\");\n const dir = pathModule.dirname(path);\n await nodeFS.mkdir(dir, { recursive: true });\n await nodeFS.writeFile(path, content, \"utf-8\");\n },\n\n async exists(path) {\n const nodeFS = await getNodeFS();\n try {\n await nodeFS.access(path);\n return true;\n } catch {\n return false;\n }\n },\n\n async stat(path) {\n const nodeFS = await getNodeFS();\n const stats = await nodeFS.stat(path);\n return { mtime: stats.mtime, size: stats.size };\n },\n\n async rename(oldPath, newPath) {\n const nodeFS = await getNodeFS();\n await nodeFS.rename(oldPath, newPath);\n },\n\n async mkdir(path, options) {\n const nodeFS = await getNodeFS();\n await nodeFS.mkdir(path, options);\n },\n };\n}\n\n// Singleton to avoid recreating instances\nlet fsInstance: PortableFS | null = null;\n\nexport function getPortableFS(): PortableFS {\n if (!fsInstance) {\n fsInstance = createPortableFS();\n }\n return fsInstance;\n}\n\n/**\n * Reset the filesystem singleton for testing\n * @internal\n */\nexport function __resetPortableFSForTests(): void {\n fsInstance = null;\n}\n","/**\n * Portable hashing API that works on both Bun and Node.js\n */\n\nimport { runtime } from \"./runtime\";\n\nexport type HashAlgorithm = \"sha256\" | \"xxhash\";\n\nexport interface PortableHasher {\n hash(content: string, algorithm?: HashAlgorithm): string;\n}\n\n/**\n * Pads a hex string to the specified length\n */\nfunction padHex(hex: string, length: number): string {\n return hex.padStart(length, \"0\");\n}\n\nexport function createPortableHasher(): PortableHasher {\n if (runtime.isBun) {\n return {\n hash(content, algorithm = \"xxhash\") {\n if (algorithm === \"sha256\") {\n const hasher = new Bun.CryptoHasher(\"sha256\");\n hasher.update(content);\n return hasher.digest(\"hex\");\n }\n // xxhash - Bun.hash returns a number\n const hashNum = Bun.hash(content);\n // Convert to hex and pad to 16 chars for consistency\n return padHex(hashNum.toString(16), 16);\n },\n };\n }\n\n // Node.js implementation\n return {\n hash(content, algorithm = \"xxhash\") {\n if (algorithm === \"sha256\") {\n const crypto = require(\"node:crypto\");\n return crypto.createHash(\"sha256\").update(content).digest(\"hex\");\n }\n // xxhash fallback: use sha256 for now (can add xxhash package later if needed)\n // This ensures consistent behavior across runtimes\n const crypto = require(\"node:crypto\");\n const sha256Hash = crypto.createHash(\"sha256\").update(content).digest(\"hex\");\n // Take first 16 chars to match xxhash output length\n return sha256Hash.substring(0, 16);\n },\n };\n}\n\n// Singleton to avoid recreating instances\nlet hasherInstance: PortableHasher | null = null;\n\nexport function getPortableHasher(): PortableHasher {\n if (!hasherInstance) {\n hasherInstance = createPortableHasher();\n }\n return hasherInstance;\n}\n\n/**\n * Reset the hasher singleton for testing\n * @internal\n */\nexport function __resetPortableHasherForTests(): void {\n hasherInstance = null;\n}\n","/**\n * Portable ID generation that works on both Bun and Node.js\n */\n\nimport { runtime } from \"./runtime\";\n\n/**\n * Generate a unique ID\n * Uses UUIDv7 on Bun (monotonic), falls back to randomUUID on Node.js\n */\nexport function generateId(): string {\n if (runtime.isBun && typeof Bun !== \"undefined\" && typeof Bun.randomUUIDv7 === \"function\") {\n return Bun.randomUUIDv7();\n }\n\n // Node.js fallback: use crypto.randomUUID\n const crypto = require(\"node:crypto\");\n return crypto.randomUUID();\n}\n","/**\n * Portable subprocess spawning that works on both Bun and Node.js\n */\n\nimport { runtime } from \"./runtime\";\n\nexport interface SpawnOptions {\n cmd: string[];\n cwd?: string;\n env?: Record<string, string>;\n}\n\nexport interface SpawnResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n}\n\nexport async function spawn(options: SpawnOptions): Promise<SpawnResult> {\n if (runtime.isBun) {\n const proc = Bun.spawn(options.cmd, {\n cwd: options.cwd,\n env: options.env,\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n\n const [stdout, stderr] = await Promise.all([new Response(proc.stdout).text(), new Response(proc.stderr).text()]);\n\n const exitCode = await proc.exited;\n\n return { stdout, stderr, exitCode };\n }\n\n // Node.js implementation\n const { execFile } = await import(\"node:child_process\");\n const { promisify } = await import(\"node:util\");\n const execFilePromise = promisify(execFile);\n\n const [command, ...args] = options.cmd;\n if (!command) {\n return {\n stdout: \"\",\n stderr: \"Error: No command provided\",\n exitCode: 1,\n };\n }\n\n try {\n const execOptions: {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n encoding: BufferEncoding;\n } = {\n encoding: \"utf-8\",\n };\n\n if (options.cwd) {\n execOptions.cwd = options.cwd;\n }\n if (options.env) {\n execOptions.env = options.env as NodeJS.ProcessEnv;\n }\n\n const { stdout, stderr } = await execFilePromise(command, args, execOptions);\n return {\n stdout: stdout || \"\",\n stderr: stderr || \"\",\n exitCode: 0,\n };\n } catch (error: unknown) {\n const err = error as {\n stdout?: string;\n stderr?: string;\n code?: number;\n };\n return {\n stdout: err.stdout || \"\",\n stderr: err.stderr || \"\",\n exitCode: err.code || 1,\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portable-Dbo3u2CQ.mjs","names":["result: T | undefined","fsInstance: PortableFS | null","crypto","hasherInstance: PortableHasher | null","crypto","execOptions: {\n cwd?: string;\n env?: Record<string, string>;\n encoding: BufferEncoding;\n }","error: unknown"],"sources":["../src/portable/runtime.ts","../src/portable/fs.ts","../src/portable/hash.ts","../src/portable/id.ts","../src/portable/spawn.ts"],"sourcesContent":["/**\n * Runtime detection utilities for portable API implementation\n */\n\nexport const runtime = {\n isBun: typeof Bun !== \"undefined\",\n isNode: typeof process !== \"undefined\" && typeof Bun === \"undefined\",\n supportsWebCrypto: typeof crypto !== \"undefined\" && typeof crypto.subtle !== \"undefined\",\n} as const;\n\n/**\n * Helper to cache module imports to avoid repeated dynamic imports\n */\nexport function once<T>(fn: () => T): () => T {\n let result: T | undefined;\n let called = false;\n\n return () => {\n if (!called) {\n result = fn();\n called = true;\n }\n return result as T;\n };\n}\n\n/**\n * Reset runtime state for testing purposes only\n * @internal\n */\nexport function resetPortableForTests(): void {\n // This is a marker function that portable modules can use\n // to reset their singleton state in tests\n}\n","/**\n * Portable filesystem API that works on both Bun and Node.js\n */\n\nimport { once, runtime } from \"./runtime\";\n\nexport interface PortableFS {\n readFile(path: string): Promise<string>;\n writeFile(path: string, content: string): Promise<void>;\n exists(path: string): Promise<boolean>;\n stat(path: string): Promise<{ mtime: Date; size: number }>;\n rename(oldPath: string, newPath: string): Promise<void>;\n mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;\n}\n\ninterface FSPromises {\n readFile: (path: string, encoding: string) => Promise<string>;\n writeFile: (path: string, content: string, encoding: string) => Promise<void>;\n access: (path: string) => Promise<void>;\n stat: (path: string) => Promise<{\n mtime: Date;\n size: number;\n isDirectory: () => boolean;\n }>;\n rename: (oldPath: string, newPath: string) => Promise<void>;\n mkdir: (path: string, options?: { recursive?: boolean }) => Promise<void>;\n}\n\n// Cache the fs/promises import\nconst getNodeFS = once(async (): Promise<FSPromises> => {\n const fs = await import(\"node:fs/promises\");\n return fs as FSPromises;\n});\n\nexport function createPortableFS(): PortableFS {\n if (runtime.isBun) {\n return {\n async readFile(path) {\n const file = Bun.file(path);\n return await file.text();\n },\n\n async writeFile(path, content) {\n // Bun.write auto-creates parent directories\n await Bun.write(path, content);\n },\n\n async exists(path) {\n // Bun.file().exists() only works for files, use fs.stat for both files and dirs\n const nodeFS = await getNodeFS();\n try {\n await nodeFS.stat(path);\n return true;\n } catch {\n return false;\n }\n },\n\n async stat(path) {\n const file = Bun.file(path);\n const size = file.size;\n // Bun doesn't expose mtime directly, use Node fs.stat\n const nodeFS = await getNodeFS();\n const { mtime } = await nodeFS.stat(path);\n return { mtime, size };\n },\n\n async rename(oldPath, newPath) {\n const nodeFS = await getNodeFS();\n await nodeFS.rename(oldPath, newPath);\n },\n\n async mkdir(path, options) {\n const nodeFS = await getNodeFS();\n await nodeFS.mkdir(path, options);\n },\n };\n }\n\n // Node.js implementation\n return {\n async readFile(path) {\n const nodeFS = await getNodeFS();\n return await nodeFS.readFile(path, \"utf-8\");\n },\n\n async writeFile(path, content) {\n const nodeFS = await getNodeFS();\n // Auto-create parent directories like Bun.write does\n const pathModule = await import(\"node:path\");\n const dir = pathModule.dirname(path);\n await nodeFS.mkdir(dir, { recursive: true });\n await nodeFS.writeFile(path, content, \"utf-8\");\n },\n\n async exists(path) {\n const nodeFS = await getNodeFS();\n try {\n await nodeFS.access(path);\n return true;\n } catch {\n return false;\n }\n },\n\n async stat(path) {\n const nodeFS = await getNodeFS();\n const stats = await nodeFS.stat(path);\n return { mtime: stats.mtime, size: stats.size };\n },\n\n async rename(oldPath, newPath) {\n const nodeFS = await getNodeFS();\n await nodeFS.rename(oldPath, newPath);\n },\n\n async mkdir(path, options) {\n const nodeFS = await getNodeFS();\n await nodeFS.mkdir(path, options);\n },\n };\n}\n\n// Singleton to avoid recreating instances\nlet fsInstance: PortableFS | null = null;\n\nexport function getPortableFS(): PortableFS {\n if (!fsInstance) {\n fsInstance = createPortableFS();\n }\n return fsInstance;\n}\n\n/**\n * Reset the filesystem singleton for testing\n * @internal\n */\nexport function __resetPortableFSForTests(): void {\n fsInstance = null;\n}\n","/**\n * Portable hashing API that works on both Bun and Node.js\n */\n\nimport { runtime } from \"./runtime\";\n\nexport type HashAlgorithm = \"sha256\" | \"xxhash\";\n\nexport interface PortableHasher {\n hash(content: string, algorithm?: HashAlgorithm): string;\n}\n\n/**\n * Pads a hex string to the specified length\n */\nfunction padHex(hex: string, length: number): string {\n return hex.padStart(length, \"0\");\n}\n\nexport function createPortableHasher(): PortableHasher {\n if (runtime.isBun) {\n return {\n hash(content, algorithm = \"xxhash\") {\n if (algorithm === \"sha256\") {\n const hasher = new Bun.CryptoHasher(\"sha256\");\n hasher.update(content);\n return hasher.digest(\"hex\");\n }\n // xxhash - Bun.hash returns a number\n const hashNum = Bun.hash(content);\n // Convert to hex and pad to 16 chars for consistency\n return padHex(hashNum.toString(16), 16);\n },\n };\n }\n\n // Node.js implementation\n return {\n hash(content, algorithm = \"xxhash\") {\n if (algorithm === \"sha256\") {\n const crypto = require(\"node:crypto\");\n return crypto.createHash(\"sha256\").update(content).digest(\"hex\");\n }\n // xxhash fallback: use sha256 for now (can add xxhash package later if needed)\n // This ensures consistent behavior across runtimes\n const crypto = require(\"node:crypto\");\n const sha256Hash = crypto.createHash(\"sha256\").update(content).digest(\"hex\");\n // Take first 16 chars to match xxhash output length\n return sha256Hash.substring(0, 16);\n },\n };\n}\n\n// Singleton to avoid recreating instances\nlet hasherInstance: PortableHasher | null = null;\n\nexport function getPortableHasher(): PortableHasher {\n if (!hasherInstance) {\n hasherInstance = createPortableHasher();\n }\n return hasherInstance;\n}\n\n/**\n * Reset the hasher singleton for testing\n * @internal\n */\nexport function __resetPortableHasherForTests(): void {\n hasherInstance = null;\n}\n","/**\n * Portable ID generation that works on both Bun and Node.js\n */\n\nimport { runtime } from \"./runtime\";\n\n/**\n * Generate a unique ID\n * Uses UUIDv7 on Bun (monotonic), falls back to randomUUID on Node.js\n */\nexport function generateId(): string {\n if (runtime.isBun && typeof Bun !== \"undefined\" && typeof Bun.randomUUIDv7 === \"function\") {\n return Bun.randomUUIDv7();\n }\n\n // Node.js fallback: use crypto.randomUUID\n const crypto = require(\"node:crypto\");\n return crypto.randomUUID();\n}\n","/**\n * Portable subprocess spawning that works on both Bun and Node.js\n */\n\nimport { runtime } from \"./runtime\";\n\nexport interface SpawnOptions {\n cmd: string[];\n cwd?: string;\n env?: Record<string, string>;\n}\n\nexport interface SpawnResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n}\n\nexport async function spawn(options: SpawnOptions): Promise<SpawnResult> {\n if (runtime.isBun) {\n const proc = Bun.spawn(options.cmd, {\n cwd: options.cwd,\n env: options.env,\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n\n const [stdout, stderr] = await Promise.all([new Response(proc.stdout).text(), new Response(proc.stderr).text()]);\n\n const exitCode = await proc.exited;\n\n return { stdout, stderr, exitCode };\n }\n\n // Node.js implementation\n const { execFile } = await import(\"node:child_process\");\n const { promisify } = await import(\"node:util\");\n const execFilePromise = promisify(execFile);\n\n const [command, ...args] = options.cmd;\n if (!command) {\n return {\n stdout: \"\",\n stderr: \"Error: No command provided\",\n exitCode: 1,\n };\n }\n\n try {\n const execOptions: {\n cwd?: string;\n env?: Record<string, string>;\n encoding: BufferEncoding;\n } = {\n encoding: \"utf-8\",\n };\n\n if (options.cwd) {\n execOptions.cwd = options.cwd;\n }\n if (options.env) {\n execOptions.env = options.env;\n }\n\n const { stdout, stderr } = await execFilePromise(command, args, execOptions);\n return {\n stdout: stdout || \"\",\n stderr: stderr || \"\",\n exitCode: 0,\n };\n } catch (error: unknown) {\n const err = error as {\n stdout?: string;\n stderr?: string;\n code?: number;\n };\n return {\n stdout: err.stdout || \"\",\n stderr: err.stderr || \"\",\n exitCode: err.code || 1,\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"portable-Dbo3u2CQ.mjs","names":["result: T | undefined","fsInstance: PortableFS | null","crypto","hasherInstance: PortableHasher | null","crypto","execOptions: {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n encoding: BufferEncoding;\n }","error: unknown"],"sources":["../src/portable/runtime.ts","../src/portable/fs.ts","../src/portable/hash.ts","../src/portable/id.ts","../src/portable/spawn.ts"],"sourcesContent":["/**\n * Runtime detection utilities for portable API implementation\n */\n\nexport const runtime = {\n isBun: typeof Bun !== \"undefined\",\n isNode: typeof process !== \"undefined\" && typeof Bun === \"undefined\",\n supportsWebCrypto: typeof crypto !== \"undefined\" && typeof crypto.subtle !== \"undefined\",\n} as const;\n\n/**\n * Helper to cache module imports to avoid repeated dynamic imports\n */\nexport function once<T>(fn: () => T): () => T {\n let result: T | undefined;\n let called = false;\n\n return () => {\n if (!called) {\n result = fn();\n called = true;\n }\n return result as T;\n };\n}\n\n/**\n * Reset runtime state for testing purposes only\n * @internal\n */\nexport function resetPortableForTests(): void {\n // This is a marker function that portable modules can use\n // to reset their singleton state in tests\n}\n","/**\n * Portable filesystem API that works on both Bun and Node.js\n */\n\nimport { once, runtime } from \"./runtime\";\n\nexport interface PortableFS {\n readFile(path: string): Promise<string>;\n writeFile(path: string, content: string): Promise<void>;\n exists(path: string): Promise<boolean>;\n stat(path: string): Promise<{ mtime: Date; size: number }>;\n rename(oldPath: string, newPath: string): Promise<void>;\n mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;\n}\n\ninterface FSPromises {\n readFile: (path: string, encoding: string) => Promise<string>;\n writeFile: (path: string, content: string, encoding: string) => Promise<void>;\n access: (path: string) => Promise<void>;\n stat: (path: string) => Promise<{\n mtime: Date;\n size: number;\n isDirectory: () => boolean;\n }>;\n rename: (oldPath: string, newPath: string) => Promise<void>;\n mkdir: (path: string, options?: { recursive?: boolean }) => Promise<void>;\n}\n\n// Cache the fs/promises import\nconst getNodeFS = once(async (): Promise<FSPromises> => {\n const fs = await import(\"node:fs/promises\");\n return fs as FSPromises;\n});\n\nexport function createPortableFS(): PortableFS {\n if (runtime.isBun) {\n return {\n async readFile(path) {\n const file = Bun.file(path);\n return await file.text();\n },\n\n async writeFile(path, content) {\n // Bun.write auto-creates parent directories\n await Bun.write(path, content);\n },\n\n async exists(path) {\n // Bun.file().exists() only works for files, use fs.stat for both files and dirs\n const nodeFS = await getNodeFS();\n try {\n await nodeFS.stat(path);\n return true;\n } catch {\n return false;\n }\n },\n\n async stat(path) {\n const file = Bun.file(path);\n const size = file.size;\n // Bun doesn't expose mtime directly, use Node fs.stat\n const nodeFS = await getNodeFS();\n const { mtime } = await nodeFS.stat(path);\n return { mtime, size };\n },\n\n async rename(oldPath, newPath) {\n const nodeFS = await getNodeFS();\n await nodeFS.rename(oldPath, newPath);\n },\n\n async mkdir(path, options) {\n const nodeFS = await getNodeFS();\n await nodeFS.mkdir(path, options);\n },\n };\n }\n\n // Node.js implementation\n return {\n async readFile(path) {\n const nodeFS = await getNodeFS();\n return await nodeFS.readFile(path, \"utf-8\");\n },\n\n async writeFile(path, content) {\n const nodeFS = await getNodeFS();\n // Auto-create parent directories like Bun.write does\n const pathModule = await import(\"node:path\");\n const dir = pathModule.dirname(path);\n await nodeFS.mkdir(dir, { recursive: true });\n await nodeFS.writeFile(path, content, \"utf-8\");\n },\n\n async exists(path) {\n const nodeFS = await getNodeFS();\n try {\n await nodeFS.access(path);\n return true;\n } catch {\n return false;\n }\n },\n\n async stat(path) {\n const nodeFS = await getNodeFS();\n const stats = await nodeFS.stat(path);\n return { mtime: stats.mtime, size: stats.size };\n },\n\n async rename(oldPath, newPath) {\n const nodeFS = await getNodeFS();\n await nodeFS.rename(oldPath, newPath);\n },\n\n async mkdir(path, options) {\n const nodeFS = await getNodeFS();\n await nodeFS.mkdir(path, options);\n },\n };\n}\n\n// Singleton to avoid recreating instances\nlet fsInstance: PortableFS | null = null;\n\nexport function getPortableFS(): PortableFS {\n if (!fsInstance) {\n fsInstance = createPortableFS();\n }\n return fsInstance;\n}\n\n/**\n * Reset the filesystem singleton for testing\n * @internal\n */\nexport function __resetPortableFSForTests(): void {\n fsInstance = null;\n}\n","/**\n * Portable hashing API that works on both Bun and Node.js\n */\n\nimport { runtime } from \"./runtime\";\n\nexport type HashAlgorithm = \"sha256\" | \"xxhash\";\n\nexport interface PortableHasher {\n hash(content: string, algorithm?: HashAlgorithm): string;\n}\n\n/**\n * Pads a hex string to the specified length\n */\nfunction padHex(hex: string, length: number): string {\n return hex.padStart(length, \"0\");\n}\n\nexport function createPortableHasher(): PortableHasher {\n if (runtime.isBun) {\n return {\n hash(content, algorithm = \"xxhash\") {\n if (algorithm === \"sha256\") {\n const hasher = new Bun.CryptoHasher(\"sha256\");\n hasher.update(content);\n return hasher.digest(\"hex\");\n }\n // xxhash - Bun.hash returns a number\n const hashNum = Bun.hash(content);\n // Convert to hex and pad to 16 chars for consistency\n return padHex(hashNum.toString(16), 16);\n },\n };\n }\n\n // Node.js implementation\n return {\n hash(content, algorithm = \"xxhash\") {\n if (algorithm === \"sha256\") {\n const crypto = require(\"node:crypto\");\n return crypto.createHash(\"sha256\").update(content).digest(\"hex\");\n }\n // xxhash fallback: use sha256 for now (can add xxhash package later if needed)\n // This ensures consistent behavior across runtimes\n const crypto = require(\"node:crypto\");\n const sha256Hash = crypto.createHash(\"sha256\").update(content).digest(\"hex\");\n // Take first 16 chars to match xxhash output length\n return sha256Hash.substring(0, 16);\n },\n };\n}\n\n// Singleton to avoid recreating instances\nlet hasherInstance: PortableHasher | null = null;\n\nexport function getPortableHasher(): PortableHasher {\n if (!hasherInstance) {\n hasherInstance = createPortableHasher();\n }\n return hasherInstance;\n}\n\n/**\n * Reset the hasher singleton for testing\n * @internal\n */\nexport function __resetPortableHasherForTests(): void {\n hasherInstance = null;\n}\n","/**\n * Portable ID generation that works on both Bun and Node.js\n */\n\nimport { runtime } from \"./runtime\";\n\n/**\n * Generate a unique ID\n * Uses UUIDv7 on Bun (monotonic), falls back to randomUUID on Node.js\n */\nexport function generateId(): string {\n if (runtime.isBun && typeof Bun !== \"undefined\" && typeof Bun.randomUUIDv7 === \"function\") {\n return Bun.randomUUIDv7();\n }\n\n // Node.js fallback: use crypto.randomUUID\n const crypto = require(\"node:crypto\");\n return crypto.randomUUID();\n}\n","/**\n * Portable subprocess spawning that works on both Bun and Node.js\n */\n\nimport { runtime } from \"./runtime\";\n\nexport interface SpawnOptions {\n cmd: string[];\n cwd?: string;\n env?: Record<string, string>;\n}\n\nexport interface SpawnResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n}\n\nexport async function spawn(options: SpawnOptions): Promise<SpawnResult> {\n if (runtime.isBun) {\n const proc = Bun.spawn(options.cmd, {\n cwd: options.cwd,\n env: options.env,\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n\n const [stdout, stderr] = await Promise.all([new Response(proc.stdout).text(), new Response(proc.stderr).text()]);\n\n const exitCode = await proc.exited;\n\n return { stdout, stderr, exitCode };\n }\n\n // Node.js implementation\n const { execFile } = await import(\"node:child_process\");\n const { promisify } = await import(\"node:util\");\n const execFilePromise = promisify(execFile);\n\n const [command, ...args] = options.cmd;\n if (!command) {\n return {\n stdout: \"\",\n stderr: \"Error: No command provided\",\n exitCode: 1,\n };\n }\n\n try {\n const execOptions: {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n encoding: BufferEncoding;\n } = {\n encoding: \"utf-8\",\n };\n\n if (options.cwd) {\n execOptions.cwd = options.cwd;\n }\n if (options.env) {\n execOptions.env = options.env as NodeJS.ProcessEnv;\n }\n\n const { stdout, stderr } = await execFilePromise(command, args, execOptions);\n return {\n stdout: stdout || \"\",\n stderr: stderr || \"\",\n exitCode: 0,\n };\n } catch (error: unknown) {\n const err = error as {\n stdout?: string;\n stderr?: string;\n code?: number;\n };\n return {\n stdout: err.stdout || \"\",\n stderr: err.stderr || \"\",\n exitCode: err.code || 1,\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_portable = require('
|
|
1
|
+
const require_portable = require('./portable-C_7gJWmz.cjs');
|
|
2
2
|
|
|
3
3
|
exports.__resetPortableFSForTests = require_portable.__resetPortableFSForTests;
|
|
4
4
|
exports.__resetPortableHasherForTests = require_portable.__resetPortableHasherForTests;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as resetPortableForTests, c as HashAlgorithm, d as createPortableHasher, f as getPortableHasher, g as getPortableFS, h as createPortableFS, i as once, l as PortableHasher, m as __resetPortableFSForTests, n as SpawnResult, o as runtime, p as PortableFS, r as spawn, s as generateId, t as SpawnOptions, u as __resetPortableHasherForTests } from "
|
|
1
|
+
import { a as resetPortableForTests, c as HashAlgorithm, d as createPortableHasher, f as getPortableHasher, g as getPortableFS, h as createPortableFS, i as once, l as PortableHasher, m as __resetPortableFSForTests, n as SpawnResult, o as runtime, p as PortableFS, r as spawn, s as generateId, t as SpawnOptions, u as __resetPortableHasherForTests } from "./index-DaAp2rNj.cjs";
|
|
2
2
|
export { HashAlgorithm, PortableFS, PortableHasher, SpawnOptions, SpawnResult, __resetPortableFSForTests, __resetPortableHasherForTests, createPortableFS, createPortableHasher, generateId, getPortableFS, getPortableHasher, once, resetPortableForTests, runtime, spawn };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as resetPortableForTests, c as HashAlgorithm, d as createPortableHasher, f as getPortableHasher, g as getPortableFS, h as createPortableFS, i as once, l as PortableHasher, m as __resetPortableFSForTests, n as SpawnResult, o as runtime, p as PortableFS, r as spawn, s as generateId, t as SpawnOptions, u as __resetPortableHasherForTests } from "
|
|
1
|
+
import { a as resetPortableForTests, c as HashAlgorithm, d as createPortableHasher, f as getPortableHasher, g as getPortableFS, h as createPortableFS, i as once, l as PortableHasher, m as __resetPortableFSForTests, n as SpawnResult, o as runtime, p as PortableFS, r as spawn, s as generateId, t as SpawnOptions, u as __resetPortableHasherForTests } from "./index-BedBpKbv.mjs";
|
|
2
2
|
export { HashAlgorithm, PortableFS, PortableHasher, SpawnOptions, SpawnResult, __resetPortableFSForTests, __resetPortableHasherForTests, createPortableFS, createPortableHasher, generateId, getPortableFS, getPortableHasher, once, resetPortableForTests, runtime, spawn };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as getPortableHasher, c as getPortableFS, d as runtime, i as createPortableHasher, l as once, n as generateId, o as __resetPortableFSForTests, r as __resetPortableHasherForTests, s as createPortableFS, t as spawn, u as resetPortableForTests } from "
|
|
1
|
+
import { a as getPortableHasher, c as getPortableFS, d as runtime, i as createPortableHasher, l as once, n as generateId, o as __resetPortableFSForTests, r as __resetPortableHasherForTests, s as createPortableFS, t as spawn, u as resetPortableForTests } from "./portable-Dbo3u2CQ.mjs";
|
|
2
2
|
|
|
3
3
|
export { __resetPortableFSForTests, __resetPortableHasherForTests, createPortableFS, createPortableHasher, generateId, getPortableFS, getPortableHasher, once, resetPortableForTests, runtime, spawn };
|
package/dist/utils-CmLf7LU5.cjs
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils-CmLf7LU5.cjs","names":["cached: { value: T } | null"],"sources":["../src/utils/cached-fn.ts","../src/utils/path.ts"],"sourcesContent":["export const cachedFn = <T>(fn: () => T) => {\n let cached: { value: T } | null = null;\n\n const ensure = () => (cached ??= { value: fn() }).value;\n ensure.clear = () => {\n cached = null;\n };\n\n return ensure;\n};\n","import { existsSync, statSync } from \"node:fs\";\nimport { dirname, join, normalize, resolve } from \"node:path\";\n\n/**\n * File extensions to try when resolving module specifiers.\n * Ordered to match TypeScript's module resolution order.\n * @see https://www.typescriptlang.org/docs/handbook/module-resolution.html\n */\nexport const MODULE_EXTENSION_CANDIDATES = [\".ts\", \".tsx\", \".mts\", \".cts\", \".js\", \".mjs\", \".cjs\", \".jsx\"] as const;\n\n/**\n * Normalize path to use forward slashes (cross-platform).\n * Ensures consistent path handling across platforms.\n */\nexport const normalizePath = (value: string): string => normalize(value).replace(/\\\\/g, \"/\");\n\n/**\n * Resolve a relative import specifier to an absolute file path.\n * Tries the specifier as-is, with extensions, and as a directory with index files.\n *\n * @param from - Absolute path to the importing file\n * @param specifier - Relative module specifier (must start with '.')\n * @returns Absolute POSIX path to the resolved file, or null if not found\n */\nexport const resolveRelativeImportWithExistenceCheck = ({\n filePath,\n specifier,\n}: {\n filePath: string;\n specifier: string;\n}): string | null => {\n const base = resolve(dirname(filePath), specifier);\n\n // Try with extensions first (most common case)\n // This handles cases like \"./constants\" resolving to \"./constants.ts\"\n // even when a \"./constants\" directory exists\n for (const ext of MODULE_EXTENSION_CANDIDATES) {\n const candidate = `${base}${ext}`;\n if (existsSync(candidate)) {\n return normalizePath(candidate);\n }\n }\n\n // Try as directory with index files\n for (const ext of MODULE_EXTENSION_CANDIDATES) {\n const candidate = join(base, `index${ext}`);\n if (existsSync(candidate)) {\n return normalizePath(candidate);\n }\n }\n\n // Try exact path last (only if it's a file, not directory)\n if (existsSync(base)) {\n try {\n const stat = statSync(base);\n if (stat.isFile()) {\n return normalizePath(base);\n }\n } catch {\n // Ignore stat errors\n }\n }\n\n return null;\n};\n\n/**\n * Resolve a relative import specifier to an absolute file path.\n * Tries the specifier as-is, with extensions, and as a directory with index files.\n *\n * @param from - Absolute path to the importing file\n * @param specifier - Relative module specifier (must start with '.')\n * @returns Absolute POSIX path to the resolved file, or null if not found\n */\nexport const resolveRelativeImportWithReferences = <_>({\n filePath,\n specifier,\n references,\n}: {\n filePath: string;\n specifier: string;\n references: Map<string, _> | Set<string>;\n}): string | null => {\n const base = resolve(dirname(filePath), specifier);\n\n // Try exact path first\n if (references.has(base)) {\n return normalizePath(base);\n }\n\n // Try with extensions\n for (const ext of MODULE_EXTENSION_CANDIDATES) {\n const candidate = `${base}${ext}`;\n if (references.has(candidate)) {\n return normalizePath(candidate);\n }\n }\n\n // Try as directory with index files\n for (const ext of MODULE_EXTENSION_CANDIDATES) {\n const candidate = join(base, `index${ext}`);\n if (references.has(candidate)) {\n return normalizePath(candidate);\n }\n }\n\n return null;\n};\n\n/**\n * Check if a module specifier is relative (starts with '.' or '..')\n */\nexport const isRelativeSpecifier = (specifier: string): boolean => specifier.startsWith(\"./\") || specifier.startsWith(\"../\");\n\n/**\n * Check if a module specifier is external (package name, not relative)\n */\nexport const isExternalSpecifier = (specifier: string): boolean => !isRelativeSpecifier(specifier);\n"],"mappings":";;;;;AAAA,MAAa,YAAe,OAAgB;CAC1C,IAAIA,SAA8B;CAElC,MAAM,gBAAgB,WAAW,EAAE,OAAO,IAAI,EAAE,EAAE;AAClD,QAAO,cAAc;AACnB,WAAS;;AAGX,QAAO;;;;;;;;;;ACAT,MAAa,8BAA8B;CAAC;CAAO;CAAQ;CAAQ;CAAQ;CAAO;CAAQ;CAAQ;CAAO;;;;;AAMzG,MAAa,iBAAiB,mCAAoC,MAAM,CAAC,QAAQ,OAAO,IAAI;;;;;;;;;AAU5F,MAAa,2CAA2C,EACtD,UACA,gBAImB;CACnB,MAAM,qDAAuB,SAAS,EAAE,UAAU;AAKlD,MAAK,MAAM,OAAO,6BAA6B;EAC7C,MAAM,YAAY,GAAG,OAAO;AAC5B,8BAAe,UAAU,EAAE;AACzB,UAAO,cAAc,UAAU;;;AAKnC,MAAK,MAAM,OAAO,6BAA6B;EAC7C,MAAM,gCAAiB,MAAM,QAAQ,MAAM;AAC3C,8BAAe,UAAU,EAAE;AACzB,UAAO,cAAc,UAAU;;;AAKnC,6BAAe,KAAK,EAAE;AACpB,MAAI;GACF,MAAM,6BAAgB,KAAK;AAC3B,OAAI,KAAK,QAAQ,EAAE;AACjB,WAAO,cAAc,KAAK;;UAEtB;;AAKV,QAAO;;;;;;;;;;AAWT,MAAa,uCAA0C,EACrD,UACA,WACA,iBAKmB;CACnB,MAAM,qDAAuB,SAAS,EAAE,UAAU;AAGlD,KAAI,WAAW,IAAI,KAAK,EAAE;AACxB,SAAO,cAAc,KAAK;;AAI5B,MAAK,MAAM,OAAO,6BAA6B;EAC7C,MAAM,YAAY,GAAG,OAAO;AAC5B,MAAI,WAAW,IAAI,UAAU,EAAE;AAC7B,UAAO,cAAc,UAAU;;;AAKnC,MAAK,MAAM,OAAO,6BAA6B;EAC7C,MAAM,gCAAiB,MAAM,QAAQ,MAAM;AAC3C,MAAI,WAAW,IAAI,UAAU,EAAE;AAC7B,UAAO,cAAc,UAAU;;;AAInC,QAAO;;;;;AAMT,MAAa,uBAAuB,cAA+B,UAAU,WAAW,KAAK,IAAI,UAAU,WAAW,MAAM;;;;AAK5H,MAAa,uBAAuB,cAA+B,CAAC,oBAAoB,UAAU"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as resolveRelativeImportWithExistenceCheck, i as normalizePath, n as isExternalSpecifier, o as resolveRelativeImportWithReferences, r as isRelativeSpecifier, s as cachedFn, t as MODULE_EXTENSION_CANDIDATES } from "
|
|
1
|
+
import { a as resolveRelativeImportWithExistenceCheck, i as normalizePath, n as isExternalSpecifier, o as resolveRelativeImportWithReferences, r as isRelativeSpecifier, s as cachedFn, t as MODULE_EXTENSION_CANDIDATES } from "./index-LaXfl_e_.cjs";
|
|
2
2
|
export { MODULE_EXTENSION_CANDIDATES, cachedFn, isExternalSpecifier, isRelativeSpecifier, normalizePath, resolveRelativeImportWithExistenceCheck, resolveRelativeImportWithReferences };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as resolveRelativeImportWithExistenceCheck, i as normalizePath, n as isExternalSpecifier, o as resolveRelativeImportWithReferences, r as isRelativeSpecifier, s as cachedFn, t as MODULE_EXTENSION_CANDIDATES } from "
|
|
1
|
+
import { a as resolveRelativeImportWithExistenceCheck, i as normalizePath, n as isExternalSpecifier, o as resolveRelativeImportWithReferences, r as isRelativeSpecifier, s as cachedFn, t as MODULE_EXTENSION_CANDIDATES } from "./index-Dv8spPt0.mjs";
|
|
2
2
|
export { MODULE_EXTENSION_CANDIDATES, cachedFn, isExternalSpecifier, isRelativeSpecifier, normalizePath, resolveRelativeImportWithExistenceCheck, resolveRelativeImportWithReferences };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as resolveRelativeImportWithExistenceCheck, i as normalizePath, n as isExternalSpecifier, o as resolveRelativeImportWithReferences, r as isRelativeSpecifier, s as cachedFn, t as MODULE_EXTENSION_CANDIDATES } from "
|
|
1
|
+
import { a as resolveRelativeImportWithExistenceCheck, i as normalizePath, n as isExternalSpecifier, o as resolveRelativeImportWithReferences, r as isRelativeSpecifier, s as cachedFn, t as MODULE_EXTENSION_CANDIDATES } from "./utils-DLEgAn7q.mjs";
|
|
2
2
|
|
|
3
3
|
export { MODULE_EXTENSION_CANDIDATES, cachedFn, isExternalSpecifier, isRelativeSpecifier, normalizePath, resolveRelativeImportWithExistenceCheck, resolveRelativeImportWithReferences };
|
package/dist/zod-CynYgOoN.cjs
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod-CynYgOoN.cjs","names":["z"],"sources":["../src/zod/schema-helper.ts"],"sourcesContent":["import { z } from \"zod\";\n\n// biome-ignore lint/suspicious/noExplicitAny: abstract type\nexport type SchemaFor<TOutput> = z.ZodType<TOutput, any, any>;\n\nexport type ShapeFor<TOutput extends object> = { [K in keyof TOutput]-?: SchemaFor<TOutput[K]> };\n\nexport function defineSchemaFor<TOutput extends object>() {\n return <TShape extends ShapeFor<NoInfer<TOutput>>>(shape: TShape & { [K in Exclude<keyof TShape, keyof TOutput>]: never }) =>\n z.object(shape).strict();\n}\n"],"mappings":";;;;AAOA,SAAgB,kBAA0C;AACxD,SAAmD,UACjDA,MAAE,OAAO,MAAM,CAAC,QAAQ"}
|
package/dist/zod.cjs
ADDED
package/dist/zod.d.cts
ADDED
package/dist/zod.d.mts
ADDED
package/dist/zod.mjs
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soda-gql/common",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Shared utilities for soda-gql packages",
|
|
4
5
|
"type": "module",
|
|
5
6
|
"private": false,
|
|
6
7
|
"license": "MIT",
|
|
@@ -12,47 +13,66 @@
|
|
|
12
13
|
"email": "shota.hatada@whatasoda.me",
|
|
13
14
|
"url": "https://github.com/whatasoda"
|
|
14
15
|
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"graphql",
|
|
18
|
+
"codegen",
|
|
19
|
+
"zero-runtime",
|
|
20
|
+
"typescript",
|
|
21
|
+
"utilities"
|
|
22
|
+
],
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "https://github.com/whatasoda/soda-gql.git",
|
|
26
|
+
"directory": "packages/common"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/whatasoda/soda-gql#readme",
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/whatasoda/soda-gql/issues"
|
|
31
|
+
},
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=18"
|
|
34
|
+
},
|
|
15
35
|
"main": "./dist/index.mjs",
|
|
16
36
|
"module": "./dist/index.mjs",
|
|
17
37
|
"types": "./dist/index.d.mts",
|
|
18
38
|
"exports": {
|
|
39
|
+
"./test": {
|
|
40
|
+
"@soda-gql": "./@devx-test.ts"
|
|
41
|
+
},
|
|
42
|
+
"./zod": {
|
|
43
|
+
"@soda-gql": "./@x-zod.ts",
|
|
44
|
+
"types": "./dist/zod.d.mts",
|
|
45
|
+
"import": "./dist/zod.mjs",
|
|
46
|
+
"require": "./dist/zod.cjs",
|
|
47
|
+
"default": "./dist/zod.mjs"
|
|
48
|
+
},
|
|
19
49
|
".": {
|
|
20
|
-
"@soda-gql": "
|
|
50
|
+
"@soda-gql": "./@x-index.ts",
|
|
21
51
|
"types": "./dist/index.d.mts",
|
|
22
52
|
"import": "./dist/index.mjs",
|
|
23
53
|
"require": "./dist/index.cjs",
|
|
24
54
|
"default": "./dist/index.mjs"
|
|
25
55
|
},
|
|
26
|
-
"./portable": {
|
|
27
|
-
"@soda-gql": "./src/portable/index.ts",
|
|
28
|
-
"types": "./dist/portable/index.d.mts",
|
|
29
|
-
"import": "./dist/portable/index.mjs",
|
|
30
|
-
"require": "./dist/portable/index.cjs",
|
|
31
|
-
"default": "./dist/portable/index.mjs"
|
|
32
|
-
},
|
|
33
|
-
"./canonical-id": {
|
|
34
|
-
"@soda-gql": "./src/canonical-id/index.ts",
|
|
35
|
-
"types": "./dist/canonical-id/index.d.mts",
|
|
36
|
-
"import": "./dist/canonical-id/index.mjs",
|
|
37
|
-
"require": "./dist/canonical-id/index.cjs",
|
|
38
|
-
"default": "./dist/canonical-id/index.mjs"
|
|
39
|
-
},
|
|
40
56
|
"./utils": {
|
|
41
|
-
"@soda-gql": "
|
|
42
|
-
"types": "./dist/utils
|
|
43
|
-
"import": "./dist/utils
|
|
44
|
-
"require": "./dist/utils
|
|
45
|
-
"default": "./dist/utils
|
|
57
|
+
"@soda-gql": "./@x-utils.ts",
|
|
58
|
+
"types": "./dist/utils.d.mts",
|
|
59
|
+
"import": "./dist/utils.mjs",
|
|
60
|
+
"require": "./dist/utils.cjs",
|
|
61
|
+
"default": "./dist/utils.mjs"
|
|
46
62
|
},
|
|
47
|
-
"./
|
|
48
|
-
"@soda-gql": "
|
|
49
|
-
"types": "./dist/
|
|
50
|
-
"import": "./dist/
|
|
51
|
-
"require": "./dist/
|
|
52
|
-
"default": "./dist/
|
|
63
|
+
"./canonical-id": {
|
|
64
|
+
"@soda-gql": "./@x-canonical-id.ts",
|
|
65
|
+
"types": "./dist/canonical-id.d.mts",
|
|
66
|
+
"import": "./dist/canonical-id.mjs",
|
|
67
|
+
"require": "./dist/canonical-id.cjs",
|
|
68
|
+
"default": "./dist/canonical-id.mjs"
|
|
53
69
|
},
|
|
54
|
-
"./
|
|
55
|
-
"@soda-gql": "
|
|
70
|
+
"./portable": {
|
|
71
|
+
"@soda-gql": "./@x-portable.ts",
|
|
72
|
+
"types": "./dist/portable.d.mts",
|
|
73
|
+
"import": "./dist/portable.mjs",
|
|
74
|
+
"require": "./dist/portable.cjs",
|
|
75
|
+
"default": "./dist/portable.mjs"
|
|
56
76
|
},
|
|
57
77
|
"./package.json": "./package.json"
|
|
58
78
|
},
|
package/dist/zod/index.cjs
DELETED
package/dist/zod/index.d.cts
DELETED
package/dist/zod/index.d.mts
DELETED
package/dist/zod/index.mjs
DELETED