@eighty4/dank 0.0.4-0 → 0.0.4-2

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/lib_js/config.js CHANGED
@@ -1,23 +1,163 @@
1
- var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
- if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
- return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
- return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
- });
6
- }
7
- return path;
1
+ import { isAbsolute, resolve } from "node:path";
2
+ import { isProductionBuild } from "./flags.js";
3
+ var __rewriteRelativeImportExtension = function(path, preserveJsx) {
4
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
5
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function(m, tsx, d, ext, cm) {
6
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : d + ext + "." + cm.toLowerCase() + "js";
7
+ });
8
+ }
9
+ return path;
8
10
  };
9
- import { isAbsolute, resolve } from 'node:path';
10
- const CFG_P = './dank.config.ts';
11
- export async function loadConfig(path = CFG_P) {
12
- const modulePath = `${resolveConfigPath(path)}?${Date.now()}`;
13
- const module = await import(__rewriteRelativeImportExtension(modulePath));
14
- return await module.default;
11
+ const CFG_P = "./dank.config.ts";
12
+ async function loadConfig(mode, path = CFG_P) {
13
+ const modulePath = resolveConfigPath(path);
14
+ const c = await resolveConfig(mode, modulePath);
15
+ normalizePagePaths(c.pages);
16
+ return c;
17
+ }
18
+ function resolveConfigPath(path) {
19
+ if (isAbsolute(path)) {
20
+ return path;
21
+ } else {
22
+ return resolve(process.cwd(), path);
23
+ }
24
+ }
25
+ async function resolveConfig(mode, modulePath) {
26
+ const module = await import(__rewriteRelativeImportExtension(`${modulePath}?${Date.now()}`));
27
+ const c = typeof module.default === "function" ? await module.default(resolveDankDetails(mode)) : module.default;
28
+ validateDankConfig(c);
29
+ return c;
30
+ }
31
+ function resolveDankDetails(mode) {
32
+ const production = isProductionBuild();
33
+ return {
34
+ dev: !production,
35
+ production,
36
+ mode
37
+ };
38
+ }
39
+ function validateDankConfig(c) {
40
+ try {
41
+ validatePorts(c);
42
+ validatePages(c.pages);
43
+ validateDevServices(c.services);
44
+ validateEsbuildConfig(c.esbuild);
45
+ } catch (e) {
46
+ throw e;
47
+ }
48
+ }
49
+ function validatePorts(c) {
50
+ if (c.port !== null && typeof c.port !== "undefined") {
51
+ if (typeof c.port !== "number") {
52
+ throw Error("DankConfig.port must be a number");
53
+ }
54
+ }
55
+ if (c.previewPort !== null && typeof c.previewPort !== "undefined") {
56
+ if (typeof c.previewPort !== "number") {
57
+ throw Error("DankConfig.previewPort must be a number");
58
+ }
59
+ }
60
+ }
61
+ function validateEsbuildConfig(esbuild) {
62
+ if (esbuild?.loaders !== null && typeof esbuild?.loaders !== "undefined") {
63
+ if (typeof esbuild.loaders !== "object") {
64
+ throw Error("DankConfig.esbuild.loaders must be a map of extensions to esbuild loaders");
65
+ } else {
66
+ for (const [ext, loader] of Object.entries(esbuild.loaders)) {
67
+ if (typeof loader !== "string") {
68
+ throw Error(`DankConfig.esbuild.loaders['${ext}'] must be a string of a loader name`);
69
+ }
70
+ }
71
+ }
72
+ }
73
+ if (esbuild?.plugins !== null && typeof esbuild?.plugins !== "undefined") {
74
+ if (!Array.isArray(esbuild.plugins)) {
75
+ throw Error("DankConfig.esbuild.plugins must be an array of esbuild plugins");
76
+ }
77
+ }
78
+ if (esbuild?.port !== null && typeof esbuild?.port !== "undefined") {
79
+ if (typeof esbuild.port !== "number") {
80
+ throw Error("DankConfig.esbuild.port must be a number");
81
+ }
82
+ }
83
+ }
84
+ function validatePages(pages) {
85
+ if (pages === null || typeof pages === "undefined" || Object.keys(pages).length === 0) {
86
+ throw Error("DankConfig.pages is required");
87
+ }
88
+ for (const [urlPath, mapping] of Object.entries(pages)) {
89
+ if (typeof mapping === "string" && mapping.endsWith(".html")) {
90
+ continue;
91
+ }
92
+ if (typeof mapping === "object") {
93
+ validatePageMapping(urlPath, mapping);
94
+ continue;
95
+ }
96
+ throw Error(`DankConfig.pages['${urlPath}'] must configure an html file`);
97
+ }
98
+ }
99
+ function validatePageMapping(urlPath, mapping) {
100
+ if (mapping.webpage === null || typeof mapping.webpage !== "string" || !mapping.webpage.endsWith(".html")) {
101
+ throw Error(`DankConfig.pages['${urlPath}'].webpage must configure an html file`);
102
+ }
103
+ if (mapping.pattern === null || typeof mapping.pattern === "undefined") {
104
+ return;
105
+ }
106
+ if (typeof mapping.pattern === "object" && mapping.pattern.constructor.name === "RegExp") {
107
+ return;
108
+ }
109
+ throw Error(`DankConfig.pages['${urlPath}'].pattern must be a RegExp`);
15
110
  }
16
- export function resolveConfigPath(path) {
17
- if (isAbsolute(path)) {
18
- return path;
111
+ function validateDevServices(services) {
112
+ if (services === null || typeof services === "undefined") {
113
+ return;
114
+ }
115
+ if (!Array.isArray(services)) {
116
+ throw Error(`DankConfig.services must be an array`);
117
+ }
118
+ for (let i = 0; i < services.length; i++) {
119
+ const s = services[i];
120
+ if (s.command === null || typeof s.command === "undefined") {
121
+ throw Error(`DankConfig.services[${i}].command is required`);
122
+ } else if (typeof s.command !== "string" || s.command.length === 0) {
123
+ throw Error(`DankConfig.services[${i}].command must be a non-empty string`);
19
124
  }
20
- else {
21
- return resolve(process.cwd(), path);
125
+ if (s.cwd !== null && typeof s.cwd !== "undefined") {
126
+ if (typeof s.cwd !== "string" || s.cwd.trim().length === 0) {
127
+ throw Error(`DankConfig.services[${i}].cwd must be a non-empty string`);
128
+ }
22
129
  }
130
+ if (s.env !== null && typeof s.env !== "undefined") {
131
+ if (typeof s.env !== "object") {
132
+ throw Error(`DankConfig.services[${i}].env must be an env variable map`);
133
+ }
134
+ for (const [k, v] of Object.entries(s.env)) {
135
+ if (typeof v !== "string") {
136
+ throw Error(`DankConfig.services[${i}].env[${k}] must be a string`);
137
+ }
138
+ }
139
+ }
140
+ if (s.http !== null && typeof s.http !== "undefined") {
141
+ if (typeof s.http.port !== "number") {
142
+ throw Error(`DankConfig.services[${i}].http.port must be a number`);
143
+ }
144
+ }
145
+ }
146
+ }
147
+ function normalizePagePaths(pages) {
148
+ for (const [pageUrl, mapping] of Object.entries(pages)) {
149
+ if (typeof mapping === "string") {
150
+ pages[pageUrl] = normalizePagePath(mapping);
151
+ } else {
152
+ mapping.webpage = normalizePagePath(mapping.webpage);
153
+ }
154
+ }
155
+ }
156
+ function normalizePagePath(p) {
157
+ return p.replace(/^\.\//, "");
23
158
  }
159
+ export {
160
+ loadConfig,
161
+ resolveConfig,
162
+ resolveConfigPath
163
+ };
package/lib_js/dank.js CHANGED
@@ -1,123 +1,6 @@
1
- export async function defineConfig(c) {
2
- if (c.port !== null && typeof c.port !== 'undefined') {
3
- if (typeof c.port !== 'number') {
4
- throw Error('DankConfig.port must be a number');
5
- }
6
- }
7
- if (c.previewPort !== null && typeof c.previewPort !== 'undefined') {
8
- if (typeof c.previewPort !== 'number') {
9
- throw Error('DankConfig.previewPort must be a number');
10
- }
11
- }
12
- validatePages(c.pages);
13
- validateDevServices(c.services);
14
- validateEsbuildConfig(c.esbuild);
15
- normalizePagePaths(c.pages);
16
- return c;
17
- }
18
- function validateEsbuildConfig(esbuild) {
19
- if (esbuild?.loaders !== null && typeof esbuild?.loaders !== 'undefined') {
20
- if (typeof esbuild.loaders !== 'object') {
21
- throw Error('DankConfig.esbuild.loaders must be a map of extensions to esbuild loaders');
22
- }
23
- else {
24
- for (const [ext, loader] of Object.entries(esbuild.loaders)) {
25
- if (typeof loader !== 'string') {
26
- throw Error(`DankConfig.esbuild.loaders['${ext}'] must be a string of a loader name`);
27
- }
28
- }
29
- }
30
- }
31
- if (esbuild?.plugins !== null && typeof esbuild?.plugins !== 'undefined') {
32
- if (!Array.isArray(esbuild.plugins)) {
33
- throw Error('DankConfig.esbuild.plugins must be an array of esbuild plugins');
34
- }
35
- }
36
- if (esbuild?.port !== null && typeof esbuild?.port !== 'undefined') {
37
- if (typeof esbuild.port !== 'number') {
38
- throw Error('DankConfig.esbuild.port must be a number');
39
- }
40
- }
41
- }
42
- function validatePages(pages) {
43
- if (pages === null ||
44
- typeof pages === 'undefined' ||
45
- Object.keys(pages).length === 0) {
46
- throw Error('DankConfig.pages is required');
47
- }
48
- for (const [urlPath, mapping] of Object.entries(pages)) {
49
- if (typeof mapping === 'string' && mapping.endsWith('.html')) {
50
- continue;
51
- }
52
- if (typeof mapping === 'object') {
53
- validatePageMapping(urlPath, mapping);
54
- continue;
55
- }
56
- throw Error(`DankConfig.pages['${urlPath}'] must configure an html file`);
57
- }
58
- }
59
- function validatePageMapping(urlPath, mapping) {
60
- if (mapping.webpage === null ||
61
- typeof mapping.webpage !== 'string' ||
62
- !mapping.webpage.endsWith('.html')) {
63
- throw Error(`DankConfig.pages['${urlPath}'].webpage must configure an html file`);
64
- }
65
- if (mapping.pattern === null || typeof mapping.pattern === 'undefined') {
66
- return;
67
- }
68
- if (typeof mapping.pattern === 'object' &&
69
- mapping.pattern.constructor.name === 'RegExp') {
70
- return;
71
- }
72
- throw Error(`DankConfig.pages['${urlPath}'].pattern must be a RegExp`);
73
- }
74
- function validateDevServices(services) {
75
- if (services === null || typeof services === 'undefined') {
76
- return;
77
- }
78
- if (!Array.isArray(services)) {
79
- throw Error(`DankConfig.services must be an array`);
80
- }
81
- for (let i = 0; i < services.length; i++) {
82
- const s = services[i];
83
- if (s.command === null || typeof s.command === 'undefined') {
84
- throw Error(`DankConfig.services[${i}].command is required`);
85
- }
86
- else if (typeof s.command !== 'string' || s.command.length === 0) {
87
- throw Error(`DankConfig.services[${i}].command must be a non-empty string`);
88
- }
89
- if (s.cwd !== null && typeof s.cwd !== 'undefined') {
90
- if (typeof s.cwd !== 'string' || s.cwd.trim().length === 0) {
91
- throw Error(`DankConfig.services[${i}].cwd must be a non-empty string`);
92
- }
93
- }
94
- if (s.env !== null && typeof s.env !== 'undefined') {
95
- if (typeof s.env !== 'object') {
96
- throw Error(`DankConfig.services[${i}].env must be an env variable map`);
97
- }
98
- for (const [k, v] of Object.entries(s.env)) {
99
- if (typeof v !== 'string') {
100
- throw Error(`DankConfig.services[${i}].env[${k}] must be a string`);
101
- }
102
- }
103
- }
104
- if (s.http !== null && typeof s.http !== 'undefined') {
105
- if (typeof s.http.port !== 'number') {
106
- throw Error(`DankConfig.services[${i}].http.port must be a number`);
107
- }
108
- }
109
- }
110
- }
111
- function normalizePagePaths(pages) {
112
- for (const [pageUrl, mapping] of Object.entries(pages)) {
113
- if (typeof mapping === 'string') {
114
- pages[pageUrl] = normalizePagePath(mapping);
115
- }
116
- else {
117
- mapping.webpage = normalizePagePath(mapping.webpage);
118
- }
119
- }
120
- }
121
- function normalizePagePath(p) {
122
- return p.replace(/^\.\//, '');
1
+ function defineConfig(config) {
2
+ return config;
123
3
  }
4
+ export {
5
+ defineConfig
6
+ };
package/lib_js/define.js CHANGED
@@ -1,6 +1,9 @@
1
- export function createGlobalDefinitions(build) {
2
- return {
3
- 'dank.IS_DEV': JSON.stringify(!build.production),
4
- 'dank.IS_PROD': JSON.stringify(build.production),
5
- };
1
+ function createGlobalDefinitions(build) {
2
+ return {
3
+ "dank.IS_DEV": JSON.stringify(!build.production),
4
+ "dank.IS_PROD": JSON.stringify(build.production)
5
+ };
6
6
  }
7
+ export {
8
+ createGlobalDefinitions
9
+ };
package/lib_js/esbuild.js CHANGED
@@ -1,179 +1,176 @@
1
- import { readFile } from 'node:fs/promises';
2
- import esbuild, {} from 'esbuild';
3
- export async function esbuildDevContext(b, r, define, entryPoints, c) {
4
- return await esbuild.context({
5
- define,
6
- entryNames: '[dir]/[name]',
7
- entryPoints: mapEntryPointPaths(entryPoints),
8
- outdir: b.dirs.buildWatch,
9
- ...commonBuildOptions(b, r, c),
10
- splitting: false,
11
- write: false,
12
- });
1
+ import { readFile } from "node:fs/promises";
2
+ import esbuild, {} from "esbuild";
3
+ async function esbuildDevContext(b, r, define, entryPoints, c) {
4
+ return await esbuild.context({
5
+ define,
6
+ entryNames: "[dir]/[name]",
7
+ entryPoints: mapEntryPointPaths(entryPoints),
8
+ outdir: b.dirs.buildWatch,
9
+ ...commonBuildOptions(b, r, c),
10
+ splitting: false,
11
+ write: false
12
+ });
13
13
  }
14
- export async function esbuildWebpages(b, r, define, entryPoints, c) {
15
- const result = await esbuild.build({
16
- define,
17
- entryNames: '[dir]/[name]-[hash]',
18
- entryPoints: mapEntryPointPaths(entryPoints),
19
- outdir: b.dirs.buildDist,
20
- ...commonBuildOptions(b, r, c),
14
+ async function esbuildWebpages(b, r, define, entryPoints, c) {
15
+ try {
16
+ await esbuild.build({
17
+ define,
18
+ entryNames: "[dir]/[name]-[hash]",
19
+ entryPoints: mapEntryPointPaths(entryPoints),
20
+ outdir: b.dirs.buildDist,
21
+ ...commonBuildOptions(b, r, c)
21
22
  });
22
- esbuildResultChecks(result);
23
+ } catch (ignore) {
24
+ process.exit(1);
25
+ }
23
26
  }
24
- export async function esbuildWorkers(b, r, define, entryPoints, c) {
25
- const result = await esbuild.build({
26
- define,
27
- entryNames: '[dir]/[name]-[hash]',
28
- entryPoints: mapEntryPointPaths(entryPoints),
29
- outdir: b.dirs.buildDist,
30
- ...commonBuildOptions(b, r, c),
31
- splitting: false,
32
- metafile: true,
33
- write: true,
34
- assetNames: 'assets/[name]-[hash]',
27
+ async function esbuildWorkers(b, r, define, entryPoints, c) {
28
+ try {
29
+ await esbuild.build({
30
+ define,
31
+ entryNames: "[dir]/[name]-[hash]",
32
+ entryPoints: mapEntryPointPaths(entryPoints),
33
+ outdir: b.dirs.buildDist,
34
+ ...commonBuildOptions(b, r, c),
35
+ splitting: false,
36
+ metafile: true,
37
+ write: true,
38
+ assetNames: "assets/[name]-[hash]"
35
39
  });
36
- esbuildResultChecks(result);
40
+ } catch (ignore) {
41
+ process.exit(1);
42
+ }
37
43
  }
38
44
  function commonBuildOptions(b, r, c) {
39
- const p = workersPlugin(r.buildRegistry());
40
- return {
41
- absWorkingDir: b.dirs.projectRootAbs,
42
- assetNames: 'assets/[name]-[hash]',
43
- bundle: true,
44
- format: 'esm',
45
- loader: c?.loaders || defaultLoaders(),
46
- metafile: true,
47
- minify: b.minify,
48
- platform: 'browser',
49
- plugins: c?.plugins?.length ? [p, ...c.plugins] : [p],
50
- splitting: true,
51
- treeShaking: true,
52
- write: true,
53
- };
45
+ const p = workersPlugin(r.buildRegistry());
46
+ return {
47
+ absWorkingDir: b.dirs.projectRootAbs,
48
+ assetNames: "assets/[name]-[hash]",
49
+ bundle: true,
50
+ format: "esm",
51
+ loader: c?.loaders || defaultLoaders(),
52
+ metafile: true,
53
+ minify: b.minify,
54
+ platform: "browser",
55
+ plugins: c?.plugins?.length ? [p, ...c.plugins] : [p],
56
+ splitting: true,
57
+ treeShaking: true,
58
+ write: true
59
+ };
54
60
  }
55
61
  function defaultLoaders() {
56
- return {
57
- '.woff': 'file',
58
- '.woff2': 'file',
59
- };
62
+ return {
63
+ ".woff": "file",
64
+ ".woff2": "file"
65
+ };
60
66
  }
61
- // esbuild will append the .js or .css to output filenames
62
- // keeping extension on entryPoints data for consistency
63
- // and only trimming when creating esbuild opts
64
67
  function mapEntryPointPaths(entryPoints) {
65
- return entryPoints.map(entryPoint => {
66
- return {
67
- in: entryPoint.in,
68
- out: entryPoint.out.replace(/\.(tsx?|jsx?|css)$/, ''),
69
- };
70
- });
68
+ return entryPoints.map((entryPoint) => {
69
+ return {
70
+ in: entryPoint.in,
71
+ out: entryPoint.out.replace(/\.(tsx?|jsx?|css)$/, "")
72
+ };
73
+ });
71
74
  }
72
- function esbuildResultChecks(buildResult) {
73
- if (buildResult.errors.length) {
74
- buildResult.errors.forEach(msg => esbuildPrintMessage(msg, 'warning'));
75
- process.exit(1);
76
- }
77
- if (buildResult.warnings.length) {
78
- buildResult.warnings.forEach(msg => esbuildPrintMessage(msg, 'warning'));
75
+ const WORKER_CTOR_REGEX = /new(?:\s|\r?\n)+(?<ctor>(?:Shared)?Worker)(?:\s|\r?\n)*\((?:\s|\r?\n)*(?<url>.*?)(?:\s|\r?\n)*(?<end>[\),])/g;
76
+ const WORKER_URL_REGEX = /^('.*'|".*")$/;
77
+ function workersPlugin(r) {
78
+ return {
79
+ name: "@eighty4/dank/esbuild/workers",
80
+ setup(build) {
81
+ if (!build.initialOptions.absWorkingDir)
82
+ throw TypeError("plugin requires absWorkingDir");
83
+ if (!build.initialOptions.metafile)
84
+ throw TypeError("plugin requires metafile");
85
+ const { absWorkingDir } = build.initialOptions;
86
+ build.onLoad({ filter: /\.(t|m?j)s$/ }, async (args) => {
87
+ let contents = await readFile(args.path, "utf8");
88
+ let offset = 0;
89
+ let errors = void 0;
90
+ for (const workerCtorMatch of contents.matchAll(WORKER_CTOR_REGEX)) {
91
+ if (!WORKER_URL_REGEX.test(workerCtorMatch.groups.url)) {
92
+ if (!errors)
93
+ errors = [];
94
+ errors.push(invalidWorkerUrlCtorArg(locationFromMatch(args, contents, workerCtorMatch), workerCtorMatch));
95
+ continue;
96
+ }
97
+ if (isIndexCommented(contents, workerCtorMatch.index)) {
98
+ continue;
99
+ }
100
+ const clientScript = args.path.replace(absWorkingDir, "").substring(1);
101
+ const workerUrl = workerCtorMatch.groups.url.substring(1, workerCtorMatch.groups.url.length - 1);
102
+ const workerEntryPoint = r.resolver.resolveHrefInPagesDir(clientScript, workerUrl);
103
+ if (workerEntryPoint === "outofbounds") {
104
+ if (!errors)
105
+ errors = [];
106
+ errors.push(outofboundsWorkerUrlCtorArg(locationFromMatch(args, contents, workerCtorMatch), workerCtorMatch));
107
+ continue;
108
+ }
109
+ const workerUrlPlaceholder = workerEntryPoint.replace(/^pages/, "").replace(/\.(t|m?j)s$/, ".js");
110
+ const workerCtorReplacement = `new ${workerCtorMatch.groups.ctor}('${workerUrlPlaceholder}'${workerCtorMatch.groups.end}`;
111
+ contents = contents.substring(0, workerCtorMatch.index + offset) + workerCtorReplacement + contents.substring(workerCtorMatch.index + workerCtorMatch[0].length + offset);
112
+ offset += workerCtorReplacement.length - workerCtorMatch[0].length;
113
+ r.addWorker({
114
+ clientScript,
115
+ workerEntryPoint,
116
+ workerUrl,
117
+ workerUrlPlaceholder
118
+ });
119
+ }
120
+ const loader = args.path.endsWith("ts") ? "ts" : "js";
121
+ return { contents, errors, loader };
122
+ });
123
+ build.onEnd((result) => {
124
+ if (result.metafile) {
125
+ r.completeBuild(result);
126
+ }
127
+ });
79
128
  }
129
+ };
80
130
  }
81
- function esbuildPrintMessage(msg, category) {
82
- const location = msg.location
83
- ? ` (${msg.location.file}L${msg.location.line}:${msg.location.column})`
84
- : '';
85
- console.error(`esbuild ${category}${location}:`, msg.text);
86
- msg.notes.forEach(note => {
87
- console.error(' ', note.text);
88
- if (note.location)
89
- console.error(' ', note.location);
90
- });
131
+ function isIndexCommented(contents, index) {
132
+ const preamble = contents.substring(0, index);
133
+ const lineIndex = preamble.lastIndexOf("\n") || 0;
134
+ const lineCommented = /\/\//.test(preamble.substring(lineIndex));
135
+ if (lineCommented) {
136
+ return true;
137
+ }
138
+ const blockCommentIndex = preamble.lastIndexOf("/*");
139
+ const blockCommented = blockCommentIndex !== -1 && preamble.substring(blockCommentIndex).indexOf("*/") === -1;
140
+ return blockCommented;
91
141
  }
92
- const WORKER_CTOR_REGEX = /new(?:\s|\r?\n)+Worker(?:\s|\r?\n)*\((?:\s|\r?\n)*(?<url>.*)(?:\s|\r?\n)*\)/g;
93
- const WORKER_URL_REGEX = /^('.*'|".*")$/;
94
- export function workersPlugin(r) {
95
- return {
96
- name: '@eighty4/dank/esbuild/workers',
97
- setup(build) {
98
- if (!build.initialOptions.absWorkingDir)
99
- throw TypeError('plugin requires absWorkingDir');
100
- if (!build.initialOptions.metafile)
101
- throw TypeError('plugin requires metafile');
102
- const { absWorkingDir } = build.initialOptions;
103
- build.onLoad({ filter: /\.(t|m?j)s$/ }, async (args) => {
104
- let contents = await readFile(args.path, 'utf8');
105
- let offset = 0;
106
- let errors = undefined;
107
- for (const workerCtorMatch of contents.matchAll(WORKER_CTOR_REGEX)) {
108
- const workerUrlString = workerCtorMatch.groups.url;
109
- if (WORKER_URL_REGEX.test(workerUrlString)) {
110
- const preamble = contents.substring(0, workerCtorMatch.index);
111
- const lineIndex = preamble.lastIndexOf('\n') || 0;
112
- const lineCommented = /\/\//.test(preamble.substring(lineIndex));
113
- if (lineCommented)
114
- continue;
115
- const blockCommentIndex = preamble.lastIndexOf('/*');
116
- const blockCommented = blockCommentIndex !== -1 &&
117
- preamble
118
- .substring(blockCommentIndex)
119
- .indexOf('*/') === -1;
120
- if (blockCommented)
121
- continue;
122
- const clientScript = args.path
123
- .replace(absWorkingDir, '')
124
- .substring(1);
125
- const workerUrl = workerUrlString.substring(1, workerUrlString.length - 1);
126
- // todo out of bounds error on path resolve
127
- const workerEntryPoint = r.resolve(clientScript, workerUrl);
128
- const workerUrlPlaceholder = workerEntryPoint
129
- .replace(/^pages/, '')
130
- .replace(/\.(t|m?j)s$/, '.js');
131
- const workerCtorReplacement = `new Worker('${workerUrlPlaceholder}')`;
132
- contents =
133
- contents.substring(0, workerCtorMatch.index + offset) +
134
- workerCtorReplacement +
135
- contents.substring(workerCtorMatch.index +
136
- workerCtorMatch[0].length +
137
- offset);
138
- offset +=
139
- workerCtorReplacement.length -
140
- workerCtorMatch[0].length;
141
- r.addWorker({
142
- clientScript,
143
- workerEntryPoint,
144
- workerUrl,
145
- workerUrlPlaceholder,
146
- });
147
- }
148
- else {
149
- if (!errors)
150
- errors = [];
151
- const preamble = contents.substring(0, workerCtorMatch.index);
152
- const line = preamble.match(/\n/g)?.length || 0;
153
- const lineIndex = preamble.lastIndexOf('\n') || 0;
154
- const column = preamble.length - lineIndex;
155
- const lineText = contents.substring(lineIndex, contents.indexOf('\n', lineIndex) ||
156
- contents.length);
157
- errors.push({
158
- id: 'worker-url-unresolvable',
159
- location: {
160
- lineText,
161
- line,
162
- column,
163
- file: args.path,
164
- length: workerCtorMatch[0].length,
165
- },
166
- });
167
- }
168
- }
169
- const loader = args.path.endsWith('ts') ? 'ts' : 'js';
170
- return { contents, errors, loader };
171
- });
172
- build.onEnd((result) => {
173
- if (result.metafile) {
174
- r.completeBuild(result);
175
- }
176
- });
177
- },
178
- };
142
+ function locationFromMatch(args, contents, match) {
143
+ const preamble = contents.substring(0, match.index);
144
+ const line = preamble.match(/\n/g)?.length || 0;
145
+ let lineIndex = preamble.lastIndexOf("\n");
146
+ lineIndex = lineIndex === -1 ? 0 : lineIndex + 1;
147
+ const column = preamble.length - lineIndex;
148
+ const lineText = contents.substring(lineIndex, contents.indexOf("\n", lineIndex) || contents.length);
149
+ return {
150
+ lineText,
151
+ line,
152
+ column,
153
+ file: args.path,
154
+ length: match[0].length
155
+ };
156
+ }
157
+ function outofboundsWorkerUrlCtorArg(location, workerCtorMatch) {
158
+ return {
159
+ id: "worker-url-outofbounds",
160
+ text: `The ${workerCtorMatch.groups.ctor} constructor URL arg \`${workerCtorMatch.groups.url}\` cannot resolve to a path outside of the pages directory`,
161
+ location
162
+ };
163
+ }
164
+ function invalidWorkerUrlCtorArg(location, workerCtorMatch) {
165
+ return {
166
+ id: "worker-url-unresolvable",
167
+ text: `The ${workerCtorMatch.groups.ctor} constructor URL arg \`${workerCtorMatch.groups.url}\` must be a relative module path`,
168
+ location
169
+ };
179
170
  }
171
+ export {
172
+ esbuildDevContext,
173
+ esbuildWebpages,
174
+ esbuildWorkers,
175
+ workersPlugin
176
+ };