@derwinjs/db 0.9.0 → 0.10.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/contract-baseline-store.d.ts +21 -0
- package/dist/contract-baseline-store.d.ts.map +1 -0
- package/dist/contract-baseline-store.js +103 -0
- package/dist/contract-baseline-store.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/scripts/smoke-auto-fix.js +1 -1
- package/dist/scripts/smoke-auto-fix.js.map +1 -1
- package/dist/tenant-fuzz-config-store.d.ts +28 -0
- package/dist/tenant-fuzz-config-store.d.ts.map +1 -0
- package/dist/tenant-fuzz-config-store.js +173 -0
- package/dist/tenant-fuzz-config-store.js.map +1 -0
- package/dist/visual-baseline-store.d.ts +21 -0
- package/dist/visual-baseline-store.d.ts.map +1 -0
- package/dist/visual-baseline-store.js +87 -0
- package/dist/visual-baseline-store.js.map +1 -0
- package/package.json +3 -3
- package/prisma/migrations/20260501165631_init/migration.sql +407 -0
- package/prisma/migrations/20260503051425_0002_qap018b_qaticket_crosslink_fields/migration.sql +6 -0
- package/prisma/migrations/20260507130000_sprint10_visual_baselines/migration.sql +27 -0
- package/prisma/migrations/20260507130100_sprint10_phase3_contract_baselines/migration.sql +32 -0
- package/prisma/migrations/20260507130200_sprint10_phase4_tenant_fuzz/migration.sql +34 -0
- package/prisma/schema.prisma +107 -0
- package/prisma-client/edge.js +36 -4
- package/prisma-client/index-browser.js +33 -1
- package/prisma-client/index.d.ts +15602 -10678
- package/prisma-client/index.js +36 -4
- package/prisma-client/package.json +1 -1
- package/prisma-client/schema.prisma +107 -0
- package/prisma-client/wasm.js +33 -1
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createPrismaContractBaselineStore — Prisma-backed implementation of the SDK
|
|
3
|
+
* ContractBaselineStore contract introduced by QAP-103.
|
|
4
|
+
*
|
|
5
|
+
* Sprint 10 Phase 3 (Test Surfaces — API contract diff). Baselines are
|
|
6
|
+
* stored as Postgres TEXT (model ContractBaseline) keyed by
|
|
7
|
+
* (projectId, specKey). One row per (projectId, specKey) — setBaseline
|
|
8
|
+
* upserts and is the only path to replace an approved baseline.
|
|
9
|
+
*
|
|
10
|
+
* Tenant isolation: every method scopes by projectId. Pattern D applies —
|
|
11
|
+
* unknown / wrong-project lookups return null rather than throwing or
|
|
12
|
+
* leaking existence (defense-in-depth against tenant enumeration).
|
|
13
|
+
*/
|
|
14
|
+
import type { PrismaClient } from './prisma.js';
|
|
15
|
+
import { type ContractBaselineStore } from '@derwinjs/sdk';
|
|
16
|
+
export interface PrismaContractBaselineStoreConfig {
|
|
17
|
+
/** Generated Prisma client. Pass an instance per process. */
|
|
18
|
+
prisma: PrismaClient;
|
|
19
|
+
}
|
|
20
|
+
export declare function createPrismaContractBaselineStore(config: PrismaContractBaselineStoreConfig): ContractBaselineStore;
|
|
21
|
+
//# sourceMappingURL=contract-baseline-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-baseline-store.d.ts","sourceRoot":"","sources":["../src/contract-baseline-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,eAAe,CAAC;AAIvB,MAAM,WAAW,iCAAiC;IAChD,6DAA6D;IAC7D,MAAM,EAAE,YAAY,CAAC;CACtB;AAqDD,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,iCAAiC,GACxC,qBAAqB,CA0EvB"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createPrismaContractBaselineStore — Prisma-backed implementation of the SDK
|
|
3
|
+
* ContractBaselineStore contract introduced by QAP-103.
|
|
4
|
+
*
|
|
5
|
+
* Sprint 10 Phase 3 (Test Surfaces — API contract diff). Baselines are
|
|
6
|
+
* stored as Postgres TEXT (model ContractBaseline) keyed by
|
|
7
|
+
* (projectId, specKey). One row per (projectId, specKey) — setBaseline
|
|
8
|
+
* upserts and is the only path to replace an approved baseline.
|
|
9
|
+
*
|
|
10
|
+
* Tenant isolation: every method scopes by projectId. Pattern D applies —
|
|
11
|
+
* unknown / wrong-project lookups return null rather than throwing or
|
|
12
|
+
* leaking existence (defense-in-depth against tenant enumeration).
|
|
13
|
+
*/
|
|
14
|
+
import { ContractBaselineStoreError, } from '@derwinjs/sdk';
|
|
15
|
+
// ─── Validation ──────────────────────────────────────────────────────────
|
|
16
|
+
function assertNonEmpty(value, fieldName) {
|
|
17
|
+
if (typeof value !== 'string' || value.trim() === '') {
|
|
18
|
+
throw new ContractBaselineStoreError('invalid_input', `createPrismaContractBaselineStore: ${fieldName} is required and non-empty`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function assertValidFormat(value) {
|
|
22
|
+
if (value !== 'openapi' && value !== 'json-schema') {
|
|
23
|
+
throw new ContractBaselineStoreError('invalid_format', `createPrismaContractBaselineStore: format must be 'openapi' or 'json-schema'`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Map a Prisma row to the SDK ContractBaseline shape. Coerces the stored
|
|
28
|
+
* `format` string back to the SDK union — defense in depth in case a
|
|
29
|
+
* malformed value somehow landed (the factory's setBaseline path validates
|
|
30
|
+
* before write, but external writes or bad migrations could bypass it).
|
|
31
|
+
*/
|
|
32
|
+
function toContractBaseline(row) {
|
|
33
|
+
const format = row.format === 'json-schema' ? 'json-schema' : 'openapi';
|
|
34
|
+
return {
|
|
35
|
+
id: row.id,
|
|
36
|
+
projectId: row.projectId,
|
|
37
|
+
specKey: row.specKey,
|
|
38
|
+
spec: row.spec,
|
|
39
|
+
format,
|
|
40
|
+
capturedAt: row.capturedAt,
|
|
41
|
+
capturedBy: row.capturedBy,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
// ─── Factory ─────────────────────────────────────────────────────────────
|
|
45
|
+
export function createPrismaContractBaselineStore(config) {
|
|
46
|
+
const { prisma } = config;
|
|
47
|
+
return {
|
|
48
|
+
async getBaseline(input) {
|
|
49
|
+
assertNonEmpty(input.projectId, 'projectId');
|
|
50
|
+
assertNonEmpty(input.specKey, 'specKey');
|
|
51
|
+
const row = await prisma.contractBaseline.findUnique({
|
|
52
|
+
where: {
|
|
53
|
+
projectId_specKey: {
|
|
54
|
+
projectId: input.projectId,
|
|
55
|
+
specKey: input.specKey,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
if (row === null)
|
|
60
|
+
return null;
|
|
61
|
+
return toContractBaseline(row);
|
|
62
|
+
},
|
|
63
|
+
async setBaseline(input) {
|
|
64
|
+
assertNonEmpty(input.projectId, 'projectId');
|
|
65
|
+
assertNonEmpty(input.specKey, 'specKey');
|
|
66
|
+
assertNonEmpty(input.spec, 'spec');
|
|
67
|
+
assertNonEmpty(input.capturedBy, 'capturedBy');
|
|
68
|
+
assertValidFormat(input.format);
|
|
69
|
+
const row = await prisma.contractBaseline.upsert({
|
|
70
|
+
where: {
|
|
71
|
+
projectId_specKey: {
|
|
72
|
+
projectId: input.projectId,
|
|
73
|
+
specKey: input.specKey,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
create: {
|
|
77
|
+
projectId: input.projectId,
|
|
78
|
+
specKey: input.specKey,
|
|
79
|
+
spec: input.spec,
|
|
80
|
+
format: input.format,
|
|
81
|
+
capturedBy: input.capturedBy,
|
|
82
|
+
},
|
|
83
|
+
update: {
|
|
84
|
+
spec: input.spec,
|
|
85
|
+
format: input.format,
|
|
86
|
+
capturedBy: input.capturedBy,
|
|
87
|
+
capturedAt: new Date(),
|
|
88
|
+
},
|
|
89
|
+
select: { id: true },
|
|
90
|
+
});
|
|
91
|
+
return { id: row.id };
|
|
92
|
+
},
|
|
93
|
+
async listBaselines(input) {
|
|
94
|
+
assertNonEmpty(input.projectId, 'projectId');
|
|
95
|
+
const rows = await prisma.contractBaseline.findMany({
|
|
96
|
+
where: { projectId: input.projectId },
|
|
97
|
+
orderBy: { capturedAt: 'desc' },
|
|
98
|
+
});
|
|
99
|
+
return rows.map(toContractBaseline);
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=contract-baseline-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-baseline-store.js","sourceRoot":"","sources":["../src/contract-baseline-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EACL,0BAA0B,GAG3B,MAAM,eAAe,CAAC;AASvB,4EAA4E;AAE5E,SAAS,cAAc,CAAC,KAAc,EAAE,SAAiB;IACvD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrD,MAAM,IAAI,0BAA0B,CAClC,eAAe,EACf,sCAAsC,SAAS,4BAA4B,CAC5E,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc;IACvC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,aAAa,EAAE,CAAC;QACnD,MAAM,IAAI,0BAA0B,CAClC,gBAAgB,EAChB,8EAA8E,CAC/E,CAAC;IACJ,CAAC;AACH,CAAC;AAYD;;;;;GAKG;AACH,SAAS,kBAAkB,CAAC,GAA8B;IACxD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;IACxE,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,MAAM;QACN,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,UAAU,EAAE,GAAG,CAAC,UAAU;KAC3B,CAAC;AACJ,CAAC;AAED,4EAA4E;AAE5E,MAAM,UAAU,iCAAiC,CAC/C,MAAyC;IAEzC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAE1B,OAAO;QACL,KAAK,CAAC,WAAW,CAAC,KAGjB;YACC,cAAc,CAAC,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;YAC7C,cAAc,CAAC,KAAK,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YAEzC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,UAAU,CAAC;gBACnD,KAAK,EAAE;oBACL,iBAAiB,EAAE;wBACjB,SAAS,EAAE,KAAK,CAAC,SAAS;wBAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;qBACvB;iBACF;aACF,CAAC,CAAC;YAEH,IAAI,GAAG,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAC;YAC9B,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAC;QACjC,CAAC;QAED,KAAK,CAAC,WAAW,CAAC,KAMjB;YACC,cAAc,CAAC,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;YAC7C,cAAc,CAAC,KAAK,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YACzC,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACnC,cAAc,CAAC,KAAK,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;YAC/C,iBAAiB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAEhC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC;gBAC/C,KAAK,EAAE;oBACL,iBAAiB,EAAE;wBACjB,SAAS,EAAE,KAAK,CAAC,SAAS;wBAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;qBACvB;iBACF;gBACD,MAAM,EAAE;oBACN,SAAS,EAAE,KAAK,CAAC,SAAS;oBAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,UAAU,EAAE,KAAK,CAAC,UAAU;iBAC7B;gBACD,MAAM,EAAE;oBACN,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,UAAU,EAAE,KAAK,CAAC,UAAU;oBAC5B,UAAU,EAAE,IAAI,IAAI,EAAE;iBACvB;gBACD,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE;aACrB,CAAC,CAAC;YAEH,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC;QACxB,CAAC;QAED,KAAK,CAAC,aAAa,CAAC,KAA4B;YAC9C,cAAc,CAAC,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;YAE7C,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC;gBAClD,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE;gBACrC,OAAO,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE;aAChC,CAAC,CAAC;YAEH,OAAO,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QACtC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -33,5 +33,8 @@ export { createPrismaBudgetGate, type PrismaBudgetGateConfig } from './budget-ga
|
|
|
33
33
|
export { createPrismaKillSwitchEvaluator, DEFAULT_KILL_SWITCH_THRESHOLDS, type PrismaKillSwitchEvaluatorConfig, } from './kill-switch-evaluator.js';
|
|
34
34
|
export { createPrismaProjectModeStore, type PrismaProjectModeStoreConfig, } from './project-mode-store.js';
|
|
35
35
|
export { createPrismaAutoPromotionEvaluator, DEFAULT_PROMOTION_THRESHOLDS, type PrismaAutoPromotionEvaluatorConfig, } from './auto-promotion-evaluator.js';
|
|
36
|
+
export { createPrismaVisualBaselineStore, type PrismaVisualBaselineStoreConfig, } from './visual-baseline-store.js';
|
|
37
|
+
export { createPrismaContractBaselineStore, type PrismaContractBaselineStoreConfig, } from './contract-baseline-store.js';
|
|
38
|
+
export { createPrismaTenantFuzzConfigStore, type PrismaTenantFuzzConfigStoreConfig, } from './tenant-fuzz-config-store.js';
|
|
36
39
|
export * from './prisma.js';
|
|
37
40
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,YAAY,EAAG,cAAuB,CAAC;AAIpD,OAAO,EAAE,yBAAyB,EAAE,KAAK,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AACjG,OAAO,EACL,6BAA6B,EAC7B,KAAK,6BAA6B,GACnC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,sBAAsB,EAAE,KAAK,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACxF,OAAO,EAAE,0BAA0B,EAAE,KAAK,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACpG,OAAO,EAAE,yBAAyB,EAAE,KAAK,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AACjG,OAAO,EACL,6BAA6B,EAC7B,KAAK,6BAA6B,GACnC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,iCAAiC,EACjC,KAAK,iCAAiC,GACvC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,kCAAkC,EAClC,KAAK,kCAAkC,GACxC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,+BAA+B,EAC/B,KAAK,+BAA+B,GACrC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,8BAA8B,EAC9B,KAAK,8BAA8B,GACpC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,yBAAyB,EAAE,KAAK,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAChG,OAAO,EACL,4BAA4B,EAC5B,SAAS,EACT,KAAK,4BAA4B,GAClC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,uCAAuC,EACvC,KAAK,uCAAuC,GAC7C,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,qCAAqC,EACrC,KAAK,qCAAqC,GAC3C,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,iCAAiC,EACjC,SAAS,EACT,cAAc,EACd,KAAK,iCAAiC,GACvC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,KAAK,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AACvF,OAAO,EACL,+BAA+B,EAC/B,8BAA8B,EAC9B,KAAK,+BAA+B,GACrC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,4BAA4B,EAC5B,KAAK,4BAA4B,GAClC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,kCAAkC,EAClC,4BAA4B,EAC5B,KAAK,kCAAkC,GACxC,MAAM,+BAA+B,CAAC;AA4BvC,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,YAAY,EAAG,cAAuB,CAAC;AAIpD,OAAO,EAAE,yBAAyB,EAAE,KAAK,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AACjG,OAAO,EACL,6BAA6B,EAC7B,KAAK,6BAA6B,GACnC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,sBAAsB,EAAE,KAAK,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACxF,OAAO,EAAE,0BAA0B,EAAE,KAAK,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACpG,OAAO,EAAE,yBAAyB,EAAE,KAAK,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AACjG,OAAO,EACL,6BAA6B,EAC7B,KAAK,6BAA6B,GACnC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,iCAAiC,EACjC,KAAK,iCAAiC,GACvC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,kCAAkC,EAClC,KAAK,kCAAkC,GACxC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,+BAA+B,EAC/B,KAAK,+BAA+B,GACrC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,8BAA8B,EAC9B,KAAK,8BAA8B,GACpC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,yBAAyB,EAAE,KAAK,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAChG,OAAO,EACL,4BAA4B,EAC5B,SAAS,EACT,KAAK,4BAA4B,GAClC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,uCAAuC,EACvC,KAAK,uCAAuC,GAC7C,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,qCAAqC,EACrC,KAAK,qCAAqC,GAC3C,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,iCAAiC,EACjC,SAAS,EACT,cAAc,EACd,KAAK,iCAAiC,GACvC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,KAAK,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AACvF,OAAO,EACL,+BAA+B,EAC/B,8BAA8B,EAC9B,KAAK,+BAA+B,GACrC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,4BAA4B,EAC5B,KAAK,4BAA4B,GAClC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,kCAAkC,EAClC,4BAA4B,EAC5B,KAAK,kCAAkC,GACxC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,+BAA+B,EAC/B,KAAK,+BAA+B,GACrC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,iCAAiC,EACjC,KAAK,iCAAiC,GACvC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,iCAAiC,EACjC,KAAK,iCAAiC,GACvC,MAAM,+BAA+B,CAAC;AA4BvC,cAAc,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -34,6 +34,9 @@ export { createPrismaBudgetGate } from './budget-gate.js';
|
|
|
34
34
|
export { createPrismaKillSwitchEvaluator, DEFAULT_KILL_SWITCH_THRESHOLDS, } from './kill-switch-evaluator.js';
|
|
35
35
|
export { createPrismaProjectModeStore, } from './project-mode-store.js';
|
|
36
36
|
export { createPrismaAutoPromotionEvaluator, DEFAULT_PROMOTION_THRESHOLDS, } from './auto-promotion-evaluator.js';
|
|
37
|
+
export { createPrismaVisualBaselineStore, } from './visual-baseline-store.js';
|
|
38
|
+
export { createPrismaContractBaselineStore, } from './contract-baseline-store.js';
|
|
39
|
+
export { createPrismaTenantFuzzConfigStore, } from './tenant-fuzz-config-store.js';
|
|
37
40
|
// ─── Prisma client re-export ─────────────────────────────────────────────
|
|
38
41
|
//
|
|
39
42
|
// @derwinjs/db ships its OWN generated Prisma client (output: prisma-client/
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,cAAuB,CAAC;AAEpD,4EAA4E;AAE5E,OAAO,EAAE,yBAAyB,EAAkC,MAAM,sBAAsB,CAAC;AACjG,OAAO,EACL,6BAA6B,GAE9B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,sBAAsB,EAA+B,MAAM,mBAAmB,CAAC;AACxF,OAAO,EAAE,0BAA0B,EAAmC,MAAM,uBAAuB,CAAC;AACpG,OAAO,EAAE,yBAAyB,EAAkC,MAAM,sBAAsB,CAAC;AACjG,OAAO,EACL,6BAA6B,GAE9B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,iCAAiC,GAElC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,kCAAkC,GAEnC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,+BAA+B,GAEhC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,8BAA8B,GAE/B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,yBAAyB,EAAkC,MAAM,qBAAqB,CAAC;AAChG,OAAO,EACL,4BAA4B,EAC5B,SAAS,GAEV,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,uCAAuC,GAExC,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,qCAAqC,GAEtC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,iCAAiC,EACjC,SAAS,EACT,cAAc,GAEf,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAA+B,MAAM,kBAAkB,CAAC;AACvF,OAAO,EACL,+BAA+B,EAC/B,8BAA8B,GAE/B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,4BAA4B,GAE7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,kCAAkC,EAClC,4BAA4B,GAE7B,MAAM,+BAA+B,CAAC;AAEvC,4EAA4E;AAC5E,EAAE;AACF,6EAA6E;AAC7E,wEAAwE;AACxE,sEAAsE;AACtE,wEAAwE;AACxE,wEAAwE;AACxE,gDAAgD;AAChD,EAAE;AACF,+DAA+D;AAC/D,0EAA0E;AAC1E,yCAAyC;AACzC,+EAA+E;AAC/E,yCAAyC;AACzC,uEAAuE;AACvE,sEAAsE;AACtE,kEAAkE;AAClE,+BAA+B;AAC/B,EAAE;AACF,oBAAoB;AACpB,8DAA8D;AAC9D,4CAA4C;AAC5C,qEAAqE;AACrE,QAAQ;AACR,gDAAgD;AAEhD,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,cAAuB,CAAC;AAEpD,4EAA4E;AAE5E,OAAO,EAAE,yBAAyB,EAAkC,MAAM,sBAAsB,CAAC;AACjG,OAAO,EACL,6BAA6B,GAE9B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,sBAAsB,EAA+B,MAAM,mBAAmB,CAAC;AACxF,OAAO,EAAE,0BAA0B,EAAmC,MAAM,uBAAuB,CAAC;AACpG,OAAO,EAAE,yBAAyB,EAAkC,MAAM,sBAAsB,CAAC;AACjG,OAAO,EACL,6BAA6B,GAE9B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,iCAAiC,GAElC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,kCAAkC,GAEnC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,+BAA+B,GAEhC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,8BAA8B,GAE/B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,yBAAyB,EAAkC,MAAM,qBAAqB,CAAC;AAChG,OAAO,EACL,4BAA4B,EAC5B,SAAS,GAEV,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,uCAAuC,GAExC,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,qCAAqC,GAEtC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,iCAAiC,EACjC,SAAS,EACT,cAAc,GAEf,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAA+B,MAAM,kBAAkB,CAAC;AACvF,OAAO,EACL,+BAA+B,EAC/B,8BAA8B,GAE/B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,4BAA4B,GAE7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,kCAAkC,EAClC,4BAA4B,GAE7B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,+BAA+B,GAEhC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,iCAAiC,GAElC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,iCAAiC,GAElC,MAAM,+BAA+B,CAAC;AAEvC,4EAA4E;AAC5E,EAAE;AACF,6EAA6E;AAC7E,wEAAwE;AACxE,sEAAsE;AACtE,wEAAwE;AACxE,wEAAwE;AACxE,gDAAgD;AAChD,EAAE;AACF,+DAA+D;AAC/D,0EAA0E;AAC1E,yCAAyC;AACzC,+EAA+E;AAC/E,yCAAyC;AACzC,uEAAuE;AACvE,sEAAsE;AACtE,kEAAkE;AAClE,+BAA+B;AAC/B,EAAE;AACF,oBAAoB;AACpB,8DAA8D;AAC9D,4CAA4C;AAC5C,qEAAqE;AACrE,QAAQ;AACR,gDAAgD;AAEhD,cAAc,aAAa,CAAC"}
|
|
@@ -79,7 +79,7 @@ const stubRepo = {
|
|
|
79
79
|
openPR: (_opts) => {
|
|
80
80
|
throw new Error('smoke: stubRepo.openPR called — DRY_RUN should not reach repo');
|
|
81
81
|
},
|
|
82
|
-
mergePR: (
|
|
82
|
+
mergePR: (_input) => {
|
|
83
83
|
throw new Error('smoke: stubRepo.mergePR called — DRY_RUN should not reach repo');
|
|
84
84
|
},
|
|
85
85
|
revertPR: (_prNumber, _reason) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"smoke-auto-fix.js","sourceRoot":"","sources":["../../src/scripts/smoke-auto-fix.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"smoke-auto-fix.js","sourceRoot":"","sources":["../../src/scripts/smoke-auto-fix.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAarD,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,6EAA6E;AAE7E,MAAM,YAAY,GAAG,iBAAiB,CAAC;AACvC,MAAM,kBAAkB,GAAG,UAAU,CAAC;AACtC,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,uBAAuB,CAAC;AAEvF,MAAM,YAAY,GAAG;;;;;;CAMpB,CAAC;AAEF,2EAA2E;AAC3E,uEAAuE;AACvE,wEAAwE;AACxE,yEAAyE;AACzE,yEAAyE;AACzE,WAAW;AACX,OAAO,CAAC,GAAG,CAAC,2BAA2B,GAAG,YAAY,CAAC;AAEvD,6EAA6E;AAE7E;;;;;GAKG;AACH,MAAM,aAAa,GAAuB;IACxC,IAAI,EAAE,mBAAmB;IACzB,YAAY,EAAE,CAAC,IAAsB,EAA4B,EAAE;QACjE,MAAM,IAAI,KAAK,CACb,6FAA6F,CAC9F,CAAC;IACJ,CAAC;CACF,CAAC;AAEF;;;;;GAKG;AACH,MAAM,QAAQ,GAAkB;IAC9B,MAAM,EAAE,CAAC,KAAkB,EAAyB,EAAE;QACpD,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACnF,CAAC;IACD,OAAO,EAAE,CAAC,MAAoB,EAA0B,EAAE;QACxD,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;IACpF,CAAC;IACD,QAAQ,EAAE,CAAC,SAAiB,EAAE,OAAe,EAA2B,EAAE;QACxE,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACrF,CAAC;IACD,YAAY,EAAE,GAA0B,EAAE;QACxC,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;IACzF,CAAC;IACD,WAAW,EAAE,CAAC,SAAiB,EAA0B,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;IACjF,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;IACtC,gBAAgB,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;CAC9C,CAAC;AAEF,6EAA6E;AAE7E,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;AAClC,MAAM,WAAW,GAAG,yBAAyB,CAAC;IAC5C,MAAM;IACN,gBAAgB,EAAE,kBAAkB;CACrC,CAAC,CAAC;AACH,MAAM,YAAY,GAAG,6BAA6B,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;AAC/D,MAAM,SAAS,GAAG,qBAAqB,CAAC;IACtC,MAAM;IACN,YAAY;IACZ,yEAAyE;IACzE,sEAAsE;IACtE,aAAa,EAAE;QACb,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,KAAK;QAClB,iBAAiB,EAAE,CAAC;QACpB,aAAa,EAAE,EAAE;QACjB,aAAa,EAAE,EAAE;KAClB;CACF,CAAC,CAAC;AAEH,IAAI,YAAgC,CAAC;AACrC,IAAI,eAAmC,CAAC;AACxC,IAAI,eAAmC,CAAC;AACxC,MAAM,iBAAiB,GAAa,EAAE,CAAC;AAEvC,KAAK,UAAU,IAAI;IACjB,uEAAuE;IACvE,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;QAC/C,KAAK,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE;KACpC,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,YAAY,kBAAkB,0CAA0C,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,wBAAwB,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC;IAEpD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;QACpC,IAAI,EAAE;YACJ,SAAS,EAAE,QAAQ,CAAC,EAAE;YACtB,WAAW,EAAE,YAAY;YACzB,WAAW,EAAE,oBAAoB;YACjC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,gCAAgC,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE;YACxE,MAAM,EAAE,WAAW;YACnB,WAAW,EAAE,IAAI,IAAI,EAAE;YACvB,aAAa,EAAE,CAAC;YAChB,cAAc,EAAE,CAAC;SAClB;KACF,CAAC,CAAC;IACH,YAAY,GAAG,GAAG,CAAC,EAAE,CAAC;IACtB,OAAO,CAAC,GAAG,CAAC,iCAAiC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;IAExD,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,cAAc,CAAC;QAC/C,SAAS,EAAE,QAAQ,CAAC,EAAE;QACtB,OAAO,EAAE,GAAG,CAAC,EAAE;QACf,KAAK,EAAE,GAAG,YAAY,wCAAwC;QAC9D,OAAO,EAAE,wBAAwB;QACjC,cAAc,EAAE,aAAa;QAC7B,QAAQ,EAAE,MAAM;QAChB,QAAQ,EAAE,MAAM;QAChB,UAAU,EAAE;YACV;gBACE,IAAI,EAAE,CAAC;gBACP,MAAM,EAAE,iBAAiB;gBACzB,QAAQ,EAAE,kBAAkB;gBAC5B,MAAM,EAAE,iBAAiB;aAC1B;SACF;QACD,kBAAkB,EAAE,GAAG,YAAY,6DAA6D;QAChG,WAAW,EAAE;YACX,aAAa,EAAE,CAAC,wBAAwB,CAAC;YACzC,aAAa,EAAE,CAAC,gCAAgC,CAAC;YACjD,aAAa,EAAE,EAAE;SAClB;QACD,mBAAmB,EAAE,sDAAsD;KAC5E,CAAC,CAAC;IACH,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,0BAA0B,OAAO,CAAC,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAC;IAE3E,qEAAqE;IACrE,2EAA2E;IAC3E,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC;QAC3C,IAAI,EAAE;YACJ,OAAO,EAAE,GAAG,CAAC,EAAE;YACf,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;YAC7B,SAAS,EAAE,cAAc;YACzB,UAAU,EAAE,cAAc;YAC1B,OAAO,EAAE;gBACP,MAAM,EAAE,YAAY;gBACpB,SAAS,EAAE,mBAAmB;gBAC9B,YAAY,EAAE,uCAAuC;aACtD;YACD,eAAe,EAAE,EAAE;YACnB,cAAc,EAAE,IAAI,IAAI,EAAE;SAC3B;KACF,CAAC,CAAC;IACH,eAAe,GAAG,MAAM,CAAC,EAAE,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,2BAA2B,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;IAErD,uEAAuE;IACvE,MAAM,UAAU,GAAG,mBAAmB,CAAC;QACrC,SAAS,EAAE,aAAa;QACxB,IAAI,EAAE,QAAQ;QACd,WAAW;QACX,YAAY;QACZ,MAAM,EAAE,SAAS;KAClB,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CACT,sFAAsF,CACvF,CAAC;IACF,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAClC,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC;QACpC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;QAC7B,SAAS,EAAE,QAAQ,CAAC,EAAE;KACvB,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,aAAa,GAAG,CAAC,OAAO,cAAc,GAAG,CAAC,SAAS,IAAI,MAAM,EAAE,CAAC,CAAC;IAE7E,IAAI,GAAG,CAAC,OAAO,KAAK,gBAAgB,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CACb,2CAA2C,GAAG,CAAC,OAAO,mBAAmB,GAAG,CAAC,YAAY,IAAI,EAAE,GAAG,CACnG,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IACD,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAEtC,uEAAuE;IACvE,0EAA0E;IAC1E,qEAAqE;IACrE,mEAAmE;IACnE,mEAAmE;IACnE,4CAA4C;IAC5C,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC;QAC5C,EAAE,EAAE,GAAG,CAAC,SAAS;QACjB,SAAS,EAAE,QAAQ,CAAC,EAAE;KACvB,CAAC,CAAC;IACH,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,gBAAgB,GAAG,CAAC,SAAS,2BAA2B,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,OAAO,CAAC,cAAc,KAAK,mBAAmB,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CACb,uFAAuF,OAAO,CAAC,cAAc,GAAG,CACjH,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,+CAA+C,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAClF,CAAC;IACD,MAAM,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;IACpD,IAAI,aAAa,GAAG,cAAc,GAAG,IAAI,IAAI,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;QAC/E,MAAM,IAAI,KAAK,CACb,wBAAwB,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,kCAAkC,CAC5F,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,GAAG,CACT,eAAe,GAAG,CAAC,SAAS,aAAa,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,kDAAkD,CACvH,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;AAClD,CAAC;AAED,KAAK,UAAU,OAAO;IACpB,+DAA+D;IAC/D,wEAAwE;IACxE,uEAAuE;IACvE,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,MAAM,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC;YACnC,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,iBAAiB,EAAE,EAAE;SACzC,CAAC,CAAC;IACL,CAAC;IACD,IAAI,eAAe,EAAE,CAAC;QACpB,MAAM,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,CAAC,CAAC;IACxE,CAAC;IACD,IAAI,eAAe,EAAE,CAAC;QACpB,MAAM,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC;AAED,IAAI,EAAE;KACH,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IACtB,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,GAAG,CAAC,CAAC;IACzD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC;KACD,OAAO,CAAC,KAAK,IAAI,EAAE;IAClB,IAAI,CAAC;QACH,MAAM,OAAO,EAAE,CAAC;IAClB,CAAC;IAAC,OAAO,UAAmB,EAAE,CAAC;QAC7B,OAAO,CAAC,KAAK,CACX,oEAAoE,EACpE,UAAU,CACX,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;AAC7B,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createPrismaTenantFuzzConfigStore — Prisma-backed implementation of the SDK
|
|
3
|
+
* TenantFuzzConfigStore contract introduced by QAP-104.
|
|
4
|
+
*
|
|
5
|
+
* Sprint 10 Phase 4 (Test Surfaces — Multi-tenant isolation fuzz). The
|
|
6
|
+
* store persists one row per project (TenantFuzzConfig.projectId @unique)
|
|
7
|
+
* and gates writes on operator consent: `consentToFuzz=false` MUST come
|
|
8
|
+
* with an empty probePairs array, otherwise we throw `no_consent`. This
|
|
9
|
+
* complements the fuzzer-side consent gate so probe pairs cannot be
|
|
10
|
+
* staged ahead of opt-in.
|
|
11
|
+
*
|
|
12
|
+
* Tenant isolation: every method scopes by projectId. Pattern D applies —
|
|
13
|
+
* unknown / wrong-project lookups return null rather than throwing or
|
|
14
|
+
* leaking existence (defense-in-depth against tenant enumeration).
|
|
15
|
+
*
|
|
16
|
+
* The two JSON columns (`tenantSafeRoutes`, `probePairs`) are validated
|
|
17
|
+
* shape-wise on read AND on write. Bad shapes from out-of-band writes
|
|
18
|
+
* surface as TenantFuzzConfigStoreError('invalid_input') rather than
|
|
19
|
+
* silently leaking malformed configs to the fuzzer.
|
|
20
|
+
*/
|
|
21
|
+
import { type PrismaClient } from './prisma.js';
|
|
22
|
+
import { type TenantFuzzConfigStore } from '@derwinjs/sdk';
|
|
23
|
+
export interface PrismaTenantFuzzConfigStoreConfig {
|
|
24
|
+
/** Generated Prisma client. Pass an instance per process. */
|
|
25
|
+
prisma: PrismaClient;
|
|
26
|
+
}
|
|
27
|
+
export declare function createPrismaTenantFuzzConfigStore(config: PrismaTenantFuzzConfigStoreConfig): TenantFuzzConfigStore;
|
|
28
|
+
//# sourceMappingURL=tenant-fuzz-config-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-fuzz-config-store.d.ts","sourceRoot":"","sources":["../src/tenant-fuzz-config-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAU,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAGL,KAAK,qBAAqB,EAG3B,MAAM,eAAe,CAAC;AAIvB,MAAM,WAAW,iCAAiC;IAChD,6DAA6D;IAC7D,MAAM,EAAE,YAAY,CAAC;CACtB;AA+JD,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,iCAAiC,GACxC,qBAAqB,CA8DvB"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createPrismaTenantFuzzConfigStore — Prisma-backed implementation of the SDK
|
|
3
|
+
* TenantFuzzConfigStore contract introduced by QAP-104.
|
|
4
|
+
*
|
|
5
|
+
* Sprint 10 Phase 4 (Test Surfaces — Multi-tenant isolation fuzz). The
|
|
6
|
+
* store persists one row per project (TenantFuzzConfig.projectId @unique)
|
|
7
|
+
* and gates writes on operator consent: `consentToFuzz=false` MUST come
|
|
8
|
+
* with an empty probePairs array, otherwise we throw `no_consent`. This
|
|
9
|
+
* complements the fuzzer-side consent gate so probe pairs cannot be
|
|
10
|
+
* staged ahead of opt-in.
|
|
11
|
+
*
|
|
12
|
+
* Tenant isolation: every method scopes by projectId. Pattern D applies —
|
|
13
|
+
* unknown / wrong-project lookups return null rather than throwing or
|
|
14
|
+
* leaking existence (defense-in-depth against tenant enumeration).
|
|
15
|
+
*
|
|
16
|
+
* The two JSON columns (`tenantSafeRoutes`, `probePairs`) are validated
|
|
17
|
+
* shape-wise on read AND on write. Bad shapes from out-of-band writes
|
|
18
|
+
* surface as TenantFuzzConfigStoreError('invalid_input') rather than
|
|
19
|
+
* silently leaking malformed configs to the fuzzer.
|
|
20
|
+
*/
|
|
21
|
+
import { Prisma } from './prisma.js';
|
|
22
|
+
import { TenantFuzzConfigStoreError, } from '@derwinjs/sdk';
|
|
23
|
+
// ─── Validation ──────────────────────────────────────────────────────────
|
|
24
|
+
const VALID_METHODS = new Set(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']);
|
|
25
|
+
function assertNonEmpty(value, fieldName) {
|
|
26
|
+
if (typeof value !== 'string' || value.trim() === '') {
|
|
27
|
+
throw new TenantFuzzConfigStoreError('invalid_input', `createPrismaTenantFuzzConfigStore: ${fieldName} is required and non-empty`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function assertRouteShape(value, ix) {
|
|
31
|
+
if (typeof value !== 'object' || value === null) {
|
|
32
|
+
throw new TenantFuzzConfigStoreError('invalid_input', `createPrismaTenantFuzzConfigStore: tenantSafeRoutes[${String(ix)}] must be an object`);
|
|
33
|
+
}
|
|
34
|
+
const route = value;
|
|
35
|
+
if (typeof route.method !== 'string' || !VALID_METHODS.has(route.method)) {
|
|
36
|
+
throw new TenantFuzzConfigStoreError('invalid_input', `createPrismaTenantFuzzConfigStore: tenantSafeRoutes[${String(ix)}].method must be one of GET/POST/PUT/PATCH/DELETE`);
|
|
37
|
+
}
|
|
38
|
+
if (typeof route.pathTemplate !== 'string' || route.pathTemplate.trim() === '') {
|
|
39
|
+
throw new TenantFuzzConfigStoreError('invalid_input', `createPrismaTenantFuzzConfigStore: tenantSafeRoutes[${String(ix)}].pathTemplate is required and non-empty`);
|
|
40
|
+
}
|
|
41
|
+
if (typeof route.description !== 'string') {
|
|
42
|
+
throw new TenantFuzzConfigStoreError('invalid_input', `createPrismaTenantFuzzConfigStore: tenantSafeRoutes[${String(ix)}].description must be a string`);
|
|
43
|
+
}
|
|
44
|
+
if (typeof route.bodyTemplate !== 'undefined' && typeof route.bodyTemplate !== 'string') {
|
|
45
|
+
throw new TenantFuzzConfigStoreError('invalid_input', `createPrismaTenantFuzzConfigStore: tenantSafeRoutes[${String(ix)}].bodyTemplate must be a string when present`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function assertPairShape(value, ix) {
|
|
49
|
+
if (typeof value !== 'object' || value === null) {
|
|
50
|
+
throw new TenantFuzzConfigStoreError('invalid_input', `createPrismaTenantFuzzConfigStore: probePairs[${String(ix)}] must be an object`);
|
|
51
|
+
}
|
|
52
|
+
const pair = value;
|
|
53
|
+
if (typeof pair.sessionToken !== 'string' || pair.sessionToken.trim() === '') {
|
|
54
|
+
throw new TenantFuzzConfigStoreError('invalid_input', `createPrismaTenantFuzzConfigStore: probePairs[${String(ix)}].sessionToken is required and non-empty`);
|
|
55
|
+
}
|
|
56
|
+
if (typeof pair.targetResourceId !== 'string' || pair.targetResourceId.trim() === '') {
|
|
57
|
+
throw new TenantFuzzConfigStoreError('invalid_input', `createPrismaTenantFuzzConfigStore: probePairs[${String(ix)}].targetResourceId is required and non-empty`);
|
|
58
|
+
}
|
|
59
|
+
if (typeof pair.label !== 'string') {
|
|
60
|
+
throw new TenantFuzzConfigStoreError('invalid_input', `createPrismaTenantFuzzConfigStore: probePairs[${String(ix)}].label must be a string`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Validate the SDK input shape before any DB write. Routes + pairs are
|
|
65
|
+
* shape-checked; the consent invariant (probePairs require consent) is
|
|
66
|
+
* enforced separately so the error surfaces with the dedicated
|
|
67
|
+
* `no_consent` code rather than `invalid_input`.
|
|
68
|
+
*/
|
|
69
|
+
function assertConfigShape(input) {
|
|
70
|
+
assertNonEmpty(input.projectId, 'projectId');
|
|
71
|
+
if (!Array.isArray(input.tenantSafeRoutes)) {
|
|
72
|
+
throw new TenantFuzzConfigStoreError('invalid_input', 'createPrismaTenantFuzzConfigStore: tenantSafeRoutes must be an array');
|
|
73
|
+
}
|
|
74
|
+
if (!Array.isArray(input.probePairs)) {
|
|
75
|
+
throw new TenantFuzzConfigStoreError('invalid_input', 'createPrismaTenantFuzzConfigStore: probePairs must be an array');
|
|
76
|
+
}
|
|
77
|
+
for (let ix = 0; ix < input.tenantSafeRoutes.length; ix++) {
|
|
78
|
+
assertRouteShape(input.tenantSafeRoutes[ix], ix);
|
|
79
|
+
}
|
|
80
|
+
for (let ix = 0; ix < input.probePairs.length; ix++) {
|
|
81
|
+
assertPairShape(input.probePairs[ix], ix);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Map a Prisma row to the SDK TenantFuzzConfig shape. We re-validate the
|
|
86
|
+
* JSON columns on read — defense-in-depth in case a malformed value
|
|
87
|
+
* landed via raw SQL or a bad migration. Failed shape checks throw
|
|
88
|
+
* invalid_input so callers see the bad row as a contract violation
|
|
89
|
+
* rather than a silently empty config.
|
|
90
|
+
*/
|
|
91
|
+
function toTenantFuzzConfig(row) {
|
|
92
|
+
const routes = [];
|
|
93
|
+
if (Array.isArray(row.tenantSafeRoutes)) {
|
|
94
|
+
for (let ix = 0; ix < row.tenantSafeRoutes.length; ix++) {
|
|
95
|
+
const candidate = row.tenantSafeRoutes[ix];
|
|
96
|
+
assertRouteShape(candidate, ix);
|
|
97
|
+
routes.push(candidate);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
throw new TenantFuzzConfigStoreError('invalid_input', `createPrismaTenantFuzzConfigStore: stored tenantSafeRoutes is not an array (projectId=${row.projectId})`);
|
|
102
|
+
}
|
|
103
|
+
const pairs = [];
|
|
104
|
+
if (Array.isArray(row.probePairs)) {
|
|
105
|
+
for (let ix = 0; ix < row.probePairs.length; ix++) {
|
|
106
|
+
const candidate = row.probePairs[ix];
|
|
107
|
+
assertPairShape(candidate, ix);
|
|
108
|
+
pairs.push(candidate);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
throw new TenantFuzzConfigStoreError('invalid_input', `createPrismaTenantFuzzConfigStore: stored probePairs is not an array (projectId=${row.projectId})`);
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
projectId: row.projectId,
|
|
116
|
+
consentToFuzz: row.consentToFuzz,
|
|
117
|
+
tenantSafeRoutes: routes,
|
|
118
|
+
probePairs: pairs,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
// ─── Factory ─────────────────────────────────────────────────────────────
|
|
122
|
+
export function createPrismaTenantFuzzConfigStore(config) {
|
|
123
|
+
const { prisma } = config;
|
|
124
|
+
return {
|
|
125
|
+
async getConfig(input) {
|
|
126
|
+
assertNonEmpty(input.projectId, 'projectId');
|
|
127
|
+
const row = await prisma.tenantFuzzConfig.findUnique({
|
|
128
|
+
where: { projectId: input.projectId },
|
|
129
|
+
});
|
|
130
|
+
if (row === null)
|
|
131
|
+
return null;
|
|
132
|
+
return toTenantFuzzConfig(row);
|
|
133
|
+
},
|
|
134
|
+
async setConfig(input) {
|
|
135
|
+
assertConfigShape(input);
|
|
136
|
+
// Defense-in-depth consent gate: the operator can't stage probePairs
|
|
137
|
+
// without first granting consentToFuzz. This complements the
|
|
138
|
+
// fuzzer-side consent re-check.
|
|
139
|
+
if (!input.consentToFuzz && input.probePairs.length > 0) {
|
|
140
|
+
throw new TenantFuzzConfigStoreError('no_consent', 'createPrismaTenantFuzzConfigStore: probePairs cannot be persisted without consentToFuzz=true (defense-in-depth)');
|
|
141
|
+
}
|
|
142
|
+
const tenantSafeRoutesJson = input.tenantSafeRoutes;
|
|
143
|
+
const probePairsJson = input.probePairs;
|
|
144
|
+
try {
|
|
145
|
+
await prisma.tenantFuzzConfig.upsert({
|
|
146
|
+
where: { projectId: input.projectId },
|
|
147
|
+
create: {
|
|
148
|
+
projectId: input.projectId,
|
|
149
|
+
consentToFuzz: input.consentToFuzz,
|
|
150
|
+
tenantSafeRoutes: tenantSafeRoutesJson,
|
|
151
|
+
probePairs: probePairsJson,
|
|
152
|
+
updatedBy: 'system',
|
|
153
|
+
},
|
|
154
|
+
update: {
|
|
155
|
+
consentToFuzz: input.consentToFuzz,
|
|
156
|
+
tenantSafeRoutes: tenantSafeRoutesJson,
|
|
157
|
+
probePairs: probePairsJson,
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
// FK violation on projectId — Prisma raises P2003. Surface as
|
|
163
|
+
// project_not_found so callers can route the missing-project flow
|
|
164
|
+
// distinctly from generic invalid_input.
|
|
165
|
+
if (err instanceof Prisma.PrismaClientKnownRequestError && err.code === 'P2003') {
|
|
166
|
+
throw new TenantFuzzConfigStoreError('project_not_found', `createPrismaTenantFuzzConfigStore: projectId ${input.projectId} does not resolve to a Project row`, err);
|
|
167
|
+
}
|
|
168
|
+
throw err;
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=tenant-fuzz-config-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-fuzz-config-store.js","sourceRoot":"","sources":["../src/tenant-fuzz-config-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createPrismaVisualBaselineStore — Prisma-backed implementation of the SDK
|
|
3
|
+
* VisualBaselineStore contract introduced by QAP-105.
|
|
4
|
+
*
|
|
5
|
+
* Sprint 10 Phase 2 (Test Surfaces). Baselines are stored as Postgres BYTEA
|
|
6
|
+
* (model VisualBaseline) keyed by (projectId, scopeKey). One row per
|
|
7
|
+
* (projectId, scopeKey) — setBaseline upserts and is the only path to
|
|
8
|
+
* replace an approved baseline.
|
|
9
|
+
*
|
|
10
|
+
* Tenant isolation: every method scopes by projectId. Pattern D applies —
|
|
11
|
+
* unknown / wrong-project lookups return null rather than throwing or
|
|
12
|
+
* leaking existence (defense-in-depth against tenant enumeration).
|
|
13
|
+
*/
|
|
14
|
+
import type { PrismaClient } from './prisma.js';
|
|
15
|
+
import { type VisualBaselineStore } from '@derwinjs/sdk';
|
|
16
|
+
export interface PrismaVisualBaselineStoreConfig {
|
|
17
|
+
/** Generated Prisma client. Pass an instance per process. */
|
|
18
|
+
prisma: PrismaClient;
|
|
19
|
+
}
|
|
20
|
+
export declare function createPrismaVisualBaselineStore(config: PrismaVisualBaselineStoreConfig): VisualBaselineStore;
|
|
21
|
+
//# sourceMappingURL=visual-baseline-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visual-baseline-store.d.ts","sourceRoot":"","sources":["../src/visual-baseline-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAA4B,KAAK,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAInF,MAAM,WAAW,+BAA+B;IAC9C,6DAA6D;IAC7D,MAAM,EAAE,YAAY,CAAC;CACtB;AAwBD,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,+BAA+B,GACtC,mBAAmB,CA0ErB"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createPrismaVisualBaselineStore — Prisma-backed implementation of the SDK
|
|
3
|
+
* VisualBaselineStore contract introduced by QAP-105.
|
|
4
|
+
*
|
|
5
|
+
* Sprint 10 Phase 2 (Test Surfaces). Baselines are stored as Postgres BYTEA
|
|
6
|
+
* (model VisualBaseline) keyed by (projectId, scopeKey). One row per
|
|
7
|
+
* (projectId, scopeKey) — setBaseline upserts and is the only path to
|
|
8
|
+
* replace an approved baseline.
|
|
9
|
+
*
|
|
10
|
+
* Tenant isolation: every method scopes by projectId. Pattern D applies —
|
|
11
|
+
* unknown / wrong-project lookups return null rather than throwing or
|
|
12
|
+
* leaking existence (defense-in-depth against tenant enumeration).
|
|
13
|
+
*/
|
|
14
|
+
import { VisualBaselineStoreError } from '@derwinjs/sdk';
|
|
15
|
+
// ─── Validation ──────────────────────────────────────────────────────────
|
|
16
|
+
function assertNonEmpty(value, fieldName) {
|
|
17
|
+
if (typeof value !== 'string' || value.trim() === '') {
|
|
18
|
+
throw new VisualBaselineStoreError('invalid_input', `createPrismaVisualBaselineStore: ${fieldName} is required and non-empty`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function assertNonEmptyBytes(bytes) {
|
|
22
|
+
if (!(bytes instanceof Uint8Array) || bytes.length === 0) {
|
|
23
|
+
throw new VisualBaselineStoreError('invalid_input', 'createPrismaVisualBaselineStore: bytes must be a non-empty Uint8Array');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// ─── Factory ─────────────────────────────────────────────────────────────
|
|
27
|
+
export function createPrismaVisualBaselineStore(config) {
|
|
28
|
+
const { prisma } = config;
|
|
29
|
+
return {
|
|
30
|
+
async getBaseline(input) {
|
|
31
|
+
assertNonEmpty(input.projectId, 'projectId');
|
|
32
|
+
assertNonEmpty(input.scopeKey, 'scopeKey');
|
|
33
|
+
let row;
|
|
34
|
+
try {
|
|
35
|
+
row = await prisma.visualBaseline.findUnique({
|
|
36
|
+
where: {
|
|
37
|
+
projectId_scopeKey: {
|
|
38
|
+
projectId: input.projectId,
|
|
39
|
+
scopeKey: input.scopeKey,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
select: { bytes: true },
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
throw new VisualBaselineStoreError('io_failed', `createPrismaVisualBaselineStore: getBaseline raised: ${err.message}`, err);
|
|
47
|
+
}
|
|
48
|
+
if (row === null)
|
|
49
|
+
return null;
|
|
50
|
+
// Prisma maps Bytes columns to Buffer at runtime; Buffer extends
|
|
51
|
+
// Uint8Array so callers see the contract type.
|
|
52
|
+
return new Uint8Array(row.bytes);
|
|
53
|
+
},
|
|
54
|
+
async setBaseline(input) {
|
|
55
|
+
assertNonEmpty(input.projectId, 'projectId');
|
|
56
|
+
assertNonEmpty(input.scopeKey, 'scopeKey');
|
|
57
|
+
assertNonEmptyBytes(input.bytes);
|
|
58
|
+
// Prisma's BYTEA writes accept Buffer. Buffer.from(Uint8Array) copies
|
|
59
|
+
// bytes into a new Buffer — predictable and avoids ArrayBufferLike
|
|
60
|
+
// typing edge cases (SharedArrayBuffer, etc.). Screenshot byte sizes
|
|
61
|
+
// are small enough that the copy cost is negligible.
|
|
62
|
+
const buf = Buffer.from(input.bytes);
|
|
63
|
+
try {
|
|
64
|
+
await prisma.visualBaseline.upsert({
|
|
65
|
+
where: {
|
|
66
|
+
projectId_scopeKey: {
|
|
67
|
+
projectId: input.projectId,
|
|
68
|
+
scopeKey: input.scopeKey,
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
create: {
|
|
72
|
+
projectId: input.projectId,
|
|
73
|
+
scopeKey: input.scopeKey,
|
|
74
|
+
bytes: buf,
|
|
75
|
+
},
|
|
76
|
+
update: {
|
|
77
|
+
bytes: buf,
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
throw new VisualBaselineStoreError('io_failed', `createPrismaVisualBaselineStore: setBaseline raised: ${err.message}`, err);
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=visual-baseline-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visual-baseline-store.js","sourceRoot":"","sources":["../src/visual-baseline-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,wBAAwB,EAA4B,MAAM,eAAe,CAAC;AASnF,4EAA4E;AAE5E,SAAS,cAAc,CAAC,KAAc,EAAE,SAAiB;IACvD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrD,MAAM,IAAI,wBAAwB,CAChC,eAAe,EACf,oCAAoC,SAAS,4BAA4B,CAC1E,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAc;IACzC,IAAI,CAAC,CAAC,KAAK,YAAY,UAAU,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,wBAAwB,CAChC,eAAe,EACf,uEAAuE,CACxE,CAAC;IACJ,CAAC;AACH,CAAC;AAED,4EAA4E;AAE5E,MAAM,UAAU,+BAA+B,CAC7C,MAAuC;IAEvC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAE1B,OAAO;QACL,KAAK,CAAC,WAAW,CAAC,KAA8C;YAC9D,cAAc,CAAC,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;YAC7C,cAAc,CAAC,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YAE3C,IAAI,GAAG,CAAC;YACR,IAAI,CAAC;gBACH,GAAG,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,UAAU,CAAC;oBAC3C,KAAK,EAAE;wBACL,kBAAkB,EAAE;4BAClB,SAAS,EAAE,KAAK,CAAC,SAAS;4BAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ;yBACzB;qBACF;oBACD,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;iBACxB,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,IAAI,wBAAwB,CAChC,WAAW,EACX,wDAAyD,GAAa,CAAC,OAAO,EAAE,EAChF,GAAG,CACJ,CAAC;YACJ,CAAC;YAED,IAAI,GAAG,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAC;YAC9B,iEAAiE;YACjE,+CAA+C;YAC/C,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,KAAK,CAAC,WAAW,CAAC,KAIjB;YACC,cAAc,CAAC,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;YAC7C,cAAc,CAAC,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YAC3C,mBAAmB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAEjC,sEAAsE;YACtE,mEAAmE;YACnE,qEAAqE;YACrE,qDAAqD;YACrD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAErC,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC;oBACjC,KAAK,EAAE;wBACL,kBAAkB,EAAE;4BAClB,SAAS,EAAE,KAAK,CAAC,SAAS;4BAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ;yBACzB;qBACF;oBACD,MAAM,EAAE;wBACN,SAAS,EAAE,KAAK,CAAC,SAAS;wBAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ;wBACxB,KAAK,EAAE,GAAG;qBACX;oBACD,MAAM,EAAE;wBACN,KAAK,EAAE,GAAG;qBACX;iBACF,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,IAAI,wBAAwB,CAChC,WAAW,EACX,wDAAyD,GAAa,CAAC,OAAO,EAAE,EAChF,GAAG,CACJ,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@derwinjs/db",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Prisma schema + migrations for Derwin's own Postgres. 14 models, project-namespaced. Per ADR-0005. Ships its own generated Prisma client (multi-platform binaries) for cross-consumer compatibility.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"type": "module",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@prisma/client": "^5.22.0",
|
|
36
|
-
"@derwinjs/
|
|
37
|
-
"@derwinjs/
|
|
36
|
+
"@derwinjs/sdk": "0.10.0",
|
|
37
|
+
"@derwinjs/core": "0.10.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@vitest/coverage-v8": "^2.1.9",
|