@tollwyn/baukasten 1.3.4 → 2.0.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/README.md +73 -12
- package/dist/check.js +16 -7
- package/dist/server/core.d.ts +3 -2
- package/dist/server/core.js +20 -11
- package/dist/server/hook.d.ts +5 -3
- package/dist/server/pages.js +2 -1
- package/dist/server/start.js +0 -6
- package/dist/shopify/hook.d.ts +2 -2
- package/dist/stubs.js +10 -12
- package/dist/testing/stripe.js +1 -1
- package/dist/variables.d.ts +1 -4
- package/dist/variables.js +1 -4
- package/package.json +6 -9
package/README.md
CHANGED
|
@@ -7,11 +7,11 @@ A product builds its core and nothing of this.
|
|
|
7
7
|
|
|
8
8
|
## Set up a product
|
|
9
9
|
|
|
10
|
-
A product is a SvelteKit
|
|
10
|
+
A product is a SvelteKit 3 app with `@sveltejs/adapter-node` 6 and Svelte 5, tested with Playwright.
|
|
11
11
|
|
|
12
12
|
```sh
|
|
13
13
|
npm install --save-exact @tollwyn/baukasten@<version>
|
|
14
|
-
npm install --save-dev @sveltejs/adapter-node@
|
|
14
|
+
npm install --save-dev @sveltejs/adapter-node@6 @playwright/test smtp-server
|
|
15
15
|
npx --no-install baukasten-stubs
|
|
16
16
|
# fill in what the product owns (below)
|
|
17
17
|
npx --no-install baukasten-check
|
|
@@ -42,9 +42,17 @@ them: `baukasten.config.ts`, `src/app.css`, `src/lib/server/baukasten.ts` and
|
|
|
42
42
|
- `src/lib/server/handle.ts`: its own handle, after the baukasten's.
|
|
43
43
|
- Its own pages. Their links to other pages go through `useLink` of `/ui`, else the referral tag
|
|
44
44
|
`?via=` is lost on the way to the sign-up.
|
|
45
|
+
- `package.json`, whose `imports` map `"#lib/*"` to `"./src/lib/*"`, as `npx sv create` sets it
|
|
46
|
+
up: the stubs import `src/lib/server/` through it.
|
|
45
47
|
- `vite.config.ts`, passing the options of the baukasten to SvelteKit:
|
|
46
48
|
`sveltekit({ ...SVELTEKIT_OPTIONS, adapter: adapter() })`, with `SVELTEKIT_OPTIONS` from
|
|
47
|
-
`@tollwyn/baukasten`. No page is prerendered.
|
|
49
|
+
`@tollwyn/baukasten`. No page is prerendered, and there is no `paths.origin`, which would build
|
|
50
|
+
one origin into the image.
|
|
51
|
+
- Its addresses, from `PUBLIC_ORIGIN` (`config.publicOrigin` of `kit.context()`), never from
|
|
52
|
+
`event.url`: adapter-node takes the origin of a request from its `host` header, with https, and
|
|
53
|
+
only `PUBLIC_ORIGIN` is the product's own.
|
|
54
|
+
- The redirect to Checkout: the address `kit.billing.checkout` gives is Stripe's, so the product
|
|
55
|
+
passes `{ external: true }` to `redirect`.
|
|
48
56
|
- `migrations/`: its tables in the schema `public`, plain SQL, forward-only and expanding (the
|
|
49
57
|
previous version must run against the new schema). Every table that holds data of an account
|
|
50
58
|
points at it with `REFERENCES baukasten.accounts (id) ON DELETE CASCADE`. It reads the tables of
|
|
@@ -94,11 +102,11 @@ it. `muster/` shows all of it with Tailwind CSS 4, Skeleton and a font from font
|
|
|
94
102
|
|
|
95
103
|
`baukasten-check` runs in the root of the product, before its gate, against the installed version:
|
|
96
104
|
the stubs are there and unchanged, `deploy/auslieferung.json` names the webhook and the rights of
|
|
97
|
-
the baukasten, SvelteKit and Svelte fit its peer ranges and adapter-node is version
|
|
98
|
-
in `package.json` replaces nothing the baukasten depends on
|
|
99
|
-
schema `baukasten` beyond its references to
|
|
100
|
-
`SVELTEKIT_OPTIONS` are in place. Exit 0 when the
|
|
101
|
-
problem.
|
|
105
|
+
the baukasten, SvelteKit and Svelte fit its peer ranges and adapter-node is version 6, `overrides`
|
|
106
|
+
in `package.json` replaces nothing the baukasten depends on and its `imports` map `#lib/*`, no
|
|
107
|
+
migration of the product names the schema `baukasten` beyond its references to
|
|
108
|
+
`baukasten.accounts`, and the configuration and `SVELTEKIT_OPTIONS` are in place. Exit 0 when the
|
|
109
|
+
product fits; else exit 1 with one line per problem.
|
|
102
110
|
|
|
103
111
|
`e2e/baukasten.spec.ts` runs the connection test in the gate of the product, against the built
|
|
104
112
|
product with the doubles of Stripe and mail: sign-up with a referral tag, mail and confirmation,
|
|
@@ -111,8 +119,8 @@ with `npx playwright test -g "the connection of the baukasten"`.
|
|
|
111
119
|
|
|
112
120
|
A Shopify app built on this kit is a public app in the Shopify App Store, embedded in the admin of
|
|
113
121
|
each store that installs it. Shopify installs it (managed installation) and bills it (Shopify App
|
|
114
|
-
Pricing); the merchant never signs up or pays anywhere else. It is a SvelteKit
|
|
115
|
-
`@sveltejs/adapter-node`
|
|
122
|
+
Pricing); the merchant never signs up or pays anywhere else. It is a SvelteKit 3 app with
|
|
123
|
+
`@sveltejs/adapter-node` 6 and Svelte 5, tested with Playwright, like a web app, and on the same
|
|
116
124
|
server; the accounts, Stripe and the legal pages of a web app are not part of it.
|
|
117
125
|
|
|
118
126
|
What the baukasten brings for it: the installation with the token exchange and expiring offline
|
|
@@ -129,7 +137,7 @@ connection test among them.
|
|
|
129
137
|
|
|
130
138
|
```sh
|
|
131
139
|
npm install --save-exact @tollwyn/baukasten@<version>
|
|
132
|
-
npm install --save-dev @sveltejs/adapter-node@
|
|
140
|
+
npm install --save-dev @sveltejs/adapter-node@6 @playwright/test smtp-server
|
|
133
141
|
npx --no-install baukasten-stubs shopify
|
|
134
142
|
# fill in what the app owns (below)
|
|
135
143
|
npx --no-install baukasten-check
|
|
@@ -183,7 +191,8 @@ missing, it writes the files the app owns as a starting point: `baukasten.config
|
|
|
183
191
|
- Runs: `periodic` with the work mark, as in a web app; a run asks the Admin API of a store with
|
|
184
192
|
`kit.admin(domain)` and skips a store that is gone.
|
|
185
193
|
- `vite.config.ts`: `sveltekit({ ...SHOPIFY_SVELTEKIT_OPTIONS, adapter: adapter() })`, with
|
|
186
|
-
`SHOPIFY_SVELTEKIT_OPTIONS` from `@tollwyn/baukasten`. No page is prerendered.
|
|
194
|
+
`SHOPIFY_SVELTEKIT_OPTIONS` from `@tollwyn/baukasten`. No page is prerendered. The `imports` of
|
|
195
|
+
`package.json` and the addresses from `PUBLIC_ORIGIN` as in a web app.
|
|
187
196
|
- `migrations/`: its tables in the schema `public`, forward-only and expanding. Every table that
|
|
188
197
|
holds data of a store points at it with `REFERENCES baukasten.shops (domain) ON DELETE CASCADE`:
|
|
189
198
|
so `shop/redact` deletes them with the store.
|
|
@@ -254,3 +263,55 @@ the baukasten do:
|
|
|
254
263
|
- Loss and incidents: on a breach the operator stops the app through the delivery service, finds what
|
|
255
264
|
was reached from the logs, and tells the stores concerned by email without undue delay, as the
|
|
256
265
|
privacy text promises.
|
|
266
|
+
|
|
267
|
+
# From 1.x to 2.0
|
|
268
|
+
|
|
269
|
+
2.0 moves the baukasten to SvelteKit 3 and adapter-node 6, and to version 23 of the SDK of Stripe.
|
|
270
|
+
Its pages, mails, legal texts, variables and migrations stay as they were: a product needs no new
|
|
271
|
+
variable, and its database stays as it is. A product on 1.x keeps running as it is; it takes 2.0 in
|
|
272
|
+
one change, a web app and a Shopify app alike:
|
|
273
|
+
|
|
274
|
+
1. `npm install --save-exact @tollwyn/baukasten@<version>`, a version from 2.0.0 on, and
|
|
275
|
+
`npm install --save-dev @sveltejs/kit@3 @sveltejs/adapter-node@6`, with what SvelteKit 3 needs:
|
|
276
|
+
Vite 8, `@sveltejs/vite-plugin-svelte` 7, TypeScript 6 and Svelte from 5.57.1 on.
|
|
277
|
+
2. The product's own code after the guide of SvelteKit,
|
|
278
|
+
https://svelte.dev/docs/kit/migrating-to-sveltekit-3 (`npx sv migrate sveltekit-3` does much of
|
|
279
|
+
it). What a product of the baukasten meets there:
|
|
280
|
+
- `$lib` becomes `#lib`, imported with the extension of the module (`#lib/texts.js`), and
|
|
281
|
+
`package.json` maps `"#lib/*": "./src/lib/*"` in `imports`.
|
|
282
|
+
- `tsconfig.json` extends `$app/tsconfig` and names its own `include`; a `types` of its own names
|
|
283
|
+
`$app/types` as well.
|
|
284
|
+
- `$app/environment` becomes `$app/env`, and `$app/stores` is gone (`$app/state`).
|
|
285
|
+
- The types of the hooks, `Handle` among them, come from `@sveltejs/kit/hooks`.
|
|
286
|
+
- `redirect` to another origin takes `{ external: true }`: the redirect to the address of
|
|
287
|
+
`kit.billing.checkout` too.
|
|
288
|
+
- `error(status, message)` takes the message as a string, further fields as a third argument.
|
|
289
|
+
3. `npx --no-install baukasten-stubs` writes the stubs of 2.0, `npx --no-install baukasten-stubs
|
|
290
|
+
shopify` those of a Shopify app. The product's own `src/lib/server/handle.ts` takes `Handle`
|
|
291
|
+
from `@sveltejs/kit/hooks`.
|
|
292
|
+
4. An override of `cookie` goes, where the product has one: SvelteKit 3 brings `cookie` 2, which
|
|
293
|
+
GHSA-pxg6-pf52-xh8x does not reach.
|
|
294
|
+
5. `npx --no-install baukasten-check`, then the gate of the product.
|
|
295
|
+
|
|
296
|
+
What changes when it runs:
|
|
297
|
+
|
|
298
|
+
- adapter-node 6 reads no `ORIGIN`, and the server of the baukasten sets none: adapter-node takes
|
|
299
|
+
the origin of a request from its `host` header, with https. `PUBLIC_ORIGIN` stays the origin of
|
|
300
|
+
every address the baukasten makes and the one its check of unsafe requests compares with; the
|
|
301
|
+
product makes its own addresses from it, not from `event.url`, which says https on a local server
|
|
302
|
+
over http too.
|
|
303
|
+
- The `handleError` of the baukasten gets every error now, those of `error()` too: it leaves them as
|
|
304
|
+
they are, and logs the others as before.
|
|
305
|
+
- An enhanced form answers with the status of `fail()`, and one that posts to another page goes
|
|
306
|
+
there, as without JavaScript.
|
|
307
|
+
- adapter-node 6 bundles the baukasten into `build/`, as a library of Svelte, and its dependencies
|
|
308
|
+
with it. The image still carries the production `node_modules`: `server.js` and the migration
|
|
309
|
+
load the baukasten from there.
|
|
310
|
+
- adapter-node 6 serves the files of the build only, and only to `GET` and `HEAD`.
|
|
311
|
+
- Stripe answers the baukasten in its API version `2026-09-30.endive`; the payload of a webhook
|
|
312
|
+
keeps the version of its endpoint, as before.
|
|
313
|
+
|
|
314
|
+
What changes in the package: `@sveltejs/kit` is a peer from 3.1.0 on, and `baukasten-check` wants
|
|
315
|
+
adapter-node 6 and the `imports` of `#lib`. `init`, `handle` and `handleError` of `Kit` and
|
|
316
|
+
`ShopifyKit` take the types of SvelteKit 3. `SVELTEKIT_OPTIONS` and `SHOPIFY_SVELTEKIT_OPTIONS` hold
|
|
317
|
+
the same options as before, typed against `Config` of `@sveltejs/kit/vite`.
|
package/dist/check.js
CHANGED
|
@@ -34,14 +34,19 @@ const SHOPIFY_ANGABE = z.looseObject({
|
|
|
34
34
|
/** Words the review of the App Store refuses in an address of an app. */
|
|
35
35
|
const REFUSED_IN_ADDRESS = ['shopify', 'example'];
|
|
36
36
|
const ART = z.looseObject({ art: z.literal('shopify') });
|
|
37
|
-
const PACKAGE = z.looseObject({
|
|
37
|
+
const PACKAGE = z.looseObject({
|
|
38
|
+
overrides: z.record(z.string(), z.unknown()).optional(),
|
|
39
|
+
imports: z.record(z.string(), z.unknown()).optional()
|
|
40
|
+
});
|
|
41
|
+
/** The alias the stubs import the product's src/lib by, as SvelteKit sets it up. */
|
|
42
|
+
const LIB_IMPORT = { key: '#lib/*', target: './src/lib/*' };
|
|
38
43
|
const PEER = z.looseObject({ version: z.string() });
|
|
39
44
|
/**
|
|
40
|
-
* What the product builds with, checked like a peer: adapter-node
|
|
41
|
-
*
|
|
42
|
-
* npm keeps a peer of a dependency in the image.
|
|
45
|
+
* What the product builds with, checked like a peer: adapter-node 5 cannot build SvelteKit 3, and the
|
|
46
|
+
* handler the stub server.js wraps, with its event at shutdown, is that of one major. It is no peer,
|
|
47
|
+
* since only the build needs it, and npm keeps a peer of a dependency in the image.
|
|
43
48
|
*/
|
|
44
|
-
const BUILT_WITH = { '@sveltejs/adapter-node': '^
|
|
49
|
+
const BUILT_WITH = { '@sveltejs/adapter-node': '^6.0.0' };
|
|
45
50
|
/**
|
|
46
51
|
* A reference to an account of a web app or a shop of a Shopify app: the one way a migration of the
|
|
47
52
|
* product names the schema baukasten.
|
|
@@ -212,7 +217,7 @@ function packageProblems(files, baukasten) {
|
|
|
212
217
|
const parsed = json(text);
|
|
213
218
|
const manifest = parsed.kind === 'json' ? PACKAGE.safeParse(parsed.value) : null;
|
|
214
219
|
if (manifest === null || !manifest.success) {
|
|
215
|
-
return ['package.json is no JSON object, or its overrides are no object'];
|
|
220
|
+
return ['package.json is no JSON object, or its overrides or imports are no object'];
|
|
216
221
|
}
|
|
217
222
|
const own = new Set([
|
|
218
223
|
baukasten.name,
|
|
@@ -220,7 +225,11 @@ function packageProblems(files, baukasten) {
|
|
|
220
225
|
...Object.keys(baukasten.peerDependencies)
|
|
221
226
|
]);
|
|
222
227
|
const names = [...new Set(overridden(manifest.data.overrides))].filter((name) => own.has(name));
|
|
223
|
-
|
|
228
|
+
const problems = names.map((name) => `package.json overrides ${name}, which the baukasten brings itself; remove it`);
|
|
229
|
+
if (manifest.data.imports?.[LIB_IMPORT.key] !== LIB_IMPORT.target) {
|
|
230
|
+
problems.push(`package.json does not map imports "${LIB_IMPORT.key}" to "${LIB_IMPORT.target}", which the stubs import from`);
|
|
231
|
+
}
|
|
232
|
+
return problems;
|
|
224
233
|
}
|
|
225
234
|
function migrationProblems(files, art) {
|
|
226
235
|
// Like the migration: every entry read, a folder failing loudly, then the .sql files.
|
package/dist/server/core.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RequestEvent } from '@sveltejs/kit';
|
|
2
|
+
import type { Handle, HandleServerError, ServerInit } from '@sveltejs/kit/hooks';
|
|
2
3
|
import type { Language } from '../product.js';
|
|
3
4
|
import { type Art } from './adapter/migrate.js';
|
|
4
5
|
import { type Mail } from './config.js';
|
|
@@ -68,7 +69,7 @@ export interface CoreSpec<C extends CoreConfig, S> {
|
|
|
68
69
|
export interface Core<C, S> {
|
|
69
70
|
/**
|
|
70
71
|
* The `init` of the hooks. SvelteKit runs it in `vite build` too, to prerender pages, with
|
|
71
|
-
* `building` of `$app/
|
|
72
|
+
* `building` of `$app/env` set: then it reads nothing and opens nothing, since the image is
|
|
72
73
|
* built without a single variable.
|
|
73
74
|
*/
|
|
74
75
|
init: (building: boolean) => ServerInit;
|
package/dist/server/core.js
CHANGED
|
@@ -152,17 +152,26 @@ export function serverCore(spec) {
|
|
|
152
152
|
});
|
|
153
153
|
}
|
|
154
154
|
};
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
(
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
155
|
+
// SvelteKit passes every error here; what a page shows of it stays SvelteKit's: the message of
|
|
156
|
+
// error(), its own safe message, or "Internal Error".
|
|
157
|
+
const handleError = (caught) => {
|
|
158
|
+
const request = { method: caught.event.request.method, path: caught.event.url.pathname };
|
|
159
|
+
switch (caught.kind) {
|
|
160
|
+
// The product raised it with error(), and its page says it.
|
|
161
|
+
case 'app':
|
|
162
|
+
return;
|
|
163
|
+
case 'framework':
|
|
164
|
+
case 'validation': {
|
|
165
|
+
const { status } = caught.error;
|
|
166
|
+
// An unknown path is already in the request log.
|
|
167
|
+
if (status !== 404)
|
|
168
|
+
log.warn('request failed', { ...request, status, error: caught.error });
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
case 'unknown':
|
|
172
|
+
log.error('request failed', { ...request, status: 500, error: caught.error });
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
166
175
|
};
|
|
167
176
|
return { init, handle, handleError, running };
|
|
168
177
|
}
|
package/dist/server/hook.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RequestEvent } from '@sveltejs/kit';
|
|
2
|
+
import type { Handle, HandleServerError, ServerInit } from '@sveltejs/kit/hooks';
|
|
2
3
|
import type { z } from 'zod';
|
|
3
4
|
import type { Product, ProductEnv } from '../product.js';
|
|
4
5
|
import { type Account } from './accounts.js';
|
|
@@ -55,7 +56,7 @@ export interface Hooks<E extends ProductEnv = ProductEnv> {
|
|
|
55
56
|
export interface Kit<E extends ProductEnv = ProductEnv> {
|
|
56
57
|
/**
|
|
57
58
|
* The `init` of the hooks. SvelteKit runs it in `vite build` too, to prerender pages, with
|
|
58
|
-
* `building` of `$app/
|
|
59
|
+
* `building` of `$app/env` set: then it reads nothing and opens nothing, since the image is
|
|
59
60
|
* built without a single variable.
|
|
60
61
|
*/
|
|
61
62
|
init(building: boolean): ServerInit;
|
|
@@ -85,7 +86,8 @@ export interface Kit<E extends ProductEnv = ProductEnv> {
|
|
|
85
86
|
billing: {
|
|
86
87
|
/**
|
|
87
88
|
* A Checkout page for a price of the catalog, by its lookup key: a subscription, or a purchase.
|
|
88
|
-
* An account with a running subscription gets none; the customer portal changes it.
|
|
89
|
+
* An account with a running subscription gets none; the customer portal changes it. Its
|
|
90
|
+
* address is Stripe's: `redirect` takes it with `{ external: true }`.
|
|
89
91
|
*/
|
|
90
92
|
checkout(account: Account, order: Order): Promise<CheckoutPage>;
|
|
91
93
|
/** The customer portal of the account, which leads back to the path `back`. */
|
package/dist/server/pages.js
CHANGED
|
@@ -471,7 +471,8 @@ export function createPages(services) {
|
|
|
471
471
|
const account = requireAccount(event);
|
|
472
472
|
if (!(await s.billing.hasCustomer(account.id)))
|
|
473
473
|
redirect(303, '/account');
|
|
474
|
-
|
|
474
|
+
// The address of the portal comes from Stripe.
|
|
475
|
+
redirect(303, await s.billing.portal(account, '/account'), { external: true });
|
|
475
476
|
},
|
|
476
477
|
delete: async (event) => {
|
|
477
478
|
const s = services();
|
package/dist/server/start.js
CHANGED
|
@@ -23,12 +23,6 @@ export async function serve(load, headers) {
|
|
|
23
23
|
log.error('unhandled rejection', { error });
|
|
24
24
|
void exitAfterLog(1);
|
|
25
25
|
});
|
|
26
|
-
// adapter-node reads ORIGIN while it loads. An invalid PUBLIC_ORIGIN stays for the configuration,
|
|
27
|
-
// which names it with every other problem in one line.
|
|
28
|
-
const publicOrigin = process.env.PUBLIC_ORIGIN?.trim();
|
|
29
|
-
if (publicOrigin !== undefined && URL.canParse(publicOrigin)) {
|
|
30
|
-
process.env.ORIGIN = new URL(publicOrigin).origin;
|
|
31
|
-
}
|
|
32
26
|
let handler;
|
|
33
27
|
try {
|
|
34
28
|
// Loading runs `init`, which reads the configuration and starts the product.
|
package/dist/shopify/hook.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Handle, HandleServerError, ServerInit } from '@sveltejs/kit';
|
|
1
|
+
import type { Handle, HandleServerError, ServerInit } from '@sveltejs/kit/hooks';
|
|
2
2
|
import type { ProductEnv } from '../product.js';
|
|
3
3
|
import type { Limits } from '../server/limits.js';
|
|
4
4
|
import type { Log } from '../server/log.js';
|
|
@@ -40,7 +40,7 @@ export interface ShopifyHooks<E extends ProductEnv = ProductEnv> extends Webhook
|
|
|
40
40
|
export interface ShopifyKit<E extends ProductEnv = ProductEnv> {
|
|
41
41
|
/**
|
|
42
42
|
* The `init` of the hooks. SvelteKit runs it in `vite build` too, with `building` of
|
|
43
|
-
* `$app/
|
|
43
|
+
* `$app/env` set: then it reads nothing and opens nothing.
|
|
44
44
|
*/
|
|
45
45
|
init(building: boolean): ServerInit;
|
|
46
46
|
handle: Handle;
|
package/dist/stubs.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { APP_BRIDGE_URL, COMPLIANCE_TOPICS, POLARIS_URL, SHOPIFY_API_VERSION, SHOPIFY_AUTH_PATH, SHOPIFY_WEBHOOK_PATH } from './shopify/constants.js';
|
|
2
|
-
/** The alias of src/lib in the product: written out in an import here, svelte-package would resolve it. */
|
|
3
|
-
const LIB = '$lib';
|
|
4
2
|
const PAGES = [
|
|
5
3
|
{
|
|
6
4
|
route: 'account',
|
|
@@ -63,7 +61,7 @@ const PAGES = [
|
|
|
63
61
|
}
|
|
64
62
|
];
|
|
65
63
|
function serverPart(page) {
|
|
66
|
-
return `import { kit } from '
|
|
64
|
+
return `import { kit } from '#lib/server/baukasten.js';
|
|
67
65
|
|
|
68
66
|
export const { ${page.server.join(', ')} } = kit.pages.${page.pages};
|
|
69
67
|
`;
|
|
@@ -98,16 +96,16 @@ await start(() => import('./build/handler.js'));
|
|
|
98
96
|
</html>
|
|
99
97
|
`,
|
|
100
98
|
'src/hooks.server.ts': `// The hooks of a product: the baukasten first, then the product's own handle.
|
|
101
|
-
import { building } from '$app/
|
|
99
|
+
import { building } from '$app/env';
|
|
102
100
|
import { sequence } from '@sveltejs/kit/hooks';
|
|
103
|
-
import { kit } from '
|
|
104
|
-
import { handle as own } from '
|
|
101
|
+
import { kit } from '#lib/server/baukasten.js';
|
|
102
|
+
import { handle as own } from '#lib/server/handle.js';
|
|
105
103
|
|
|
106
104
|
export const init = kit.init(building);
|
|
107
105
|
export const handle = sequence(kit.handle, own);
|
|
108
106
|
export const handleError = kit.handleError;
|
|
109
107
|
`,
|
|
110
|
-
'src/routes/+layout.server.ts': `import { kit } from '
|
|
108
|
+
'src/routes/+layout.server.ts': `import { kit } from '#lib/server/baukasten.js';
|
|
111
109
|
|
|
112
110
|
export const { load } = kit.pages.layout;
|
|
113
111
|
`,
|
|
@@ -179,7 +177,7 @@ import product from '../../../baukasten.config';
|
|
|
179
177
|
export const kit = baukasten(product);
|
|
180
178
|
`,
|
|
181
179
|
'src/lib/server/handle.ts': `// The product's own handle, after that of the baukasten (src/hooks.server.ts).
|
|
182
|
-
import type { Handle } from '@sveltejs/kit';
|
|
180
|
+
import type { Handle } from '@sveltejs/kit/hooks';
|
|
183
181
|
|
|
184
182
|
export const handle: Handle = ({ event, resolve }) => resolve(event);
|
|
185
183
|
`
|
|
@@ -208,10 +206,10 @@ await start(() => import('./build/handler.js'));
|
|
|
208
206
|
</html>
|
|
209
207
|
`,
|
|
210
208
|
'src/hooks.server.ts': `// The hooks of a Shopify app: the baukasten first, then the app's own handle.
|
|
211
|
-
import { building } from '$app/
|
|
209
|
+
import { building } from '$app/env';
|
|
212
210
|
import { sequence } from '@sveltejs/kit/hooks';
|
|
213
|
-
import { kit } from '
|
|
214
|
-
import { handle as own } from '
|
|
211
|
+
import { kit } from '#lib/server/baukasten.js';
|
|
212
|
+
import { handle as own } from '#lib/server/handle.js';
|
|
215
213
|
|
|
216
214
|
export const init = kit.init(building);
|
|
217
215
|
export const handle = sequence(kit.handle, own);
|
|
@@ -280,7 +278,7 @@ import app from '../../../baukasten.config';
|
|
|
280
278
|
export const kit = shopifyBaukasten(app);
|
|
281
279
|
`,
|
|
282
280
|
'src/lib/server/handle.ts': `// The app's own handle, after that of the baukasten (src/hooks.server.ts).
|
|
283
|
-
import type { Handle } from '@sveltejs/kit';
|
|
281
|
+
import type { Handle } from '@sveltejs/kit/hooks';
|
|
284
282
|
|
|
285
283
|
export const handle: Handle = ({ event, resolve }) => resolve(event);
|
|
286
284
|
`
|
package/dist/testing/stripe.js
CHANGED
|
@@ -164,7 +164,7 @@ export async function startStripe(options = {}) {
|
|
|
164
164
|
const payload = JSON.stringify({
|
|
165
165
|
id: sendOptions.id ?? next('evt'),
|
|
166
166
|
object: 'event',
|
|
167
|
-
api_version: '2026-
|
|
167
|
+
api_version: '2026-09-30.endive',
|
|
168
168
|
created: Math.floor(Date.now() / 1_000),
|
|
169
169
|
livemode: false,
|
|
170
170
|
type,
|
package/dist/variables.d.ts
CHANGED
|
@@ -16,10 +16,7 @@ export type ShopifyStandardVariable = (typeof SHOPIFY_STANDARD_VARIABLES)[number
|
|
|
16
16
|
* without, its .env.example may name them, and none takes one for its own.
|
|
17
17
|
*/
|
|
18
18
|
export declare const RETIRED_VARIABLES: readonly ["HOSTING_LOCATION"];
|
|
19
|
-
/**
|
|
20
|
-
* Every variable the baukasten reads in a web app. NODE_ENV comes from the image, and the server sets
|
|
21
|
-
* ORIGIN from PUBLIC_ORIGIN.
|
|
22
|
-
*/
|
|
19
|
+
/** Every variable the baukasten reads in a web app. NODE_ENV comes from the image. */
|
|
23
20
|
export declare const WEBAPP_VARIABLES: readonly ["PUBLIC_ORIGIN", "PORT", "DATABASE_URL", "SMTP_HOST", "SMTP_PORT", "MAIL_FROM", "MAIL_FROM_NAME", "OPERATOR_NAME", "OPERATOR_ADDRESS", "OPERATOR_REGISTER", "OPERATOR_VAT", "OPERATOR_JURISDICTION", "STRIPE_SECRET_KEY", "STRIPE_WEBHOOK_SECRET", "VERTRIEB_TOKEN", "LOG_LEVEL", "TEST_DATABASE_URL", "STRIPE_API_BASE"];
|
|
24
21
|
export declare const SHOPIFY_VARIABLES: readonly ["PUBLIC_ORIGIN", "PORT", "DATABASE_URL", "SMTP_HOST", "SMTP_PORT", "MAIL_FROM", "MAIL_FROM_NAME", "OPERATOR_NAME", "OPERATOR_ADDRESS", "VERTRIEB_TOKEN", "SHOPIFY_API_SECRET", "SHOPIFY_TOKEN_KEY", "SHOPIFY_PARTNER_TOKEN", "SHOPIFY_PARTNER_ORG", "LOG_LEVEL", "TEST_DATABASE_URL", "SHOPIFY_API_BASE", "SHOPIFY_CLIENT_ID"];
|
|
25
22
|
/**
|
package/dist/variables.js
CHANGED
|
@@ -45,10 +45,7 @@ export const SHOPIFY_STANDARD_VARIABLES = [
|
|
|
45
45
|
* without, its .env.example may name them, and none takes one for its own.
|
|
46
46
|
*/
|
|
47
47
|
export const RETIRED_VARIABLES = ['HOSTING_LOCATION'];
|
|
48
|
-
/**
|
|
49
|
-
* Every variable the baukasten reads in a web app. NODE_ENV comes from the image, and the server sets
|
|
50
|
-
* ORIGIN from PUBLIC_ORIGIN.
|
|
51
|
-
*/
|
|
48
|
+
/** Every variable the baukasten reads in a web app. NODE_ENV comes from the image. */
|
|
52
49
|
export const WEBAPP_VARIABLES = [
|
|
53
50
|
...STANDARD_VARIABLES,
|
|
54
51
|
'LOG_LEVEL',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tollwyn/baukasten",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "What every product built on this kit shares: configuration, log and server, database with two-layer migrations, health, accounts with sessions and API keys, limits, mail, payment through Stripe, the numbers for sales, the frame and pages, the stubs that hang them into a product and the check of a product, and the tools to test one, its connection test among them; and for a Shopify app its installation with tokens, the frame of the admin, its webhooks, its plan through the Partner API and its privacy text.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -56,22 +56,22 @@
|
|
|
56
56
|
"check:version": "node scripts/npm-version.ts"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"@sveltejs/kit": "^
|
|
60
|
-
"svelte": "^5.57.
|
|
59
|
+
"@sveltejs/kit": "^3.1.0",
|
|
60
|
+
"svelte": "^5.57.1"
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
63
|
"nodemailer": "10.1.4",
|
|
64
64
|
"pg": "8.23.1",
|
|
65
65
|
"smol-toml": "1.9.1",
|
|
66
|
-
"stripe": "
|
|
66
|
+
"stripe": "23.0.0",
|
|
67
67
|
"zod": "4.6.7"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
70
|
"@eslint-community/eslint-plugin-eslint-comments": "4.8.1",
|
|
71
71
|
"@eslint/js": "10.0.1",
|
|
72
72
|
"@playwright/test": "1.64.1",
|
|
73
|
-
"@sveltejs/kit": "
|
|
74
|
-
"@sveltejs/package": "
|
|
73
|
+
"@sveltejs/kit": "3.1.0",
|
|
74
|
+
"@sveltejs/package": "3.0.1",
|
|
75
75
|
"@sveltejs/vite-plugin-svelte": "7.3.1",
|
|
76
76
|
"@types/node": "24.19.2",
|
|
77
77
|
"@types/pg": "8.23.1",
|
|
@@ -89,8 +89,5 @@
|
|
|
89
89
|
"typescript-eslint": "8.71.2",
|
|
90
90
|
"vite": "8.3.4",
|
|
91
91
|
"vitest": "5.0.4"
|
|
92
|
-
},
|
|
93
|
-
"overrides": {
|
|
94
|
-
"cookie": "0.7.0"
|
|
95
92
|
}
|
|
96
93
|
}
|