Skip to content

Commit

Permalink
Merge pull request #16 from kmontag/protobufjs7
Browse files Browse the repository at this point in the history
update to `protobufjs@^7.0.0`
  • Loading branch information
kmontag committed Jul 18, 2022
2 parents 8fccf71 + 7390523 commit 163f121
Show file tree
Hide file tree
Showing 7 changed files with 1,403 additions and 2,716 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module.exports = {
extends: [
'eslint:recommended',
'airbnb/base',
'airbnb-base',
'plugin:mocha/recommended',
'prettier',
],
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:

strategy:
matrix:
node-version: [10.x, 12.x, 16.x, 18.x]
node-version: [12.x, 16.x, 18.x]
webpack-version: [2, 3, 4, 5]

env:
Expand Down
19 changes: 11 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,6 @@ module.exports = {
use: {
loader: 'protobufjs-loader',
options: {
/* Controls the "target" flag to pbjs - true for
* json-module, false for static-module.
*
* default: false
*/
json: false,

/* Import paths provided to pbjs.
*
* default: webpack import paths (i.e. config.resolve.modules)
Expand All @@ -56,7 +49,11 @@ module.exports = {
* They'll be saved in the same directory as the protobuf file
* being processed, with a `.d.ts` extension.
*
* This can be a config object or a boolean.
* This only works if you're using the 'static-module' target
* for pbjs (enabled by default).
*
* The value here can be a config object or a boolean; set it to
* true to enable pbts with default configuration.
*
* default: false
*/
Expand All @@ -65,6 +62,12 @@ module.exports = {
*/
args: ['--no-comments'],
}

/* Set the "target" flag to pbjs.
*
* default: 'static-module'
*/
target: 'json-module',
}
}
}]
Expand Down
252 changes: 122 additions & 130 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
const fs = require('fs');
const { pbjs, pbts } = require('protobufjs/cli');
const { pbjs, pbts } = require('protobufjs-cli');
const protobuf = require('protobufjs');
const tmp = require('tmp-promise');
const validateOptions = require('schema-utils').validate;

const { getOptions } = require('loader-utils');

const TARGET_STATIC_MODULE = 'static-module';

/** @type { Parameters<typeof validateOptions>[0] } */
const schema = {
type: 'object',
properties: {
json: {
type: 'boolean',
default: false,
target: {
type: 'string',
default: TARGET_STATIC_MODULE,
},
paths: {
type: 'array',
Expand Down Expand Up @@ -41,23 +43,6 @@ const schema = {
},
},

// pbts config is only applicable if the pbjs target is
// `static-module`, i.e. if the `json` flag is false. We enforce
// this at the schema level; see
// https://json-schema.org/understanding-json-schema/reference/conditionals.html#implication.
anyOf: [
{
properties: {
json: { const: true },
pbts: { const: false },
},
},
{
not: {
properties: { json: { const: true } },
},
},
],
additionalProperties: false,
};

Expand All @@ -68,8 +53,9 @@ const schema = {
*
* @typedef {{ args: string[] }} PbtsOptions
* @typedef {{
* json: boolean, paths: string[], pbjsArgs: string[],
* pbts: boolean | PbtsOptions
* paths: string[], pbjsArgs: string[],
* pbts: boolean | PbtsOptions,
* target: string,
* }} LoaderOptions
*/

Expand Down Expand Up @@ -133,133 +119,139 @@ module.exports = function protobufJsLoader(source) {
throw new Error('Failed to request async execution from webpack');
}

const defaultPaths = (() => {
if ('options' in this) {
// For webpack@2 and webpack@3. property loaderContext.options
// was deprecated in webpack@3 and removed in webpack@4.
return (this.options.resolve || {}).modules;
}
try {
const defaultPaths = (() => {
if ('options' in this) {
// For webpack@2 and webpack@3. property loaderContext.options
// was deprecated in webpack@3 and removed in webpack@4.
return (this.options.resolve || {}).modules;
}

if (this._compiler) {
// For webpack@4 and webpack@5. The `_compiler` property is
// deprecated, but still works as of webpack@5.
return (this._compiler.options.resolve || {}).modules;
}
if (this._compiler) {
// For webpack@4 and webpack@5. The `_compiler` property is
// deprecated, but still works as of webpack@5.
return (this._compiler.options.resolve || {}).modules;
}

return undefined;
})();
return undefined;
})();

/** @type LoaderOptions */
const options = {
json: false,
/** @type LoaderOptions */
const options = {
target: TARGET_STATIC_MODULE,

// Default to the paths given to the compiler.
paths: defaultPaths || [],
// Default to the paths given to the compiler.
paths: defaultPaths || [],

pbjsArgs: [],
pbjsArgs: [],

pbts: false,
pbts: false,

...getOptions(this),
};
try {
...getOptions(this),
};
validateOptions(schema, options, { name: 'protobufjs-loader' });
} catch (err) {
callback(err instanceof Error ? err : new Error(`${err}`), undefined);
return;
}

/** @type { string } */
let filename;
tmp
.file()
.then((o) => {
filename = o.path;
return new Promise((resolve, reject) => {
fs.write(o.fd, source, (err, bytesWritten) => {
if (err) {
reject(err);
} else {
resolve(bytesWritten);
}
/** @type { string } */
let filename;
tmp
.file()
.then((o) => {
filename = o.path;
return new Promise((resolve, reject) => {
fs.write(o.fd, source, (err, bytesWritten) => {
if (err) {
reject(err);
} else {
resolve(bytesWritten);
}
});
});
});
})
.then(() => {
const { paths } = options;
})
.then(() => {
const { paths } = options;

const loadDependencies = new Promise((resolve, reject) => {
const root = new protobuf.Root();
root.resolvePath = (origin, target) => {
// Adapted from
// https://github.com/dcodeIO/protobuf.js/blob/master/cli/pbjs.js
const normOrigin = protobuf.util.path.normalize(origin);
const normTarget = protobuf.util.path.normalize(target);
const loadDependencies = new Promise((resolve, reject) => {
const root = new protobuf.Root();
root.resolvePath = (origin, target) => {
// Adapted from
// https://github.com/dcodeIO/protobuf.js/blob/master/cli/pbjs.js
const normOrigin = protobuf.util.path.normalize(origin);
const normTarget = protobuf.util.path.normalize(target);

let resolved = protobuf.util.path.resolve(
normOrigin,
normTarget,
true
);
const idx = resolved.lastIndexOf('google/protobuf/');
if (idx > -1) {
const altname = resolved.substring(idx);
if (altname in protobuf.common) {
resolved = altname;
let resolved = protobuf.util.path.resolve(
normOrigin,
normTarget,
true
);
const idx = resolved.lastIndexOf('google/protobuf/');
if (idx > -1) {
const altname = resolved.substring(idx);
if (altname in protobuf.common) {
resolved = altname;
}
}
}

if (fs.existsSync(resolved)) {
// Don't add a dependency on the temp file
if (resolved !== filename) {
self.addDependency(resolved);
if (fs.existsSync(resolved)) {
// Don't add a dependency on the temp file
if (resolved !== filename) {
self.addDependency(resolved);
}
return resolved;
}
return resolved;
}

for (let i = 0; i < paths.length; i += 1) {
const iresolved = protobuf.util.path.resolve(
`${paths[i]}/`,
target
);
if (fs.existsSync(iresolved)) {
self.addDependency(iresolved);
return iresolved;
for (let i = 0; i < paths.length; i += 1) {
const iresolved = protobuf.util.path.resolve(
`${paths[i]}/`,
target
);
if (fs.existsSync(iresolved)) {
self.addDependency(iresolved);
return iresolved;
}
}
}

return null;
};
protobuf.load(filename, root, (err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});

let args = options.pbjsArgs;
paths.forEach((path) => {
args = args.concat(['-p', path]);
});
args = args
.concat(['-t', options.json ? 'json-module' : 'static-module'])
.concat([filename]);

pbjs.main(args, (err, result) => {
// Make sure we've added all dependencies before completing.
loadDependencies
.catch((depErr) => {
callback(depErr);
})
.then(() => {
if (!options.pbts || err) {
callback(err, result);
return null;
};
protobuf.load(filename, root, (err, result) => {
if (err) {
reject(err);
} else {
execPbts(self.resourcePath, options.pbts, result || '', callback);
resolve(result);
}
});
});

/** @type { string[] } */
let args = ['-t', options.target];
paths.forEach((path) => {
args = args.concat(['-p', path]);
});
args = args.concat(options.pbjsArgs).concat([filename]);

pbjs.main(args, (err, result) => {
// Make sure we've added all dependencies before completing.
loadDependencies
.catch((depErr) => {
callback(depErr);
})
.then(() => {
if (!options.pbts || err) {
callback(err, result);
} else {
execPbts(
self.resourcePath,
options.pbts,
result || '',
callback
);
}
});
});
})
.catch((err) => {
callback(err instanceof Error ? err : new Error(`${err}`), undefined);
});
});
} catch (err) {
callback(err instanceof Error ? err : new Error(`${err}`), undefined);
}
};
Loading

0 comments on commit 163f121

Please sign in to comment.