@chidchanun/bcp 0.2.19 → 0.3.1
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/README.md +207 -98
- package/docs/README.md +82 -62
- package/docs/api-freeze-snapshot.json +254 -232
- package/docs/api-manifest.json +29 -13
- package/docs/api-reference.md +240 -149
- package/docs/application-platform.md +348 -0
- package/docs/docs-web-manifest.json +10 -5
- package/docs/migration-0.3.md +280 -0
- package/docs/platform-contract.md +68 -23
- package/docs/platform-manifest.json +38 -6
- package/docs/releases/0.3.0.md +129 -0
- package/docs/releases/0.3.1.md +116 -0
- package/docs/service-container.md +333 -0
- package/docs/stability-api-freeze.md +62 -91
- package/package.json +14 -2
- package/packages/bundler/src/client-boundary.ts +2 -0
- package/packages/client/src/application.mjs +2439 -0
- package/packages/client/src/application.ts +12 -0
- package/packages/client/src/container.mjs +573 -0
- package/packages/client/src/container.ts +24 -0
- package/packages/server/src/application.ts +956 -0
- package/packages/server/src/container.ts +970 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export {
|
|
2
|
+
ApplicationLifecycleError,
|
|
3
|
+
createApp,
|
|
4
|
+
defineApp,
|
|
5
|
+
|
|
6
|
+
type Application,
|
|
7
|
+
type ApplicationConfigParser,
|
|
8
|
+
type ApplicationConfigSchema,
|
|
9
|
+
type ApplicationContext,
|
|
10
|
+
type ApplicationDefinition,
|
|
11
|
+
type ApplicationState,
|
|
12
|
+
} from "../../server/src/application.js";
|
|
@@ -0,0 +1,573 @@
|
|
|
1
|
+
// packages/server/src/container.ts
|
|
2
|
+
var ServiceNotFoundError = class extends Error {
|
|
3
|
+
token;
|
|
4
|
+
constructor(token) {
|
|
5
|
+
super(
|
|
6
|
+
`BCP Container: service "${token.description}" is not registered.`
|
|
7
|
+
);
|
|
8
|
+
this.name = "ServiceNotFoundError";
|
|
9
|
+
this.token = token;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
var ServiceResolutionError = class extends Error {
|
|
13
|
+
token;
|
|
14
|
+
cause;
|
|
15
|
+
constructor(token, message, cause) {
|
|
16
|
+
super(
|
|
17
|
+
`BCP Container: could not resolve "${token.description}". ${message}`
|
|
18
|
+
);
|
|
19
|
+
this.name = "ServiceResolutionError";
|
|
20
|
+
this.token = token;
|
|
21
|
+
this.cause = cause;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
var ServiceDisposalError = class extends AggregateError {
|
|
25
|
+
constructor(errors) {
|
|
26
|
+
super(
|
|
27
|
+
errors,
|
|
28
|
+
"BCP Container: one or more services failed to dispose."
|
|
29
|
+
);
|
|
30
|
+
this.name = "ServiceDisposalError";
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
function createServiceToken(description) {
|
|
34
|
+
const normalized = normalizeName(
|
|
35
|
+
description,
|
|
36
|
+
"service token description"
|
|
37
|
+
);
|
|
38
|
+
return Object.freeze({
|
|
39
|
+
id: Symbol(normalized),
|
|
40
|
+
description: normalized
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function provideValue(token, value, options = {}) {
|
|
44
|
+
assertToken(token);
|
|
45
|
+
return {
|
|
46
|
+
token,
|
|
47
|
+
lifetime: "singleton",
|
|
48
|
+
factory() {
|
|
49
|
+
return value;
|
|
50
|
+
},
|
|
51
|
+
...options.dispose ? {
|
|
52
|
+
dispose: options.dispose
|
|
53
|
+
} : {}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function provideFactory(token, dependencies, factory, options = {}) {
|
|
57
|
+
assertToken(token);
|
|
58
|
+
assertDependencies(dependencies);
|
|
59
|
+
const lifetime = normalizeLifetime(
|
|
60
|
+
options.lifetime
|
|
61
|
+
);
|
|
62
|
+
return {
|
|
63
|
+
token,
|
|
64
|
+
lifetime,
|
|
65
|
+
dependencies: [
|
|
66
|
+
...dependencies
|
|
67
|
+
],
|
|
68
|
+
factory(context, values) {
|
|
69
|
+
return factory(
|
|
70
|
+
context,
|
|
71
|
+
values
|
|
72
|
+
);
|
|
73
|
+
},
|
|
74
|
+
...options.dispose ? {
|
|
75
|
+
dispose: options.dispose
|
|
76
|
+
} : {}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function provideClass(token, dependencies, Constructor, options = {}) {
|
|
80
|
+
if (typeof Constructor !== "function") {
|
|
81
|
+
throw new TypeError(
|
|
82
|
+
"BCP Container: service constructor must be a function."
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
return provideFactory(
|
|
86
|
+
token,
|
|
87
|
+
dependencies,
|
|
88
|
+
(_context, values) => new Constructor(
|
|
89
|
+
...values
|
|
90
|
+
),
|
|
91
|
+
options
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
function createServiceContainer(options = {}) {
|
|
95
|
+
const root = new ScopeImpl(
|
|
96
|
+
normalizeOptionalName(
|
|
97
|
+
options.name
|
|
98
|
+
) ?? "root",
|
|
99
|
+
void 0
|
|
100
|
+
);
|
|
101
|
+
root.root = root;
|
|
102
|
+
const container = {
|
|
103
|
+
get name() {
|
|
104
|
+
return root.name;
|
|
105
|
+
},
|
|
106
|
+
get state() {
|
|
107
|
+
return root.state;
|
|
108
|
+
},
|
|
109
|
+
get parent() {
|
|
110
|
+
return void 0;
|
|
111
|
+
},
|
|
112
|
+
has(token) {
|
|
113
|
+
return root.has(token);
|
|
114
|
+
},
|
|
115
|
+
resolve(token) {
|
|
116
|
+
return root.resolve(token);
|
|
117
|
+
},
|
|
118
|
+
optional(token) {
|
|
119
|
+
return root.optional(token);
|
|
120
|
+
},
|
|
121
|
+
createScope(scopeOptions = {}) {
|
|
122
|
+
return root.createScope(
|
|
123
|
+
scopeOptions
|
|
124
|
+
);
|
|
125
|
+
},
|
|
126
|
+
graph() {
|
|
127
|
+
return root.graph();
|
|
128
|
+
},
|
|
129
|
+
dispose() {
|
|
130
|
+
return root.dispose();
|
|
131
|
+
},
|
|
132
|
+
register(provider, registerOptions = {}) {
|
|
133
|
+
root.registerProvider(
|
|
134
|
+
provider,
|
|
135
|
+
registerOptions.replace === true
|
|
136
|
+
);
|
|
137
|
+
return container;
|
|
138
|
+
},
|
|
139
|
+
registerMany(providers) {
|
|
140
|
+
for (const provider of providers) {
|
|
141
|
+
root.registerProvider(
|
|
142
|
+
provider,
|
|
143
|
+
false
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
return container;
|
|
147
|
+
},
|
|
148
|
+
providers() {
|
|
149
|
+
return Array.from(
|
|
150
|
+
root.providersMap.values()
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
for (const provider of options.providers ?? []) {
|
|
155
|
+
root.registerProvider(
|
|
156
|
+
provider,
|
|
157
|
+
false
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
return container;
|
|
161
|
+
}
|
|
162
|
+
var ScopeImpl = class _ScopeImpl {
|
|
163
|
+
constructor(name, parent) {
|
|
164
|
+
this.name = name;
|
|
165
|
+
this.parent = parent;
|
|
166
|
+
if (parent) {
|
|
167
|
+
this.root = parent.root;
|
|
168
|
+
parent.children.add(this);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
name;
|
|
172
|
+
parent;
|
|
173
|
+
root;
|
|
174
|
+
providersMap = /* @__PURE__ */ new Map();
|
|
175
|
+
overrideProviders = /* @__PURE__ */ new Map();
|
|
176
|
+
singletonCache = /* @__PURE__ */ new Map();
|
|
177
|
+
scopedCache = /* @__PURE__ */ new Map();
|
|
178
|
+
disposals = [];
|
|
179
|
+
children = /* @__PURE__ */ new Set();
|
|
180
|
+
state = "active";
|
|
181
|
+
disposePromise;
|
|
182
|
+
has(token) {
|
|
183
|
+
assertToken(token);
|
|
184
|
+
return this.findProvider(token) !== void 0;
|
|
185
|
+
}
|
|
186
|
+
resolve(token) {
|
|
187
|
+
return this.resolveWithPath(
|
|
188
|
+
token,
|
|
189
|
+
[]
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
async optional(token) {
|
|
193
|
+
if (!this.has(token)) {
|
|
194
|
+
return void 0;
|
|
195
|
+
}
|
|
196
|
+
return this.resolve(token);
|
|
197
|
+
}
|
|
198
|
+
createScope(options = {}) {
|
|
199
|
+
this.assertActive();
|
|
200
|
+
const scope = new _ScopeImpl(
|
|
201
|
+
normalizeOptionalName(
|
|
202
|
+
options.name
|
|
203
|
+
) ?? `${this.name}:scope-${this.children.size + 1}`,
|
|
204
|
+
this
|
|
205
|
+
);
|
|
206
|
+
for (const provider of options.overrides ?? []) {
|
|
207
|
+
scope.registerOverride(
|
|
208
|
+
provider
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
return scope;
|
|
212
|
+
}
|
|
213
|
+
graph() {
|
|
214
|
+
const effective = /* @__PURE__ */ new Map();
|
|
215
|
+
let current = this;
|
|
216
|
+
while (current) {
|
|
217
|
+
for (const [id, provider] of current.overrideProviders) {
|
|
218
|
+
if (!effective.has(id)) {
|
|
219
|
+
effective.set(
|
|
220
|
+
id,
|
|
221
|
+
{
|
|
222
|
+
provider,
|
|
223
|
+
owner: current,
|
|
224
|
+
overridden: true
|
|
225
|
+
}
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
current = current.parent;
|
|
230
|
+
}
|
|
231
|
+
for (const [id, provider] of this.root.providersMap) {
|
|
232
|
+
if (!effective.has(id)) {
|
|
233
|
+
effective.set(
|
|
234
|
+
id,
|
|
235
|
+
{
|
|
236
|
+
provider,
|
|
237
|
+
owner: this.root,
|
|
238
|
+
overridden: false
|
|
239
|
+
}
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return Array.from(
|
|
244
|
+
effective.values(),
|
|
245
|
+
(record) => ({
|
|
246
|
+
token: record.provider.token,
|
|
247
|
+
description: record.provider.token.description,
|
|
248
|
+
lifetime: normalizeLifetime(
|
|
249
|
+
record.provider.lifetime
|
|
250
|
+
),
|
|
251
|
+
dependencies: (record.provider.dependencies ?? []).map(
|
|
252
|
+
(dependency) => dependency.description
|
|
253
|
+
),
|
|
254
|
+
overridden: record.overridden
|
|
255
|
+
})
|
|
256
|
+
).sort(
|
|
257
|
+
(left, right) => left.description.localeCompare(
|
|
258
|
+
right.description
|
|
259
|
+
)
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
dispose() {
|
|
263
|
+
if (this.disposePromise) {
|
|
264
|
+
return this.disposePromise;
|
|
265
|
+
}
|
|
266
|
+
if (this.state === "disposed") {
|
|
267
|
+
return Promise.resolve();
|
|
268
|
+
}
|
|
269
|
+
this.disposePromise = this.disposeInternal();
|
|
270
|
+
return this.disposePromise;
|
|
271
|
+
}
|
|
272
|
+
registerProvider(provider, replace) {
|
|
273
|
+
this.assertActive();
|
|
274
|
+
if (this.parent) {
|
|
275
|
+
throw new Error(
|
|
276
|
+
"BCP Container: providers can only be registered on the root container. Use scope overrides for child scopes."
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
validateProvider(provider);
|
|
280
|
+
const id = provider.token.id;
|
|
281
|
+
if (this.providersMap.has(id) && !replace) {
|
|
282
|
+
throw new Error(
|
|
283
|
+
`BCP Container: service "${provider.token.description}" is already registered.`
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
if (replace && this.hasResolved(id)) {
|
|
287
|
+
throw new Error(
|
|
288
|
+
`BCP Container: service "${provider.token.description}" cannot be replaced after it has been resolved.`
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
this.providersMap.set(
|
|
292
|
+
id,
|
|
293
|
+
provider
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
registerOverride(provider) {
|
|
297
|
+
validateProvider(provider);
|
|
298
|
+
const id = provider.token.id;
|
|
299
|
+
if (this.overrideProviders.has(id)) {
|
|
300
|
+
throw new Error(
|
|
301
|
+
`BCP Container: scope override for "${provider.token.description}" is already registered.`
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
this.overrideProviders.set(
|
|
305
|
+
id,
|
|
306
|
+
provider
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
async resolveWithPath(token, path) {
|
|
310
|
+
this.assertActive();
|
|
311
|
+
assertToken(token);
|
|
312
|
+
if (path.some(
|
|
313
|
+
(item) => item.id === token.id
|
|
314
|
+
)) {
|
|
315
|
+
throw new ServiceResolutionError(
|
|
316
|
+
token,
|
|
317
|
+
`Circular dependency detected: ${[
|
|
318
|
+
...path,
|
|
319
|
+
token
|
|
320
|
+
].map(
|
|
321
|
+
(item) => item.description
|
|
322
|
+
).join(" -> ")}.`
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
const record = this.findProvider(token);
|
|
326
|
+
if (!record) {
|
|
327
|
+
throw new ServiceNotFoundError(
|
|
328
|
+
token
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
const lifetime = normalizeLifetime(
|
|
332
|
+
record.provider.lifetime
|
|
333
|
+
);
|
|
334
|
+
const cache = lifetime === "singleton" ? record.owner.singletonCache : lifetime === "scoped" ? this.scopedCache : void 0;
|
|
335
|
+
const existing = cache?.get(token.id);
|
|
336
|
+
if (existing) {
|
|
337
|
+
return existing;
|
|
338
|
+
}
|
|
339
|
+
const resolution = this.instantiate(
|
|
340
|
+
record.provider,
|
|
341
|
+
[
|
|
342
|
+
...path,
|
|
343
|
+
token
|
|
344
|
+
],
|
|
345
|
+
lifetime,
|
|
346
|
+
record.owner
|
|
347
|
+
);
|
|
348
|
+
cache?.set(
|
|
349
|
+
token.id,
|
|
350
|
+
resolution
|
|
351
|
+
);
|
|
352
|
+
try {
|
|
353
|
+
return await resolution;
|
|
354
|
+
} catch (error) {
|
|
355
|
+
cache?.delete(token.id);
|
|
356
|
+
if (error instanceof ServiceNotFoundError || error instanceof ServiceResolutionError) {
|
|
357
|
+
throw error;
|
|
358
|
+
}
|
|
359
|
+
throw new ServiceResolutionError(
|
|
360
|
+
token,
|
|
361
|
+
error instanceof Error ? error.message : String(error),
|
|
362
|
+
error
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
async instantiate(provider, path, lifetime, providerOwner) {
|
|
367
|
+
const dependencies = await Promise.all(
|
|
368
|
+
(provider.dependencies ?? []).map(
|
|
369
|
+
(dependency) => this.resolveWithPath(
|
|
370
|
+
dependency,
|
|
371
|
+
path
|
|
372
|
+
)
|
|
373
|
+
)
|
|
374
|
+
);
|
|
375
|
+
const context = {
|
|
376
|
+
scope: this,
|
|
377
|
+
resolve: (dependency) => this.resolveWithPath(
|
|
378
|
+
dependency,
|
|
379
|
+
path
|
|
380
|
+
),
|
|
381
|
+
optional: async (dependency) => {
|
|
382
|
+
if (!this.has(dependency)) {
|
|
383
|
+
return void 0;
|
|
384
|
+
}
|
|
385
|
+
return this.resolveWithPath(
|
|
386
|
+
dependency,
|
|
387
|
+
path
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
const value = await provider.factory(
|
|
392
|
+
context,
|
|
393
|
+
dependencies
|
|
394
|
+
);
|
|
395
|
+
if (provider.dispose) {
|
|
396
|
+
const disposalOwner = lifetime === "singleton" ? providerOwner : this;
|
|
397
|
+
disposalOwner.disposals.push({
|
|
398
|
+
provider,
|
|
399
|
+
value
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
return value;
|
|
403
|
+
}
|
|
404
|
+
findProvider(token) {
|
|
405
|
+
let current = this;
|
|
406
|
+
while (current) {
|
|
407
|
+
const override = current.overrideProviders.get(
|
|
408
|
+
token.id
|
|
409
|
+
);
|
|
410
|
+
if (override) {
|
|
411
|
+
return {
|
|
412
|
+
provider: override,
|
|
413
|
+
owner: current,
|
|
414
|
+
overridden: true
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
current = current.parent;
|
|
418
|
+
}
|
|
419
|
+
const provider = this.root.providersMap.get(
|
|
420
|
+
token.id
|
|
421
|
+
);
|
|
422
|
+
if (!provider) {
|
|
423
|
+
return void 0;
|
|
424
|
+
}
|
|
425
|
+
return {
|
|
426
|
+
provider,
|
|
427
|
+
owner: this.root,
|
|
428
|
+
overridden: false
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
async disposeInternal() {
|
|
432
|
+
this.state = "disposing";
|
|
433
|
+
const errors = [];
|
|
434
|
+
for (const child of Array.from(
|
|
435
|
+
this.children
|
|
436
|
+
).reverse()) {
|
|
437
|
+
try {
|
|
438
|
+
await child.dispose();
|
|
439
|
+
} catch (error) {
|
|
440
|
+
errors.push(error);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
for (const record of [...this.disposals].reverse()) {
|
|
444
|
+
if (!record.provider.dispose) {
|
|
445
|
+
continue;
|
|
446
|
+
}
|
|
447
|
+
try {
|
|
448
|
+
await record.provider.dispose(
|
|
449
|
+
record.value
|
|
450
|
+
);
|
|
451
|
+
} catch (error) {
|
|
452
|
+
errors.push(error);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
this.disposals.length = 0;
|
|
456
|
+
this.singletonCache.clear();
|
|
457
|
+
this.scopedCache.clear();
|
|
458
|
+
this.children.clear();
|
|
459
|
+
this.parent?.children.delete(this);
|
|
460
|
+
this.state = "disposed";
|
|
461
|
+
if (errors.length > 0) {
|
|
462
|
+
throw new ServiceDisposalError(
|
|
463
|
+
errors
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
hasResolved(id) {
|
|
468
|
+
if (this.singletonCache.has(id) || this.scopedCache.has(id)) {
|
|
469
|
+
return true;
|
|
470
|
+
}
|
|
471
|
+
for (const child of this.children) {
|
|
472
|
+
if (child.hasResolved(id)) {
|
|
473
|
+
return true;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
return false;
|
|
477
|
+
}
|
|
478
|
+
assertActive() {
|
|
479
|
+
if (this.state !== "active") {
|
|
480
|
+
throw new Error(
|
|
481
|
+
`BCP Container: scope "${this.name}" is ${this.state}.`
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
};
|
|
486
|
+
function validateProvider(provider) {
|
|
487
|
+
if (!provider || typeof provider !== "object") {
|
|
488
|
+
throw new TypeError(
|
|
489
|
+
"BCP Container: provider must be an object."
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
assertToken(provider.token);
|
|
493
|
+
if (typeof provider.factory !== "function") {
|
|
494
|
+
throw new TypeError(
|
|
495
|
+
`BCP Container: provider "${provider.token.description}" must define factory().`
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
normalizeLifetime(
|
|
499
|
+
provider.lifetime
|
|
500
|
+
);
|
|
501
|
+
assertDependencies(
|
|
502
|
+
provider.dependencies ?? []
|
|
503
|
+
);
|
|
504
|
+
if (provider.dispose !== void 0 && typeof provider.dispose !== "function") {
|
|
505
|
+
throw new TypeError(
|
|
506
|
+
`BCP Container: provider "${provider.token.description}" dispose must be a function.`
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
function assertToken(token) {
|
|
511
|
+
if (!token || typeof token !== "object" || typeof token.id !== "symbol" || typeof token.description !== "string" || token.description.trim() === "") {
|
|
512
|
+
throw new TypeError(
|
|
513
|
+
"BCP Container: invalid service token. Use createServiceToken()."
|
|
514
|
+
);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
function assertDependencies(dependencies) {
|
|
518
|
+
if (!Array.isArray(dependencies)) {
|
|
519
|
+
throw new TypeError(
|
|
520
|
+
"BCP Container: provider dependencies must be an array."
|
|
521
|
+
);
|
|
522
|
+
}
|
|
523
|
+
for (const dependency of dependencies) {
|
|
524
|
+
assertToken(dependency);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
function normalizeLifetime(lifetime) {
|
|
528
|
+
const normalized = lifetime ?? "singleton";
|
|
529
|
+
if (normalized !== "singleton" && normalized !== "scoped" && normalized !== "transient") {
|
|
530
|
+
throw new TypeError(
|
|
531
|
+
"BCP Container: service lifetime must be singleton, scoped or transient."
|
|
532
|
+
);
|
|
533
|
+
}
|
|
534
|
+
return normalized;
|
|
535
|
+
}
|
|
536
|
+
function normalizeName(value, label) {
|
|
537
|
+
if (typeof value !== "string") {
|
|
538
|
+
throw new TypeError(
|
|
539
|
+
`BCP Container: ${label} must be a string.`
|
|
540
|
+
);
|
|
541
|
+
}
|
|
542
|
+
const normalized = value.trim();
|
|
543
|
+
if (!normalized) {
|
|
544
|
+
throw new TypeError(
|
|
545
|
+
`BCP Container: ${label} cannot be empty.`
|
|
546
|
+
);
|
|
547
|
+
}
|
|
548
|
+
if (normalized.length > 256 || /[\r\n]/.test(normalized)) {
|
|
549
|
+
throw new TypeError(
|
|
550
|
+
`BCP Container: ${label} must be at most 256 characters without line breaks.`
|
|
551
|
+
);
|
|
552
|
+
}
|
|
553
|
+
return normalized;
|
|
554
|
+
}
|
|
555
|
+
function normalizeOptionalName(value) {
|
|
556
|
+
if (value === void 0) {
|
|
557
|
+
return void 0;
|
|
558
|
+
}
|
|
559
|
+
return normalizeName(
|
|
560
|
+
value,
|
|
561
|
+
"scope name"
|
|
562
|
+
);
|
|
563
|
+
}
|
|
564
|
+
export {
|
|
565
|
+
ServiceDisposalError,
|
|
566
|
+
ServiceNotFoundError,
|
|
567
|
+
ServiceResolutionError,
|
|
568
|
+
createServiceContainer,
|
|
569
|
+
createServiceToken,
|
|
570
|
+
provideClass,
|
|
571
|
+
provideFactory,
|
|
572
|
+
provideValue
|
|
573
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export {
|
|
2
|
+
createServiceContainer,
|
|
3
|
+
createServiceToken,
|
|
4
|
+
provideClass,
|
|
5
|
+
provideFactory,
|
|
6
|
+
provideValue,
|
|
7
|
+
ServiceDisposalError,
|
|
8
|
+
ServiceNotFoundError,
|
|
9
|
+
ServiceResolutionError,
|
|
10
|
+
|
|
11
|
+
type ServiceContainer,
|
|
12
|
+
type ServiceContainerOptions,
|
|
13
|
+
type ServiceDependencyValues,
|
|
14
|
+
type ServiceFactoryContext,
|
|
15
|
+
type ServiceGraphNode,
|
|
16
|
+
type ServiceLifetime,
|
|
17
|
+
type ServiceProvider,
|
|
18
|
+
type ServiceProviderOptions,
|
|
19
|
+
type ServiceScope,
|
|
20
|
+
type ServiceScopeOptions,
|
|
21
|
+
type ServiceScopeState,
|
|
22
|
+
type ServiceToken,
|
|
23
|
+
type ServiceTokenValue,
|
|
24
|
+
} from "../../server/src/container.js";
|