@fakeware/core 0.0.6 → 0.0.8

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.
@@ -1,2 +1,2 @@
1
- import { a as interpolate, c as FakewareConfigFn, d as FakewareUserConfig, f as fakewareConfigSchema, i as loadConfig, l as defineConfig, n as LoadConfigOptions, o as ConfigError, p as shopwareSchema, r as LoadedConfig, s as ConfigEnv, t as DEFAULT_CONFIG_FILENAME, u as FakewareConfig } from "../index-Dpb1t7ns.mjs";
2
- export { type ConfigEnv, ConfigError, DEFAULT_CONFIG_FILENAME, type FakewareConfig, type FakewareConfigFn, type FakewareUserConfig, type LoadConfigOptions, type LoadedConfig, defineConfig, fakewareConfigSchema, interpolate, loadConfig, shopwareSchema };
1
+ import { a as interpolate, c as FakewareConfigFn, d as FakewareUserConfig, f as TransactionConfig, h as transactionSchema, i as loadConfig, l as defineConfig, m as shopwareSchema, n as LoadConfigOptions, o as ConfigError, p as fakewareConfigSchema, r as LoadedConfig, s as ConfigEnv, t as DEFAULT_CONFIG_FILENAME, u as FakewareConfig } from "../index-jYm7NShY.mjs";
2
+ export { type ConfigEnv, ConfigError, DEFAULT_CONFIG_FILENAME, type FakewareConfig, type FakewareConfigFn, type FakewareUserConfig, type LoadConfigOptions, type LoadedConfig, type TransactionConfig, defineConfig, fakewareConfigSchema, interpolate, loadConfig, shopwareSchema, transactionSchema };
@@ -1,2 +1,2 @@
1
- import { a as interpolate, i as shopwareSchema, n as loadConfig, o as ConfigError, r as fakewareConfigSchema, s as defineConfig, t as DEFAULT_CONFIG_FILENAME } from "../config-CSPA4Itj.mjs";
2
- export { ConfigError, DEFAULT_CONFIG_FILENAME, defineConfig, fakewareConfigSchema, interpolate, loadConfig, shopwareSchema };
1
+ import { a as transactionSchema, c as defineConfig, i as shopwareSchema, n as loadConfig, o as interpolate, r as fakewareConfigSchema, s as ConfigError, t as DEFAULT_CONFIG_FILENAME } from "../config-K2mtOgJS.mjs";
2
+ export { ConfigError, DEFAULT_CONFIG_FILENAME, defineConfig, fakewareConfigSchema, interpolate, loadConfig, shopwareSchema, transactionSchema };
@@ -0,0 +1,308 @@
1
+ import { createHash } from "node:crypto";
2
+ import { access, readFile } from "node:fs/promises";
3
+ import { dirname, isAbsolute, join, resolve } from "node:path";
4
+ import { createJiti } from "jiti";
5
+ import { z } from "zod";
6
+ //#region \0rolldown/runtime.js
7
+ var __defProp = Object.defineProperty;
8
+ var __exportAll = (all, no_symbols) => {
9
+ let target = {};
10
+ for (var name in all) __defProp(target, name, {
11
+ get: all[name],
12
+ enumerable: true
13
+ });
14
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
15
+ return target;
16
+ };
17
+ //#endregion
18
+ //#region src/define/errors.ts
19
+ var RefError = class extends Error {};
20
+ //#endregion
21
+ //#region src/define/is-plain-object.ts
22
+ function isPlainObject(value) {
23
+ return typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof Date);
24
+ }
25
+ //#endregion
26
+ //#region src/define/ids.ts
27
+ const FAKEWARE_NAMESPACE = "b1e0a3f4-6c2d-5a8b-9e7f-0d1c2b3a4e5f";
28
+ function uuidBytes(uuid) {
29
+ const hex = uuid.replace(/-/g, "");
30
+ const bytes = new Uint8Array(16);
31
+ for (let i = 0; i < 16; i++) bytes[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);
32
+ return bytes;
33
+ }
34
+ const NAMESPACE_BYTES = uuidBytes(FAKEWARE_NAMESPACE);
35
+ function uuidv5(name) {
36
+ const hash = createHash("sha1");
37
+ hash.update(NAMESPACE_BYTES);
38
+ hash.update(name, "utf8");
39
+ const bytes = hash.digest().subarray(0, 16);
40
+ bytes[6] = bytes[6] & 15 | 80;
41
+ bytes[8] = bytes[8] & 63 | 128;
42
+ return bytes.toString("hex");
43
+ }
44
+ function deterministicId(entity, key) {
45
+ return uuidv5(`${entity}:${key}`);
46
+ }
47
+ function canonicalize(value) {
48
+ if (Array.isArray(value)) return value.map(canonicalize);
49
+ if (isPlainObject(value)) {
50
+ const sorted = {};
51
+ for (const k of Object.keys(value).sort()) sorted[k] = canonicalize(value[k]);
52
+ return sorted;
53
+ }
54
+ return value;
55
+ }
56
+ function recordHash(payload) {
57
+ return createHash("sha256").update(JSON.stringify(canonicalize(payload))).digest("hex");
58
+ }
59
+ //#endregion
60
+ //#region src/define/registry.ts
61
+ let entries = [];
62
+ function resetRegistry() {
63
+ entries = [];
64
+ }
65
+ function staticKey(value) {
66
+ if (typeof value !== "function") {
67
+ const k = value.$key;
68
+ if (typeof k === "string") return k;
69
+ }
70
+ }
71
+ function defineRecords(entity, recordOrRecords) {
72
+ const list = Array.isArray(recordOrRecords) ? recordOrRecords : [recordOrRecords];
73
+ for (const value of list) entries.push({
74
+ entity,
75
+ key: staticKey(value),
76
+ value
77
+ });
78
+ }
79
+ function drain() {
80
+ const order = [];
81
+ const byEntity = /* @__PURE__ */ new Map();
82
+ for (const e of entries) {
83
+ let bucket = byEntity.get(e.entity);
84
+ if (!bucket) {
85
+ bucket = [];
86
+ byEntity.set(e.entity, bucket);
87
+ order.push(e.entity);
88
+ }
89
+ bucket.push(e);
90
+ }
91
+ return order.map((entity) => ({
92
+ entity,
93
+ entries: byEntity.get(entity)
94
+ }));
95
+ }
96
+ function buildRefIndex(drained) {
97
+ const refIndex = { byEntity: /* @__PURE__ */ new Map() };
98
+ const ids = /* @__PURE__ */ new Map();
99
+ for (const { entity, entries: bucket } of drained) {
100
+ const slot = {
101
+ byKey: /* @__PURE__ */ new Map(),
102
+ all: []
103
+ };
104
+ refIndex.byEntity.set(entity, slot);
105
+ bucket.forEach((entry, i) => {
106
+ const id = deterministicId(entity, entry.key ?? String(i));
107
+ ids.set(entry, id);
108
+ slot.all.push(id);
109
+ if (entry.key) slot.byKey.set(entry.key, id);
110
+ });
111
+ }
112
+ return {
113
+ refIndex,
114
+ ids
115
+ };
116
+ }
117
+ //#endregion
118
+ //#region src/define/define.ts
119
+ function define(entity, records) {
120
+ defineRecords(entity, records);
121
+ }
122
+ function many(n, fn) {
123
+ return Array.from({ length: n }, () => fn);
124
+ }
125
+ let active;
126
+ function setActiveRefIndex(refIndex) {
127
+ active = refIndex;
128
+ }
129
+ function requireActive() {
130
+ if (!active) throw new RefError("ref()/refs() may only be called while resolving definitions.");
131
+ return active;
132
+ }
133
+ function ref(path) {
134
+ const slash = path.indexOf("/");
135
+ if (slash === -1) throw new RefError(`ref('${path}') must be of the form 'entity/key'.`);
136
+ const entity = path.slice(0, slash);
137
+ const key = path.slice(slash + 1);
138
+ const id = requireActive().byEntity.get(entity)?.byKey.get(key);
139
+ if (!id) throw new RefError(`ref('${path}') does not match any defined record.`);
140
+ return id;
141
+ }
142
+ function refs(entity) {
143
+ const slot = requireActive().byEntity.get(entity);
144
+ if (!slot) throw new RefError(`refs('${entity}') does not match any defined entity.`);
145
+ return [...slot.all];
146
+ }
147
+ //#endregion
148
+ //#region src/define/resolve.ts
149
+ function resolveValue(value, ctx) {
150
+ if (typeof value === "function") return resolveValue(value(ctx), ctx);
151
+ if (Array.isArray(value)) return value.map((item) => resolveValue(item, ctx));
152
+ if (isPlainObject(value)) {
153
+ const out = {};
154
+ for (const [key, v] of Object.entries(value)) {
155
+ if (key === "$key") continue;
156
+ out[key] = resolveValue(v, ctx);
157
+ }
158
+ return out;
159
+ }
160
+ return value;
161
+ }
162
+ //#endregion
163
+ //#region src/define/index.ts
164
+ var define_exports = /* @__PURE__ */ __exportAll({
165
+ RefError: () => RefError,
166
+ buildRefIndex: () => buildRefIndex,
167
+ define: () => define,
168
+ deterministicId: () => deterministicId,
169
+ drain: () => drain,
170
+ isPlainObject: () => isPlainObject,
171
+ many: () => many,
172
+ recordHash: () => recordHash,
173
+ ref: () => ref,
174
+ refs: () => refs,
175
+ resetRegistry: () => resetRegistry,
176
+ resolveValue: () => resolveValue,
177
+ setActiveRefIndex: () => setActiveRefIndex
178
+ });
179
+ //#endregion
180
+ //#region src/runtime/load-module.ts
181
+ var LoadModuleError = class extends Error {};
182
+ const jiti = createJiti(import.meta.url, { virtualModules: { "@fakeware/core": define_exports } });
183
+ async function loadModule(absPath) {
184
+ try {
185
+ return await jiti.import(absPath);
186
+ } catch (error) {
187
+ throw new LoadModuleError(`Could not load ${absPath}: ${error instanceof Error ? error.message : String(error)}`);
188
+ }
189
+ }
190
+ //#endregion
191
+ //#region src/config/define.ts
192
+ function defineConfig(config) {
193
+ return config;
194
+ }
195
+ //#endregion
196
+ //#region src/config/errors.ts
197
+ var ConfigError = class extends Error {};
198
+ //#endregion
199
+ //#region src/config/interpolate.ts
200
+ const ENV_REF = /^\$([A-Z0-9_]+)$/;
201
+ function interpolate(value, env) {
202
+ if (typeof value === "string") {
203
+ const match = ENV_REF.exec(value);
204
+ if (!match) return value;
205
+ const name = match[1];
206
+ const resolved = env[name];
207
+ if (resolved === void 0) throw new ConfigError(`Config references $${name}, but it is not set (check your .env).`);
208
+ return resolved;
209
+ }
210
+ if (Array.isArray(value)) return value.map((item) => interpolate(item, env));
211
+ if (value && typeof value === "object") {
212
+ const out = {};
213
+ for (const [k, v] of Object.entries(value)) out[k] = interpolate(v, env);
214
+ return out;
215
+ }
216
+ return value;
217
+ }
218
+ //#endregion
219
+ //#region src/config/schema.ts
220
+ const shopwareSchema = z.object({
221
+ url: z.string().min(1, "shopware.url is required"),
222
+ clientId: z.string().min(1, "shopware.clientId is required"),
223
+ clientSecret: z.string().min(1, "shopware.clientSecret is required")
224
+ });
225
+ const transactionSchema = z.object({
226
+ onError: z.enum([
227
+ "rollback",
228
+ "continue",
229
+ "stop"
230
+ ]).default("rollback"),
231
+ atomic: z.boolean().default(true)
232
+ });
233
+ const fakewareConfigSchema = z.object({
234
+ shopware: shopwareSchema.optional(),
235
+ transaction: transactionSchema.prefault({})
236
+ });
237
+ //#endregion
238
+ //#region src/config/load.ts
239
+ const DEFAULT_CONFIG_FILENAME = "fakeware.config.ts";
240
+ async function fileExists(path) {
241
+ try {
242
+ await access(path);
243
+ return true;
244
+ } catch {
245
+ return false;
246
+ }
247
+ }
248
+ async function findConfig(cwd) {
249
+ let dir = cwd;
250
+ for (;;) {
251
+ const candidate = join(dir, DEFAULT_CONFIG_FILENAME);
252
+ if (await fileExists(candidate)) return candidate;
253
+ const parent = dirname(dir);
254
+ if (parent === dir) break;
255
+ dir = parent;
256
+ }
257
+ throw new ConfigError(`No ${DEFAULT_CONFIG_FILENAME} found in ${cwd} or any parent directory. Run \`fakeware init\` first.`);
258
+ }
259
+ async function readEnvFile(projectRoot) {
260
+ const path = join(projectRoot, ".env");
261
+ if (!await fileExists(path)) return {};
262
+ const out = {};
263
+ const contents = await readFile(path, "utf8");
264
+ for (const raw of contents.split("\n")) {
265
+ const line = raw.trim();
266
+ if (!line || line.startsWith("#")) continue;
267
+ const eq = line.indexOf("=");
268
+ if (eq === -1) continue;
269
+ const key = line.slice(0, eq).trim();
270
+ let val = line.slice(eq + 1).trim();
271
+ if (val.startsWith("\"") && val.endsWith("\"") || val.startsWith("'") && val.endsWith("'")) val = val.slice(1, -1);
272
+ out[key] = val;
273
+ }
274
+ return out;
275
+ }
276
+ function isConfigFn(value) {
277
+ return typeof value === "function";
278
+ }
279
+ async function loadConfig(opts = {}) {
280
+ const cwd = opts.cwd ?? process.cwd();
281
+ const configPath = opts.configFile ? isAbsolute(opts.configFile) ? opts.configFile : resolve(cwd, opts.configFile) : await findConfig(cwd);
282
+ const projectRoot = dirname(configPath);
283
+ const env = {
284
+ ...process.env,
285
+ ...await readEnvFile(projectRoot)
286
+ };
287
+ const exported = (await loadModule(configPath)).default;
288
+ if (exported === void 0) throw new ConfigError(`${configPath} must \`export default defineConfig(...)\`.`);
289
+ const configEnv = {
290
+ env,
291
+ mode: opts.mode ?? "development"
292
+ };
293
+ const interpolated = interpolate(isConfigFn(exported) ? exported(configEnv) : exported, env);
294
+ const parsed = fakewareConfigSchema.safeParse(interpolated);
295
+ if (!parsed.success) throw new ConfigError(`Invalid config in ${configPath}: ${parsed.error.message}`);
296
+ const { shopware } = parsed.data;
297
+ if (!shopware) throw new ConfigError(`No \`shopware\` connection configured in ${configPath}. up/down need a shop to talk to.`);
298
+ return {
299
+ config: parsed.data,
300
+ connection: shopware,
301
+ configPath,
302
+ projectRoot
303
+ };
304
+ }
305
+ //#endregion
306
+ export { RefError as S, buildRefIndex as _, transactionSchema as a, recordHash as b, defineConfig as c, resolveValue as d, define as f, setActiveRefIndex as g, refs as h, shopwareSchema as i, LoadModuleError as l, ref as m, loadConfig as n, interpolate as o, many as p, fakewareConfigSchema as r, ConfigError as s, DEFAULT_CONFIG_FILENAME as t, loadModule as u, drain as v, isPlainObject as x, resetRegistry as y };
307
+
308
+ //# sourceMappingURL=config-K2mtOgJS.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-K2mtOgJS.mjs","names":["core"],"sources":["../src/define/errors.ts","../src/define/is-plain-object.ts","../src/define/ids.ts","../src/define/registry.ts","../src/define/define.ts","../src/define/resolve.ts","../src/define/index.ts","../src/runtime/load-module.ts","../src/config/define.ts","../src/config/errors.ts","../src/config/interpolate.ts","../src/config/schema.ts","../src/config/load.ts"],"sourcesContent":["export class RefError extends Error {}\n","export function isPlainObject(value: unknown): value is Record<string, unknown> {\n return (\n typeof value === 'object' && value !== null && !Array.isArray(value) && !(value instanceof Date)\n )\n}\n","import { createHash } from 'node:crypto'\nimport { isPlainObject } from './is-plain-object'\n\nconst FAKEWARE_NAMESPACE = 'b1e0a3f4-6c2d-5a8b-9e7f-0d1c2b3a4e5f'\n\nfunction uuidBytes(uuid: string): Uint8Array {\n const hex = uuid.replace(/-/g, '')\n const bytes = new Uint8Array(16)\n for (let i = 0; i < 16; i++) {\n bytes[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16)\n }\n return bytes\n}\n\nconst NAMESPACE_BYTES = uuidBytes(FAKEWARE_NAMESPACE)\n\nfunction uuidv5(name: string): string {\n const hash = createHash('sha1')\n hash.update(NAMESPACE_BYTES)\n hash.update(name, 'utf8')\n const digest = hash.digest()\n\n const bytes = digest.subarray(0, 16)\n bytes[6] = ((bytes[6] as number) & 0x0f) | 0x50\n bytes[8] = ((bytes[8] as number) & 0x3f) | 0x80\n\n return bytes.toString('hex')\n}\n\nexport function deterministicId(entity: string, key: string): string {\n return uuidv5(`${entity}:${key}`)\n}\n\nfunction canonicalize(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(canonicalize)\n if (isPlainObject(value)) {\n const sorted: Record<string, unknown> = {}\n for (const k of Object.keys(value).sort()) {\n sorted[k] = canonicalize(value[k])\n }\n return sorted\n }\n return value\n}\n\nexport function recordHash(payload: unknown): string {\n return createHash('sha256')\n .update(JSON.stringify(canonicalize(payload)))\n .digest('hex')\n}\n","import type { Ctx } from './ctx'\nimport { deterministicId } from './ids'\n\ntype RecordObject = Record<string, unknown>\nexport type RecordValue = RecordObject | ((ctx: Ctx) => RecordObject)\n\ninterface RawEntry {\n entity: string\n key?: string\n value: RecordValue\n}\n\nexport type DrainedEntries = { entity: string; entries: RawEntry[] }[]\n\nexport interface RefIndex {\n byEntity: Map<string, { byKey: Map<string, string>; all: string[] }>\n}\n\nlet entries: RawEntry[] = []\n\nexport function resetRegistry(): void {\n entries = []\n}\n\nfunction staticKey(value: RecordValue): string | undefined {\n if (typeof value !== 'function') {\n const k = (value as RecordObject).$key\n if (typeof k === 'string') return k\n }\n return undefined\n}\n\nexport function defineRecords(entity: string, recordOrRecords: RecordValue | RecordValue[]): void {\n const list = Array.isArray(recordOrRecords) ? recordOrRecords : [recordOrRecords]\n for (const value of list) {\n entries.push({ entity, key: staticKey(value), value })\n }\n}\n\nexport function drain(): DrainedEntries {\n const order: string[] = []\n const byEntity = new Map<string, RawEntry[]>()\n for (const e of entries) {\n let bucket = byEntity.get(e.entity)\n if (!bucket) {\n bucket = []\n byEntity.set(e.entity, bucket)\n order.push(e.entity)\n }\n bucket.push(e)\n }\n return order.map((entity) => ({ entity, entries: byEntity.get(entity) as RawEntry[] }))\n}\n\nexport function buildRefIndex(drained: DrainedEntries): {\n refIndex: RefIndex\n ids: Map<RawEntry, string>\n} {\n const refIndex: RefIndex = { byEntity: new Map() }\n const ids = new Map<RawEntry, string>()\n\n for (const { entity, entries: bucket } of drained) {\n const slot = { byKey: new Map<string, string>(), all: [] as string[] }\n refIndex.byEntity.set(entity, slot)\n bucket.forEach((entry, i) => {\n const idKey = entry.key ?? String(i)\n const id = deterministicId(entity, idKey)\n ids.set(entry, id)\n slot.all.push(id)\n if (entry.key) slot.byKey.set(entry.key, id)\n })\n }\n\n return { refIndex, ids }\n}\n\nexport type { RawEntry }\n","import type { Ctx } from './ctx'\nimport { RefError } from './errors'\nimport { defineRecords, type RecordValue, type RefIndex } from './registry'\nimport type { DefineRecord, EntityName } from './schema'\n\nexport function define<const E extends EntityName>(\n entity: E,\n records: DefineRecord<E> | readonly DefineRecord<E>[],\n): void {\n defineRecords(entity, records as RecordValue | RecordValue[])\n}\n\nexport function many<R extends Record<string, unknown>>(n: number, fn: (ctx: Ctx) => R): R {\n return Array.from({ length: n }, () => fn) as unknown as R\n}\n\nlet active: RefIndex | undefined\n\nexport function setActiveRefIndex(refIndex: RefIndex | undefined): void {\n active = refIndex\n}\n\nfunction requireActive(): RefIndex {\n if (!active) {\n throw new RefError('ref()/refs() may only be called while resolving definitions.')\n }\n return active\n}\n\nexport function ref(path: string): string {\n const slash = path.indexOf('/')\n if (slash === -1) {\n throw new RefError(`ref('${path}') must be of the form 'entity/key'.`)\n }\n const entity = path.slice(0, slash)\n const key = path.slice(slash + 1)\n const id = requireActive().byEntity.get(entity)?.byKey.get(key)\n if (!id) {\n throw new RefError(`ref('${path}') does not match any defined record.`)\n }\n return id\n}\n\nexport function refs(entity: string): string[] {\n const slot = requireActive().byEntity.get(entity)\n if (!slot) {\n throw new RefError(`refs('${entity}') does not match any defined entity.`)\n }\n return [...slot.all]\n}\n","import type { Ctx } from './ctx'\nimport { isPlainObject } from './is-plain-object'\n\nexport function resolveValue(value: unknown, ctx: Ctx): unknown {\n if (typeof value === 'function') {\n return resolveValue((value as (ctx: Ctx) => unknown)(ctx), ctx)\n }\n if (Array.isArray(value)) {\n return value.map((item) => resolveValue(item, ctx))\n }\n if (isPlainObject(value)) {\n const out: Record<string, unknown> = {}\n for (const [key, v] of Object.entries(value)) {\n if (key === '$key') continue\n out[key] = resolveValue(v, ctx)\n }\n return out\n }\n return value\n}\n","export type { Ctx } from './ctx'\nexport { define, many, ref, refs, setActiveRefIndex } from './define'\nexport { RefError } from './errors'\nexport { deterministicId, recordHash } from './ids'\nexport { isPlainObject } from './is-plain-object'\nexport type { DrainedEntries, RawEntry, RecordValue, RefIndex } from './registry'\nexport { buildRefIndex, drain, resetRegistry } from './registry'\nexport { resolveValue } from './resolve'\nexport type { DefineRecord, EntityName } from './schema'\n","import { createJiti } from 'jiti'\nimport * as core from '../define'\n\nexport class LoadModuleError extends Error {}\n\nconst jiti = createJiti(import.meta.url, {\n virtualModules: { '@fakeware/core': core },\n})\n\nexport async function loadModule<T = unknown>(absPath: string): Promise<T> {\n try {\n return (await jiti.import(absPath)) as T\n } catch (error) {\n throw new LoadModuleError(\n `Could not load ${absPath}: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n}\n","import type { FakewareUserConfig } from './schema'\n\nexport interface ConfigEnv {\n env: Record<string, string | undefined>\n mode: string\n}\n\nexport type FakewareConfigFn = (env: ConfigEnv) => FakewareUserConfig\n\nexport function defineConfig(config: FakewareUserConfig): FakewareUserConfig\nexport function defineConfig(config: FakewareConfigFn): FakewareConfigFn\nexport function defineConfig(\n config: FakewareUserConfig | FakewareConfigFn,\n): FakewareUserConfig | FakewareConfigFn {\n return config\n}\n","export class ConfigError extends Error {}\n","import { ConfigError } from './errors'\n\nconst ENV_REF = /^\\$([A-Z0-9_]+)$/\n\nexport function interpolate<T>(value: T, env: Record<string, string | undefined>): T {\n if (typeof value === 'string') {\n const match = ENV_REF.exec(value)\n if (!match) return value\n const name = match[1] as string\n const resolved = env[name]\n if (resolved === undefined) {\n throw new ConfigError(`Config references $${name}, but it is not set (check your .env).`)\n }\n return resolved as unknown as T\n }\n if (Array.isArray(value)) {\n return value.map((item) => interpolate(item, env)) as unknown as T\n }\n if (value && typeof value === 'object') {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value)) {\n out[k] = interpolate(v, env)\n }\n return out as T\n }\n return value\n}\n","import { z } from 'zod'\n\nexport const shopwareSchema = z.object({\n url: z.string().min(1, 'shopware.url is required'),\n clientId: z.string().min(1, 'shopware.clientId is required'),\n clientSecret: z.string().min(1, 'shopware.clientSecret is required'),\n})\n\nexport const transactionSchema = z.object({\n onError: z.enum(['rollback', 'continue', 'stop']).default('rollback'),\n atomic: z.boolean().default(true),\n})\n\nexport const fakewareConfigSchema = z.object({\n shopware: shopwareSchema.optional(),\n transaction: transactionSchema.prefault({}),\n})\n\nexport type TransactionConfig = z.output<typeof transactionSchema>\n\nexport type FakewareConfig = z.output<typeof fakewareConfigSchema>\n\nexport type FakewareUserConfig = z.input<typeof fakewareConfigSchema>\n","import { access, readFile } from 'node:fs/promises'\nimport { dirname, isAbsolute, join, resolve } from 'node:path'\nimport { loadModule } from '../runtime'\nimport type { ShopwareConnection } from '../shopware'\nimport type { ConfigEnv, FakewareConfigFn } from './define'\nimport { ConfigError } from './errors'\nimport { interpolate } from './interpolate'\nimport { type FakewareConfig, type FakewareUserConfig, fakewareConfigSchema } from './schema'\n\nexport const DEFAULT_CONFIG_FILENAME = 'fakeware.config.ts'\n\nexport interface LoadConfigOptions {\n cwd?: string\n configFile?: string\n mode?: string\n}\n\nexport interface LoadedConfig {\n config: FakewareConfig\n connection: ShopwareConnection\n configPath: string\n projectRoot: string\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path)\n return true\n } catch {\n return false\n }\n}\n\nasync function findConfig(cwd: string): Promise<string> {\n let dir = cwd\n for (;;) {\n const candidate = join(dir, DEFAULT_CONFIG_FILENAME)\n if (await fileExists(candidate)) return candidate\n const parent = dirname(dir)\n if (parent === dir) break\n dir = parent\n }\n throw new ConfigError(\n `No ${DEFAULT_CONFIG_FILENAME} found in ${cwd} or any parent directory. Run \\`fakeware init\\` first.`,\n )\n}\n\nasync function readEnvFile(projectRoot: string): Promise<Record<string, string>> {\n const path = join(projectRoot, '.env')\n if (!(await fileExists(path))) return {}\n const out: Record<string, string> = {}\n const contents = await readFile(path, 'utf8')\n for (const raw of contents.split('\\n')) {\n const line = raw.trim()\n if (!line || line.startsWith('#')) continue\n const eq = line.indexOf('=')\n if (eq === -1) continue\n const key = line.slice(0, eq).trim()\n let val = line.slice(eq + 1).trim()\n if ((val.startsWith('\"') && val.endsWith('\"')) || (val.startsWith(\"'\") && val.endsWith(\"'\"))) {\n val = val.slice(1, -1)\n }\n out[key] = val\n }\n return out\n}\n\nfunction isConfigFn(value: unknown): value is FakewareConfigFn {\n return typeof value === 'function'\n}\n\nexport async function loadConfig(opts: LoadConfigOptions = {}): Promise<LoadedConfig> {\n const cwd = opts.cwd ?? process.cwd()\n const configPath = opts.configFile\n ? isAbsolute(opts.configFile)\n ? opts.configFile\n : resolve(cwd, opts.configFile)\n : await findConfig(cwd)\n const projectRoot = dirname(configPath)\n\n const env: Record<string, string | undefined> = {\n ...process.env,\n ...(await readEnvFile(projectRoot)),\n }\n\n const mod = await loadModule<{ default?: unknown }>(configPath)\n const exported = mod.default\n if (exported === undefined) {\n throw new ConfigError(`${configPath} must \\`export default defineConfig(...)\\`.`)\n }\n\n const configEnv: ConfigEnv = { env, mode: opts.mode ?? 'development' }\n const raw = isConfigFn(exported) ? exported(configEnv) : (exported as FakewareUserConfig)\n\n const interpolated = interpolate(raw, env)\n\n const parsed = fakewareConfigSchema.safeParse(interpolated)\n if (!parsed.success) {\n throw new ConfigError(`Invalid config in ${configPath}: ${parsed.error.message}`)\n }\n\n const { shopware } = parsed.data\n if (!shopware) {\n throw new ConfigError(\n `No \\`shopware\\` connection configured in ${configPath}. up/down need a shop to talk to.`,\n )\n }\n\n return { config: parsed.data, connection: shopware, configPath, projectRoot }\n}\n"],"mappings":"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"}
@@ -28,16 +28,35 @@ declare function fetchShopInfo(connection: ShopwareConnection): Promise<ShopInfo
28
28
  type SinkRecord = Record<string, unknown> & {
29
29
  id: string;
30
30
  };
31
+ type SyncOperation = {
32
+ entity: string;
33
+ action: 'upsert';
34
+ records: SinkRecord[];
35
+ } | {
36
+ entity: string;
37
+ action: 'delete';
38
+ ids: string[];
39
+ };
40
+ interface BatchProgress {
41
+ records: number;
42
+ recordsTotal: number;
43
+ batches: number;
44
+ batchesTotal: number;
45
+ }
46
+ type OnBatch = (progress: BatchProgress) => void;
31
47
  interface ShopwareSink {
32
- upsert(entity: string, records: SinkRecord[]): Promise<void>;
33
- delete(entity: string, ids: string[]): Promise<void>;
48
+ upsert(entity: string, records: SinkRecord[], onBatch?: OnBatch): Promise<void>;
49
+ delete(entity: string, ids: string[], onBatch?: OnBatch): Promise<void>;
50
+ applyAtomic(operations: SyncOperation[]): Promise<void>;
34
51
  }
35
52
  //#endregion
36
53
  //#region src/shopware/sink.d.ts
37
54
  interface SyncSinkOptions {
38
55
  client?: ShopwareClient;
39
56
  }
57
+ declare const ATOMIC_REQUEST_BYTE_LIMIT: number;
58
+ declare function estimateSyncBytes(operations: SyncOperation[]): number;
40
59
  declare function createSyncSink(connection: ShopwareConnection, options?: SyncSinkOptions): ShopwareSink;
41
60
  //#endregion
42
- export { toConnectionError as a, ShopwareClient as c, ShopwareConnection as d, fetchShopInfo as i, createShopwareClient as l, ShopwareSink as n, validateConnection as o, SinkRecord as r, ShopwareConnectionError as s, createSyncSink as t, ShopInfo as u };
43
- //# sourceMappingURL=index-BZFBgKu8.d.mts.map
61
+ export { ShopwareSink as a, fetchShopInfo as c, ShopwareConnectionError as d, ShopwareClient as f, ShopwareConnection as h, BatchProgress as i, toConnectionError as l, ShopInfo as m, createSyncSink as n, SinkRecord as o, createShopwareClient as p, estimateSyncBytes as r, SyncOperation as s, ATOMIC_REQUEST_BYTE_LIMIT as t, validateConnection as u };
62
+ //# sourceMappingURL=index-Brciwig_.d.mts.map
@@ -1,4 +1,4 @@
1
- import { d as ShopwareConnection } from "./index-BZFBgKu8.mjs";
1
+ import { h as ShopwareConnection } from "./index-Brciwig_.mjs";
2
2
  import { z } from "zod";
3
3
 
4
4
  //#region src/config/schema.d.ts
@@ -7,13 +7,30 @@ declare const shopwareSchema: z.ZodObject<{
7
7
  clientId: z.ZodString;
8
8
  clientSecret: z.ZodString;
9
9
  }, z.core.$strip>;
10
+ declare const transactionSchema: z.ZodObject<{
11
+ onError: z.ZodDefault<z.ZodEnum<{
12
+ rollback: "rollback";
13
+ continue: "continue";
14
+ stop: "stop";
15
+ }>>;
16
+ atomic: z.ZodDefault<z.ZodBoolean>;
17
+ }, z.core.$strip>;
10
18
  declare const fakewareConfigSchema: z.ZodObject<{
11
19
  shopware: z.ZodOptional<z.ZodObject<{
12
20
  url: z.ZodString;
13
21
  clientId: z.ZodString;
14
22
  clientSecret: z.ZodString;
15
23
  }, z.core.$strip>>;
24
+ transaction: z.ZodPrefault<z.ZodObject<{
25
+ onError: z.ZodDefault<z.ZodEnum<{
26
+ rollback: "rollback";
27
+ continue: "continue";
28
+ stop: "stop";
29
+ }>>;
30
+ atomic: z.ZodDefault<z.ZodBoolean>;
31
+ }, z.core.$strip>>;
16
32
  }, z.core.$strip>;
33
+ type TransactionConfig = z.output<typeof transactionSchema>;
17
34
  type FakewareConfig = z.output<typeof fakewareConfigSchema>;
18
35
  type FakewareUserConfig = z.input<typeof fakewareConfigSchema>;
19
36
  //#endregion
@@ -47,5 +64,5 @@ interface LoadedConfig {
47
64
  }
48
65
  declare function loadConfig(opts?: LoadConfigOptions): Promise<LoadedConfig>;
49
66
  //#endregion
50
- export { interpolate as a, FakewareConfigFn as c, FakewareUserConfig as d, fakewareConfigSchema as f, loadConfig as i, defineConfig as l, LoadConfigOptions as n, ConfigError as o, shopwareSchema as p, LoadedConfig as r, ConfigEnv as s, DEFAULT_CONFIG_FILENAME as t, FakewareConfig as u };
51
- //# sourceMappingURL=index-Dpb1t7ns.d.mts.map
67
+ export { interpolate as a, FakewareConfigFn as c, FakewareUserConfig as d, TransactionConfig as f, transactionSchema as h, loadConfig as i, defineConfig as l, shopwareSchema as m, LoadConfigOptions as n, ConfigError as o, fakewareConfigSchema as p, LoadedConfig as r, ConfigEnv as s, DEFAULT_CONFIG_FILENAME as t, FakewareConfig as u };
68
+ //# sourceMappingURL=index-jYm7NShY.d.mts.map
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { r as LoadedConfig } from "./index-Dpb1t7ns.mjs";
2
- import { n as ShopwareSink, r as SinkRecord } from "./index-BZFBgKu8.mjs";
1
+ import { r as LoadedConfig } from "./index-jYm7NShY.mjs";
2
+ import { a as ShopwareSink, i as BatchProgress, o as SinkRecord, s as SyncOperation } from "./index-Brciwig_.mjs";
3
3
  import { Schemas } from "@shopware/api-client/admin-api-types";
4
4
 
5
5
  //#region src/define/ctx.d.ts
@@ -44,32 +44,28 @@ declare function refs(entity: string): string[];
44
44
  //#region src/define/errors.d.ts
45
45
  declare class RefError extends Error {}
46
46
  //#endregion
47
- //#region src/engine/errors.d.ts
48
- declare class GraphError extends Error {}
49
- //#endregion
50
- //#region src/engine/manifest.d.ts
51
- interface ManifestRecord {
52
- id: string;
53
- hash: string;
54
- }
55
- interface ManifestEntity {
56
- entity: string;
57
- records: ManifestRecord[];
58
- }
59
- interface Manifest {
60
- version: 1;
61
- fakewareVersion: string;
62
- createdAt: string;
63
- shopwareUrl: string;
64
- entities: ManifestEntity[];
65
- checksum: string;
66
- }
67
- declare function readManifest(projectRoot: string, shopwareUrl: string): Promise<Manifest | null>;
68
- //#endregion
69
47
  //#region src/engine/run.d.ts
70
48
  interface Reporter {
71
- onStart?(entity: string): void;
49
+ onStart?(entity: string, records?: number): void;
50
+ onBatch?(progress: BatchProgress): void;
72
51
  onStep?(step: ReportStep): void;
52
+ onTransactionStart?(info: {
53
+ mode: 'atomic' | 'saga';
54
+ }): void;
55
+ onCommit?(info: {
56
+ committed: number;
57
+ }): void;
58
+ onCompensate?(entity: string, count: number): void;
59
+ onCompensateFail?(entity: string): void;
60
+ onSkip?(info: {
61
+ entity: string;
62
+ error: unknown;
63
+ }): void;
64
+ onStop?(info: {
65
+ failedEntity: string;
66
+ error: unknown;
67
+ message: string;
68
+ }): void;
73
69
  }
74
70
  interface ReportStep {
75
71
  entity: string;
@@ -78,6 +74,11 @@ interface ReportStep {
78
74
  unchanged: number;
79
75
  deleted: number;
80
76
  }
77
+ type OnError = 'rollback' | 'continue' | 'stop';
78
+ interface TransactionOptions {
79
+ onError: OnError;
80
+ atomic: boolean;
81
+ }
81
82
  interface RunOptions {
82
83
  loaded: LoadedConfig;
83
84
  sink: ShopwareSink;
@@ -85,10 +86,14 @@ interface RunOptions {
85
86
  reporter?: Reporter;
86
87
  fakewareVersion?: string;
87
88
  now?: string;
89
+ transaction?: TransactionOptions;
88
90
  }
89
91
  interface UpResult {
90
92
  steps: ReportStep[];
91
93
  manifestWritten: boolean;
94
+ mode: 'atomic' | 'saga' | 'dry-run' | 'noop';
95
+ committed: number;
96
+ rolledBack: number;
92
97
  }
93
98
  interface DownResult {
94
99
  steps: ReportStep[];
@@ -97,8 +102,43 @@ interface DownResult {
97
102
  declare function runUp(opts: RunOptions): Promise<UpResult>;
98
103
  declare function runDown(opts: RunOptions): Promise<DownResult>;
99
104
  //#endregion
105
+ //#region src/engine/errors.d.ts
106
+ declare class GraphError extends Error {}
107
+ declare class TransactionError extends Error {
108
+ readonly rolledBack: ReportStep[];
109
+ readonly failedEntity: string;
110
+ readonly unrevertableUpdates: boolean;
111
+ readonly compensationErrors: unknown[];
112
+ constructor(message: string, options: {
113
+ cause: unknown;
114
+ rolledBack: ReportStep[];
115
+ failedEntity: string;
116
+ unrevertableUpdates?: boolean;
117
+ compensationErrors?: unknown[];
118
+ });
119
+ }
120
+ //#endregion
121
+ //#region src/engine/manifest.d.ts
122
+ interface ManifestRecord {
123
+ id: string;
124
+ hash: string;
125
+ }
126
+ interface ManifestEntity {
127
+ entity: string;
128
+ records: ManifestRecord[];
129
+ }
130
+ interface Manifest {
131
+ version: 1;
132
+ fakewareVersion: string;
133
+ createdAt: string;
134
+ shopwareUrl: string;
135
+ entities: ManifestEntity[];
136
+ checksum: string;
137
+ }
138
+ declare function readManifest(projectRoot: string, shopwareUrl: string): Promise<Manifest | null>;
139
+ //#endregion
100
140
  //#region src/runtime/load-module.d.ts
101
141
  declare class LoadModuleError extends Error {}
102
142
  //#endregion
103
- export { type Ctx, type DefineRecord, type DownResult, type EntityName, GraphError, LoadModuleError, type Manifest, type ManifestEntity, type ManifestRecord, RefError, type ReportStep, type Reporter, type RunOptions, type ShopwareSink, type SinkRecord, type UpResult, define, many, readManifest, ref, refs, runDown, runUp };
143
+ export { type BatchProgress, type Ctx, type DefineRecord, type DownResult, type EntityName, GraphError, LoadModuleError, type Manifest, type ManifestEntity, type ManifestRecord, type OnError, RefError, type ReportStep, type Reporter, type RunOptions, type ShopwareSink, type SinkRecord, type SyncOperation, TransactionError, type TransactionOptions, type UpResult, define, many, readManifest, ref, refs, runDown, runUp };
104
144
  //# sourceMappingURL=index.d.mts.map