@adcp/sdk 6.4.1 → 6.6.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/bin/adcp.js +99 -0
- package/dist/lib/core/AgentClient.d.ts.map +1 -1
- package/dist/lib/core/SingleAgentClient.d.ts.map +1 -1
- package/dist/lib/core/SingleAgentClient.js +31 -0
- package/dist/lib/core/SingleAgentClient.js.map +1 -1
- package/dist/lib/mock-server/creative-template/seed-data.d.ts +45 -0
- package/dist/lib/mock-server/creative-template/seed-data.d.ts.map +1 -0
- package/dist/lib/mock-server/creative-template/seed-data.js +149 -0
- package/dist/lib/mock-server/creative-template/seed-data.js.map +1 -0
- package/dist/lib/mock-server/creative-template/server.d.ts +13 -0
- package/dist/lib/mock-server/creative-template/server.d.ts.map +1 -0
- package/dist/lib/mock-server/creative-template/server.js +280 -0
- package/dist/lib/mock-server/creative-template/server.js.map +1 -0
- package/dist/lib/mock-server/index.d.ts +38 -0
- package/dist/lib/mock-server/index.d.ts.map +1 -0
- package/dist/lib/mock-server/index.js +107 -0
- package/dist/lib/mock-server/index.js.map +1 -0
- package/dist/lib/mock-server/signal-marketplace/seed-data.d.ts +77 -0
- package/dist/lib/mock-server/signal-marketplace/seed-data.d.ts.map +1 -0
- package/dist/lib/mock-server/signal-marketplace/seed-data.js +194 -0
- package/dist/lib/mock-server/signal-marketplace/seed-data.js.map +1 -0
- package/dist/lib/mock-server/signal-marketplace/server.d.ts +15 -0
- package/dist/lib/mock-server/signal-marketplace/server.d.ts.map +1 -0
- package/dist/lib/mock-server/signal-marketplace/server.js +333 -0
- package/dist/lib/mock-server/signal-marketplace/server.js.map +1 -0
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/decisioning/capabilities.d.ts +7 -2
- package/dist/lib/server/decisioning/capabilities.d.ts.map +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.d.ts.map +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.js +144 -2
- package/dist/lib/server/decisioning/runtime/from-platform.js.map +1 -1
- package/dist/lib/testing/storyboard/assertions.d.ts +1 -19
- package/dist/lib/testing/storyboard/assertions.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/assertions.js.map +1 -1
- package/dist/lib/testing/storyboard/loader.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/loader.js +38 -0
- package/dist/lib/testing/storyboard/loader.js.map +1 -1
- package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/runner.js +67 -68
- package/dist/lib/testing/storyboard/runner.js.map +1 -1
- package/dist/lib/testing/storyboard/types.d.ts +33 -0
- package/dist/lib/testing/storyboard/types.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/types.js.map +1 -1
- package/dist/lib/utils/capabilities.d.ts +22 -0
- package/dist/lib/utils/capabilities.d.ts.map +1 -1
- package/dist/lib/utils/capabilities.js +44 -0
- package/dist/lib/utils/capabilities.js.map +1 -1
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/package.json +1 -1
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_API_KEY = exports.WORKSPACES = exports.TEMPLATES = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Templates seeded across both workspaces. Each represents a common creative
|
|
6
|
+
* shape (display medium rectangle, leaderboard, mobile banner, video
|
|
7
|
+
* preroll). The slot definitions intentionally use upstream vocabulary
|
|
8
|
+
* (`slot_id`) rather than AdCP's `asset_role` so the adapter has to
|
|
9
|
+
* translate during list_creative_formats projection.
|
|
10
|
+
*/
|
|
11
|
+
exports.TEMPLATES = [
|
|
12
|
+
{
|
|
13
|
+
template_id: 'tpl_celtra_display_medrec_v2',
|
|
14
|
+
name: 'Display Medium Rectangle (300x250)',
|
|
15
|
+
description: 'Standard IAB medium rectangle with brand-aware text overlay and CTA.',
|
|
16
|
+
channel: 'display',
|
|
17
|
+
dimensions: { width: 300, height: 250 },
|
|
18
|
+
output_kind: 'html_tag',
|
|
19
|
+
slots: [
|
|
20
|
+
{
|
|
21
|
+
slot_id: 'image',
|
|
22
|
+
asset_type: 'image',
|
|
23
|
+
required: true,
|
|
24
|
+
constraints: { width: 300, height: 250, mime_types: ['image/jpeg', 'image/png', 'image/webp'] },
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
slot_id: 'headline',
|
|
28
|
+
asset_type: 'text',
|
|
29
|
+
required: true,
|
|
30
|
+
constraints: { max_chars: 40 },
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
slot_id: 'cta',
|
|
34
|
+
asset_type: 'text',
|
|
35
|
+
required: true,
|
|
36
|
+
constraints: { max_chars: 20 },
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
slot_id: 'click_through',
|
|
40
|
+
asset_type: 'click_url',
|
|
41
|
+
required: true,
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
sample_inputs: {
|
|
45
|
+
image_url: 'https://test-assets.adcontextprotocol.org/acme-outdoor/hero-300x250.jpg',
|
|
46
|
+
headline: 'Built for the trail.',
|
|
47
|
+
cta: 'Shop Gear',
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
template_id: 'tpl_celtra_display_leaderboard_v2',
|
|
52
|
+
name: 'Display Leaderboard (728x90)',
|
|
53
|
+
description: 'Standard IAB leaderboard with brand-aware text overlay and CTA. JS tag output (carries impression macros, viewability shims, MRAID/SafeFrame hooks per IAB OpenRTB 2.6 §3.2.4).',
|
|
54
|
+
channel: 'display',
|
|
55
|
+
dimensions: { width: 728, height: 90 },
|
|
56
|
+
output_kind: 'javascript_tag',
|
|
57
|
+
slots: [
|
|
58
|
+
{
|
|
59
|
+
slot_id: 'image',
|
|
60
|
+
asset_type: 'image',
|
|
61
|
+
required: true,
|
|
62
|
+
constraints: { width: 728, height: 90, mime_types: ['image/jpeg', 'image/png', 'image/webp'] },
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
slot_id: 'headline',
|
|
66
|
+
asset_type: 'text',
|
|
67
|
+
required: true,
|
|
68
|
+
constraints: { max_chars: 60 },
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
slot_id: 'cta',
|
|
72
|
+
asset_type: 'text',
|
|
73
|
+
required: true,
|
|
74
|
+
constraints: { max_chars: 20 },
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
slot_id: 'click_through',
|
|
78
|
+
asset_type: 'click_url',
|
|
79
|
+
required: true,
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
template_id: 'tpl_celtra_mobile_banner_v2',
|
|
85
|
+
name: 'Mobile Banner (320x50)',
|
|
86
|
+
description: 'Standard IAB mobile banner. JS tag output for in-app/MRAID compatibility.',
|
|
87
|
+
channel: 'display',
|
|
88
|
+
dimensions: { width: 320, height: 50 },
|
|
89
|
+
output_kind: 'javascript_tag',
|
|
90
|
+
slots: [
|
|
91
|
+
{
|
|
92
|
+
slot_id: 'image',
|
|
93
|
+
asset_type: 'image',
|
|
94
|
+
required: true,
|
|
95
|
+
constraints: { width: 320, height: 50, mime_types: ['image/jpeg', 'image/png', 'image/webp'] },
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
slot_id: 'cta',
|
|
99
|
+
asset_type: 'text',
|
|
100
|
+
required: true,
|
|
101
|
+
constraints: { max_chars: 16 },
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
slot_id: 'click_through',
|
|
105
|
+
asset_type: 'click_url',
|
|
106
|
+
required: true,
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
template_id: 'tpl_celtra_video_preroll_v1',
|
|
112
|
+
name: 'Video Preroll (15s)',
|
|
113
|
+
description: 'In-stream video preroll with 15-second cap and end card.',
|
|
114
|
+
channel: 'video',
|
|
115
|
+
duration_seconds: { min: 6, max: 15 },
|
|
116
|
+
output_kind: 'vast_xml',
|
|
117
|
+
slots: [
|
|
118
|
+
{
|
|
119
|
+
slot_id: 'video',
|
|
120
|
+
asset_type: 'video',
|
|
121
|
+
required: true,
|
|
122
|
+
constraints: { duration_max_seconds: 15, mime_types: ['video/mp4', 'video/webm'] },
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
slot_id: 'click_through',
|
|
126
|
+
asset_type: 'click_url',
|
|
127
|
+
required: true,
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
];
|
|
132
|
+
exports.WORKSPACES = [
|
|
133
|
+
{
|
|
134
|
+
workspace_id: 'ws_acme_studio',
|
|
135
|
+
display_name: 'Acme Outdoor Creative Studio',
|
|
136
|
+
adcp_advertiser: 'acmeoutdoor.example',
|
|
137
|
+
visible_template_ids: exports.TEMPLATES.map(t => t.template_id),
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
workspace_id: 'ws_summit_studio',
|
|
141
|
+
display_name: 'Summit Media Creative Studio',
|
|
142
|
+
adcp_advertiser: 'summit-media.example',
|
|
143
|
+
// Summit's workspace doesn't have video access — only display templates.
|
|
144
|
+
visible_template_ids: exports.TEMPLATES.filter(t => t.channel === 'display').map(t => t.template_id),
|
|
145
|
+
},
|
|
146
|
+
];
|
|
147
|
+
/** Default static API key. Override via `--api-key` at boot. */
|
|
148
|
+
exports.DEFAULT_API_KEY = 'mock_creative_template_key_do_not_use_in_prod';
|
|
149
|
+
//# sourceMappingURL=seed-data.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seed-data.js","sourceRoot":"","sources":["../../../../src/lib/mock-server/creative-template/seed-data.ts"],"names":[],"mappings":";;;AA8BA;;;;;;GAMG;AACU,QAAA,SAAS,GAAmB;IACvC;QACE,WAAW,EAAE,8BAA8B;QAC3C,IAAI,EAAE,oCAAoC;QAC1C,WAAW,EAAE,sEAAsE;QACnF,OAAO,EAAE,SAAS;QAClB,UAAU,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE;QACvC,WAAW,EAAE,UAAU;QACvB,KAAK,EAAE;YACL;gBACE,OAAO,EAAE,OAAO;gBAChB,UAAU,EAAE,OAAO;gBACnB,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,YAAY,CAAC,EAAE;aAChG;YACD;gBACE,OAAO,EAAE,UAAU;gBACnB,UAAU,EAAE,MAAM;gBAClB,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;aAC/B;YACD;gBACE,OAAO,EAAE,KAAK;gBACd,UAAU,EAAE,MAAM;gBAClB,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;aAC/B;YACD;gBACE,OAAO,EAAE,eAAe;gBACxB,UAAU,EAAE,WAAW;gBACvB,QAAQ,EAAE,IAAI;aACf;SACF;QACD,aAAa,EAAE;YACb,SAAS,EAAE,yEAAyE;YACpF,QAAQ,EAAE,sBAAsB;YAChC,GAAG,EAAE,WAAW;SACjB;KACF;IACD;QACE,WAAW,EAAE,mCAAmC;QAChD,IAAI,EAAE,8BAA8B;QACpC,WAAW,EACT,iLAAiL;QACnL,OAAO,EAAE,SAAS;QAClB,UAAU,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE;QACtC,WAAW,EAAE,gBAAgB;QAC7B,KAAK,EAAE;YACL;gBACE,OAAO,EAAE,OAAO;gBAChB,UAAU,EAAE,OAAO;gBACnB,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,YAAY,CAAC,EAAE;aAC/F;YACD;gBACE,OAAO,EAAE,UAAU;gBACnB,UAAU,EAAE,MAAM;gBAClB,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;aAC/B;YACD;gBACE,OAAO,EAAE,KAAK;gBACd,UAAU,EAAE,MAAM;gBAClB,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;aAC/B;YACD;gBACE,OAAO,EAAE,eAAe;gBACxB,UAAU,EAAE,WAAW;gBACvB,QAAQ,EAAE,IAAI;aACf;SACF;KACF;IACD;QACE,WAAW,EAAE,6BAA6B;QAC1C,IAAI,EAAE,wBAAwB;QAC9B,WAAW,EAAE,2EAA2E;QACxF,OAAO,EAAE,SAAS;QAClB,UAAU,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE;QACtC,WAAW,EAAE,gBAAgB;QAC7B,KAAK,EAAE;YACL;gBACE,OAAO,EAAE,OAAO;gBAChB,UAAU,EAAE,OAAO;gBACnB,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,YAAY,CAAC,EAAE;aAC/F;YACD;gBACE,OAAO,EAAE,KAAK;gBACd,UAAU,EAAE,MAAM;gBAClB,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;aAC/B;YACD;gBACE,OAAO,EAAE,eAAe;gBACxB,UAAU,EAAE,WAAW;gBACvB,QAAQ,EAAE,IAAI;aACf;SACF;KACF;IACD;QACE,WAAW,EAAE,6BAA6B;QAC1C,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EAAE,0DAA0D;QACvE,OAAO,EAAE,OAAO;QAChB,gBAAgB,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;QACrC,WAAW,EAAE,UAAU;QACvB,KAAK,EAAE;YACL;gBACE,OAAO,EAAE,OAAO;gBAChB,UAAU,EAAE,OAAO;gBACnB,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,EAAE,oBAAoB,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC,EAAE;aACnF;YACD;gBACE,OAAO,EAAE,eAAe;gBACxB,UAAU,EAAE,WAAW;gBACvB,QAAQ,EAAE,IAAI;aACf;SACF;KACF;CACF,CAAC;AAEW,QAAA,UAAU,GAAoB;IACzC;QACE,YAAY,EAAE,gBAAgB;QAC9B,YAAY,EAAE,8BAA8B;QAC5C,eAAe,EAAE,qBAAqB;QACtC,oBAAoB,EAAE,iBAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;KACxD;IACD;QACE,YAAY,EAAE,kBAAkB;QAChC,YAAY,EAAE,8BAA8B;QAC5C,eAAe,EAAE,sBAAsB;QACvC,yEAAyE;QACzE,oBAAoB,EAAE,iBAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;KAC7F;CACF,CAAC;AAEF,gEAAgE;AACnD,QAAA,eAAe,GAAG,+CAA+C,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type MockTemplate, type MockWorkspace } from './seed-data';
|
|
2
|
+
export interface BootOptions {
|
|
3
|
+
port: number;
|
|
4
|
+
apiKey?: string;
|
|
5
|
+
templates?: MockTemplate[];
|
|
6
|
+
workspaces?: MockWorkspace[];
|
|
7
|
+
}
|
|
8
|
+
export interface BootResult {
|
|
9
|
+
url: string;
|
|
10
|
+
close: () => Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
export declare function bootCreativeTemplate(options: BootOptions): Promise<BootResult>;
|
|
13
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../../src/lib/mock-server/creative-template/server.ts"],"names":[],"mappings":"AAEA,OAAO,EAA0C,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5G,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,YAAY,EAAE,CAAC;IAC3B,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAsBD,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAuCpF"}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.bootCreativeTemplate = bootCreativeTemplate;
|
|
4
|
+
const node_http_1 = require("node:http");
|
|
5
|
+
const node_crypto_1 = require("node:crypto");
|
|
6
|
+
const seed_data_1 = require("./seed-data");
|
|
7
|
+
async function bootCreativeTemplate(options) {
|
|
8
|
+
const apiKey = options.apiKey ?? seed_data_1.DEFAULT_API_KEY;
|
|
9
|
+
const templates = options.templates ?? seed_data_1.TEMPLATES;
|
|
10
|
+
const workspaces = options.workspaces ?? seed_data_1.WORKSPACES;
|
|
11
|
+
const renders = new Map();
|
|
12
|
+
// client_request_id idempotency table — keyed by `<workspace_id>::<key>`.
|
|
13
|
+
const idempotency = new Map();
|
|
14
|
+
const server = (0, node_http_1.createServer)((req, res) => {
|
|
15
|
+
handleRequest(req, res, { apiKey, templates, workspaces, renders, idempotency }).catch(err => {
|
|
16
|
+
const requestId = req.headers['x-request-id'] ?? (0, node_crypto_1.randomUUID)();
|
|
17
|
+
writeJson(res, 500, {
|
|
18
|
+
code: 'internal_error',
|
|
19
|
+
message: err?.message ?? 'unexpected error',
|
|
20
|
+
request_id: requestId,
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
await new Promise((resolve, reject) => {
|
|
25
|
+
server.once('error', reject);
|
|
26
|
+
server.listen(options.port, '127.0.0.1', () => {
|
|
27
|
+
server.removeListener('error', reject);
|
|
28
|
+
resolve();
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
const addr = server.address();
|
|
32
|
+
const boundPort = typeof addr === 'object' && addr ? addr.port : options.port;
|
|
33
|
+
const url = `http://127.0.0.1:${boundPort}`;
|
|
34
|
+
return {
|
|
35
|
+
url,
|
|
36
|
+
close: () => new Promise((resolve, reject) => {
|
|
37
|
+
server.close(err => (err ? reject(err) : resolve()));
|
|
38
|
+
}),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
async function handleRequest(req, res, ctx) {
|
|
42
|
+
// Authentication first.
|
|
43
|
+
const auth = req.headers['authorization'];
|
|
44
|
+
if (!auth || !auth.startsWith('Bearer ') || auth.slice(7) !== ctx.apiKey) {
|
|
45
|
+
writeJson(res, 401, { code: 'unauthorized', message: 'Missing or invalid bearer credential.' });
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const url = new URL(req.url ?? '/', `http://127.0.0.1`);
|
|
49
|
+
const path = url.pathname;
|
|
50
|
+
const method = req.method ?? 'GET';
|
|
51
|
+
// Path-based workspace scoping. Matches /v3/workspaces/{ws}/...
|
|
52
|
+
const wsMatch = path.match(/^\/v3\/workspaces\/([^/]+)(\/.*)?$/);
|
|
53
|
+
if (!wsMatch || !wsMatch[1]) {
|
|
54
|
+
writeJson(res, 404, { code: 'not_found', message: `No route for ${method} ${path}` });
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const workspaceId = decodeURIComponent(wsMatch[1]);
|
|
58
|
+
const subPath = wsMatch[2] ?? '/';
|
|
59
|
+
const workspace = ctx.workspaces.find(w => w.workspace_id === workspaceId);
|
|
60
|
+
if (!workspace) {
|
|
61
|
+
writeJson(res, 404, { code: 'workspace_not_found', message: `Workspace ${workspaceId} not found.` });
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
// GET /v3/workspaces/{ws}/templates
|
|
65
|
+
if (method === 'GET' && subPath === '/templates') {
|
|
66
|
+
return handleListTemplates(url, ctx, workspace, res);
|
|
67
|
+
}
|
|
68
|
+
// GET /v3/workspaces/{ws}/templates/{tpl_id}
|
|
69
|
+
const tplMatch = subPath.match(/^\/templates\/([^/]+)$/);
|
|
70
|
+
if (method === 'GET' && tplMatch && tplMatch[1]) {
|
|
71
|
+
return handleGetTemplate(decodeURIComponent(tplMatch[1]), ctx, workspace, res);
|
|
72
|
+
}
|
|
73
|
+
// POST /v3/workspaces/{ws}/renders
|
|
74
|
+
if (method === 'POST' && subPath === '/renders') {
|
|
75
|
+
return handleCreateRender(req, ctx, workspace, res);
|
|
76
|
+
}
|
|
77
|
+
// GET /v3/workspaces/{ws}/renders/{render_id}
|
|
78
|
+
const rMatch = subPath.match(/^\/renders\/([^/]+)$/);
|
|
79
|
+
if (method === 'GET' && rMatch && rMatch[1]) {
|
|
80
|
+
return handleGetRender(decodeURIComponent(rMatch[1]), ctx, workspace, res);
|
|
81
|
+
}
|
|
82
|
+
writeJson(res, 404, { code: 'not_found', message: `No route for ${method} ${path}` });
|
|
83
|
+
}
|
|
84
|
+
function handleListTemplates(url, ctx, ws, res) {
|
|
85
|
+
const visible = ctx.templates.filter(t => ws.visible_template_ids.includes(t.template_id));
|
|
86
|
+
const channel = url.searchParams.get('channel');
|
|
87
|
+
const filtered = channel ? visible.filter(t => t.channel === channel) : visible;
|
|
88
|
+
writeJson(res, 200, { templates: filtered });
|
|
89
|
+
}
|
|
90
|
+
function handleGetTemplate(templateId, ctx, ws, res) {
|
|
91
|
+
const template = ctx.templates.find(t => t.template_id === templateId);
|
|
92
|
+
if (!template) {
|
|
93
|
+
writeJson(res, 404, { code: 'template_not_found', message: `Template ${templateId} not found.` });
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (!ws.visible_template_ids.includes(templateId)) {
|
|
97
|
+
writeJson(res, 404, {
|
|
98
|
+
code: 'template_not_visible',
|
|
99
|
+
message: `Template ${templateId} is not visible to workspace ${ws.workspace_id}.`,
|
|
100
|
+
});
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
writeJson(res, 200, template);
|
|
104
|
+
}
|
|
105
|
+
async function handleCreateRender(req, ctx, ws, res) {
|
|
106
|
+
let body;
|
|
107
|
+
try {
|
|
108
|
+
body = await readJson(req);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
writeJson(res, 400, { code: 'invalid_json', message: 'Request body must be valid JSON.' });
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (!isObject(body)) {
|
|
115
|
+
writeJson(res, 400, { code: 'invalid_request', message: 'Body must be an object.' });
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const { template_id, inputs, mode, client_request_id } = body;
|
|
119
|
+
if (typeof template_id !== 'string' || !Array.isArray(inputs) || (mode !== 'preview' && mode !== 'build')) {
|
|
120
|
+
writeJson(res, 400, {
|
|
121
|
+
code: 'invalid_request',
|
|
122
|
+
message: 'template_id (string), inputs (array), and mode ("preview" or "build") are required.',
|
|
123
|
+
});
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const template = ctx.templates.find(t => t.template_id === template_id);
|
|
127
|
+
if (!template || !ws.visible_template_ids.includes(template_id)) {
|
|
128
|
+
writeJson(res, 404, {
|
|
129
|
+
code: template ? 'template_not_visible' : 'template_not_found',
|
|
130
|
+
message: `Template ${template_id} ${template ? 'not visible' : 'not found'}.`,
|
|
131
|
+
});
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const fingerprint = fingerprintBody(template_id, inputs, mode);
|
|
135
|
+
// Idempotency replay (same body) / conflict (mismatched body).
|
|
136
|
+
if (typeof client_request_id === 'string' && client_request_id.length > 0) {
|
|
137
|
+
const idemKey = `${ws.workspace_id}::${client_request_id}`;
|
|
138
|
+
const existing = ctx.idempotency.get(idemKey);
|
|
139
|
+
if (existing) {
|
|
140
|
+
const render = ctx.renders.get(existing);
|
|
141
|
+
if (render) {
|
|
142
|
+
if (render.body_fingerprint !== fingerprint) {
|
|
143
|
+
writeJson(res, 409, {
|
|
144
|
+
code: 'idempotency_conflict',
|
|
145
|
+
message: `client_request_id ${client_request_id} was previously used with a different body. Use a fresh idempotency key for distinct requests.`,
|
|
146
|
+
});
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
writeJson(res, 200, serializeRender(render));
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const renderId = `rnd_${(0, node_crypto_1.randomUUID)().replace(/-/g, '').slice(0, 16)}`;
|
|
155
|
+
const now = new Date();
|
|
156
|
+
const render = {
|
|
157
|
+
render_id: renderId,
|
|
158
|
+
workspace_id: ws.workspace_id,
|
|
159
|
+
status: 'queued',
|
|
160
|
+
template_id,
|
|
161
|
+
mode,
|
|
162
|
+
body_fingerprint: fingerprint,
|
|
163
|
+
created_at: now.toISOString(),
|
|
164
|
+
updated_at: now.toISOString(),
|
|
165
|
+
};
|
|
166
|
+
ctx.renders.set(renderId, render);
|
|
167
|
+
if (typeof client_request_id === 'string' && client_request_id.length > 0) {
|
|
168
|
+
ctx.idempotency.set(`${ws.workspace_id}::${client_request_id}`, renderId);
|
|
169
|
+
}
|
|
170
|
+
writeJson(res, 202, serializeRender(render));
|
|
171
|
+
}
|
|
172
|
+
function handleGetRender(renderId, ctx, ws, res) {
|
|
173
|
+
const render = ctx.renders.get(renderId);
|
|
174
|
+
if (!render) {
|
|
175
|
+
writeJson(res, 404, { code: 'render_not_found', message: `Render ${renderId} not found.` });
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
if (render.workspace_id !== ws.workspace_id) {
|
|
179
|
+
writeJson(res, 404, {
|
|
180
|
+
code: 'render_not_in_workspace',
|
|
181
|
+
message: `Render ${renderId} not found in workspace ${ws.workspace_id}.`,
|
|
182
|
+
});
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
// Auto-promote queued → running on first poll, running → complete on second.
|
|
186
|
+
// Real platforms render in seconds-to-minutes; the mock simulates a fast
|
|
187
|
+
// async with two state transitions to exercise polling without making the
|
|
188
|
+
// matrix run drag. The `else if` chain means a `complete` render is a
|
|
189
|
+
// terminal state — subsequent polls return the same complete render
|
|
190
|
+
// without further mutation. Callers serializing polls (one GET at a time)
|
|
191
|
+
// observe each transition exactly once; concurrent polls in flight will
|
|
192
|
+
// both see the post-transition state, which is fine for a fixture but
|
|
193
|
+
// means the matrix harness should not race polls against itself.
|
|
194
|
+
const template = ctx.templates.find(t => t.template_id === render.template_id);
|
|
195
|
+
if (render.status === 'queued') {
|
|
196
|
+
render.status = 'running';
|
|
197
|
+
render.updated_at = new Date().toISOString();
|
|
198
|
+
}
|
|
199
|
+
else if (render.status === 'running') {
|
|
200
|
+
render.status = 'complete';
|
|
201
|
+
render.updated_at = new Date().toISOString();
|
|
202
|
+
render.output = synthesizeOutput(render, template);
|
|
203
|
+
}
|
|
204
|
+
writeJson(res, 200, serializeRender(render));
|
|
205
|
+
}
|
|
206
|
+
function synthesizeOutput(render, template) {
|
|
207
|
+
// Fixture output. Real platforms return real ad tags / VAST XML / etc; the
|
|
208
|
+
// mock returns plausible-looking synthetic output so adapters can pattern-
|
|
209
|
+
// match without rendering anything real. The kind is driven by the
|
|
210
|
+
// template's output_kind so the adapter has to read it and project to AdCP
|
|
211
|
+
// creative_manifest correctly.
|
|
212
|
+
const previewBase = `https://mock-creative-template.example/preview/${render.render_id}`;
|
|
213
|
+
if (!template) {
|
|
214
|
+
return { preview_url: previewBase };
|
|
215
|
+
}
|
|
216
|
+
if (template.output_kind === 'vast_xml') {
|
|
217
|
+
return {
|
|
218
|
+
vast_xml: `<?xml version="1.0"?><VAST version="4.2"><Ad id="${render.render_id}"><InLine><AdSystem>MockCreativeTemplate</AdSystem><AdTitle>${template.name}</AdTitle></InLine></Ad></VAST>`,
|
|
219
|
+
preview_url: previewBase,
|
|
220
|
+
assets: [{ kind: 'video_tag', mime_type: 'application/xml+vast' }],
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
if (template.output_kind === 'javascript_tag') {
|
|
224
|
+
return {
|
|
225
|
+
tag_javascript: `(function(){var d=document;var img=d.createElement('img');img.src='${previewBase}.png';d.write(img.outerHTML);})();`,
|
|
226
|
+
preview_url: previewBase,
|
|
227
|
+
assets: [{ kind: 'js_tag', mime_type: 'application/javascript' }],
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
// default html_tag
|
|
231
|
+
return {
|
|
232
|
+
tag_html: `<a href="https://example.com/click"><img src="${previewBase}.png" width="${template.dimensions?.width ?? 300}" height="${template.dimensions?.height ?? 250}" alt="${template.name}" /></a>`,
|
|
233
|
+
preview_url: previewBase,
|
|
234
|
+
assets: [{ kind: 'html_tag', mime_type: 'text/html' }],
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
function serializeRender(r) {
|
|
238
|
+
// workspace_id / body_fingerprint are internal book-keeping — strip from public payload.
|
|
239
|
+
const { workspace_id, body_fingerprint, ...rest } = r;
|
|
240
|
+
return rest;
|
|
241
|
+
}
|
|
242
|
+
function fingerprintBody(templateId, inputs, mode) {
|
|
243
|
+
// Stable JSON canonicalization for body equivalence. Serializing a sorted-
|
|
244
|
+
// key copy gives whitespace/order independence without pulling in a
|
|
245
|
+
// dependency. Inputs are array-position-significant (slot order matters
|
|
246
|
+
// for some upstream renders), so we don't sort the array itself.
|
|
247
|
+
return JSON.stringify({ template_id: templateId, inputs, mode });
|
|
248
|
+
}
|
|
249
|
+
function readJson(req) {
|
|
250
|
+
return new Promise((resolve, reject) => {
|
|
251
|
+
const chunks = [];
|
|
252
|
+
req.on('data', c => chunks.push(c));
|
|
253
|
+
req.on('error', reject);
|
|
254
|
+
req.on('end', () => {
|
|
255
|
+
const raw = Buffer.concat(chunks).toString('utf8');
|
|
256
|
+
if (!raw) {
|
|
257
|
+
resolve({});
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
try {
|
|
261
|
+
resolve(JSON.parse(raw));
|
|
262
|
+
}
|
|
263
|
+
catch (err) {
|
|
264
|
+
reject(err);
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
function writeJson(res, status, body) {
|
|
270
|
+
const json = JSON.stringify(body);
|
|
271
|
+
res.writeHead(status, {
|
|
272
|
+
'content-type': 'application/json; charset=utf-8',
|
|
273
|
+
'content-length': Buffer.byteLength(json),
|
|
274
|
+
});
|
|
275
|
+
res.end(json);
|
|
276
|
+
}
|
|
277
|
+
function isObject(x) {
|
|
278
|
+
return typeof x === 'object' && x !== null && !Array.isArray(x);
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../../src/lib/mock-server/creative-template/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export interface MockServerOptions {
|
|
2
|
+
specialism: string;
|
|
3
|
+
port: number;
|
|
4
|
+
apiKey?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface MockServerHandle {
|
|
7
|
+
url: string;
|
|
8
|
+
apiKey: string;
|
|
9
|
+
close: () => Promise<void>;
|
|
10
|
+
/** Adopter-friendly summary for boot-log printing. */
|
|
11
|
+
summary: () => string;
|
|
12
|
+
/** Specialism-agnostic principal-mapping table the matrix harness inlines
|
|
13
|
+
* into the build prompt so Claude can wire AdCP-side identity to upstream
|
|
14
|
+
* tenant/workspace ids without re-deriving them per specialism. */
|
|
15
|
+
principalMapping: PrincipalMappingEntry[];
|
|
16
|
+
/** Human-prose description of how the upstream gates per-tenant scope —
|
|
17
|
+
* e.g. "via X-Operator-Id header" or "via path /v3/workspaces/{id}/...".
|
|
18
|
+
* Surfaces in the harness prompt to make the auth-translation requirement
|
|
19
|
+
* explicit. */
|
|
20
|
+
principalScope: string;
|
|
21
|
+
}
|
|
22
|
+
export interface PrincipalMappingEntry {
|
|
23
|
+
adcpField: string;
|
|
24
|
+
adcpValue: string;
|
|
25
|
+
upstreamField: string;
|
|
26
|
+
upstreamValue: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Boot a mock upstream platform for the given specialism. Returns a handle
|
|
30
|
+
* the caller (CLI or matrix harness) uses to read connection details and
|
|
31
|
+
* shut down cleanly.
|
|
32
|
+
*
|
|
33
|
+
* Adding a new specialism means adding the upstream-shape OpenAPI + seed
|
|
34
|
+
* data + boot function under `src/lib/mock-server/<specialism>/` and a
|
|
35
|
+
* switch case here.
|
|
36
|
+
*/
|
|
37
|
+
export declare function bootMockServer(options: MockServerOptions): Promise<MockServerHandle>;
|
|
38
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/mock-server/index.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,sDAAsD;IACtD,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB;;uEAEmE;IACnE,gBAAgB,EAAE,qBAAqB,EAAE,CAAC;IAC1C;;;mBAGe;IACf,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA+C1F"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.bootMockServer = bootMockServer;
|
|
4
|
+
const server_1 = require("./creative-template/server");
|
|
5
|
+
const seed_data_1 = require("./creative-template/seed-data");
|
|
6
|
+
const server_2 = require("./signal-marketplace/server");
|
|
7
|
+
const seed_data_2 = require("./signal-marketplace/seed-data");
|
|
8
|
+
/**
|
|
9
|
+
* Boot a mock upstream platform for the given specialism. Returns a handle
|
|
10
|
+
* the caller (CLI or matrix harness) uses to read connection details and
|
|
11
|
+
* shut down cleanly.
|
|
12
|
+
*
|
|
13
|
+
* Adding a new specialism means adding the upstream-shape OpenAPI + seed
|
|
14
|
+
* data + boot function under `src/lib/mock-server/<specialism>/` and a
|
|
15
|
+
* switch case here.
|
|
16
|
+
*/
|
|
17
|
+
async function bootMockServer(options) {
|
|
18
|
+
switch (options.specialism) {
|
|
19
|
+
case 'signal-marketplace': {
|
|
20
|
+
const { url, close } = await (0, server_2.bootSignalMarketplace)({
|
|
21
|
+
port: options.port,
|
|
22
|
+
apiKey: options.apiKey,
|
|
23
|
+
});
|
|
24
|
+
const apiKey = options.apiKey ?? seed_data_2.DEFAULT_API_KEY;
|
|
25
|
+
return {
|
|
26
|
+
url,
|
|
27
|
+
apiKey,
|
|
28
|
+
close,
|
|
29
|
+
summary: () => formatSignalMarketplaceSummary(url, apiKey),
|
|
30
|
+
principalScope: 'X-Operator-Id header (required on every request)',
|
|
31
|
+
principalMapping: seed_data_2.OPERATORS.map(op => ({
|
|
32
|
+
adcpField: 'account.operator',
|
|
33
|
+
adcpValue: op.adcp_operator,
|
|
34
|
+
upstreamField: 'X-Operator-Id',
|
|
35
|
+
upstreamValue: op.operator_id,
|
|
36
|
+
})),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
case 'creative-template': {
|
|
40
|
+
const { url, close } = await (0, server_1.bootCreativeTemplate)({
|
|
41
|
+
port: options.port,
|
|
42
|
+
apiKey: options.apiKey,
|
|
43
|
+
});
|
|
44
|
+
const apiKey = options.apiKey ?? seed_data_1.DEFAULT_API_KEY;
|
|
45
|
+
return {
|
|
46
|
+
url,
|
|
47
|
+
apiKey,
|
|
48
|
+
close,
|
|
49
|
+
summary: () => formatCreativeTemplateSummary(url, apiKey),
|
|
50
|
+
principalScope: 'URL path segment /v3/workspaces/{workspace_id}/...',
|
|
51
|
+
principalMapping: seed_data_1.WORKSPACES.map(ws => ({
|
|
52
|
+
adcpField: 'account.advertiser',
|
|
53
|
+
adcpValue: ws.adcp_advertiser,
|
|
54
|
+
upstreamField: 'path /v3/workspaces/{workspace_id}/',
|
|
55
|
+
upstreamValue: ws.workspace_id,
|
|
56
|
+
})),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
default:
|
|
60
|
+
throw new Error(`Unknown mock-server specialism: "${options.specialism}". Supported: signal-marketplace, creative-template.`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function formatSignalMarketplaceSummary(url, apiKey) {
|
|
64
|
+
const operatorLines = seed_data_2.OPERATORS.map(op => ` ${op.operator_id} → AdCP account.operator: "${op.adcp_operator}" (visible cohorts: ${op.visible_cohort_ids.length})`).join('\n');
|
|
65
|
+
return [
|
|
66
|
+
`Mock signal marketplace running at ${url}`,
|
|
67
|
+
``,
|
|
68
|
+
`Auth:`,
|
|
69
|
+
` Authorization: Bearer ${apiKey}`,
|
|
70
|
+
` X-Operator-Id: <operator_id> (required on every call)`,
|
|
71
|
+
``,
|
|
72
|
+
`Operator mapping:`,
|
|
73
|
+
operatorLines,
|
|
74
|
+
``,
|
|
75
|
+
`OpenAPI spec: src/lib/mock-server/signal-marketplace/openapi.yaml`,
|
|
76
|
+
`Routes:`,
|
|
77
|
+
` GET ${url}/v2/cohorts`,
|
|
78
|
+
` GET ${url}/v2/cohorts/{cohort_id}`,
|
|
79
|
+
` GET ${url}/v2/destinations`,
|
|
80
|
+
` POST ${url}/v2/activations`,
|
|
81
|
+
` GET ${url}/v2/activations/{activation_id}`,
|
|
82
|
+
].join('\n');
|
|
83
|
+
}
|
|
84
|
+
function formatCreativeTemplateSummary(url, apiKey) {
|
|
85
|
+
const workspaceLines = seed_data_1.WORKSPACES.map(ws => ` ${ws.workspace_id} → AdCP account.advertiser: "${ws.adcp_advertiser}" (visible templates: ${ws.visible_template_ids.length})`).join('\n');
|
|
86
|
+
return [
|
|
87
|
+
`Mock creative-template platform running at ${url}`,
|
|
88
|
+
``,
|
|
89
|
+
`Auth:`,
|
|
90
|
+
` Authorization: Bearer ${apiKey}`,
|
|
91
|
+
` Workspace scoping via URL path: /v3/workspaces/{workspace_id}/...`,
|
|
92
|
+
``,
|
|
93
|
+
`Workspace mapping:`,
|
|
94
|
+
workspaceLines,
|
|
95
|
+
``,
|
|
96
|
+
`OpenAPI spec: src/lib/mock-server/creative-template/openapi.yaml`,
|
|
97
|
+
`Routes:`,
|
|
98
|
+
` GET ${url}/v3/workspaces/{ws}/templates`,
|
|
99
|
+
` GET ${url}/v3/workspaces/{ws}/templates/{template_id}`,
|
|
100
|
+
` POST ${url}/v3/workspaces/{ws}/renders`,
|
|
101
|
+
` GET ${url}/v3/workspaces/{ws}/renders/{render_id}`,
|
|
102
|
+
``,
|
|
103
|
+
`Renders are async: POST returns 202 with status="queued", then progresses`,
|
|
104
|
+
`through "running" → "complete" on subsequent GETs (or "failed" on error).`,
|
|
105
|
+
].join('\n');
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/mock-server/index.ts"],"names":[],"mappings":"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"}
|